用openresty做后台服务器
文章目录
[隐藏]
- 与OpenResty及其原作者邂逅
- 我们后台选用的第三方库和文件
- 架构思想和坑
- 讨论太廉价了,直接上代码吧
- 后记
【腾讯云】校园优惠再度来袭cloud.tencent.com
与OpenResty及其原作者邂逅
OpenResty是一个优秀的开源项目,作者是章亦春。官网是openresty.org/en/。这已经是我第二次在公司项目中使用它展开业务了。分享使用经历的时候,顺便帮春哥推广一下:
其实,我想说的是春哥真的像知乎上传的一样,热情,专业。同时也希望大家都到邮件列表里问问题,像我一样莽莽撞撞直接私发邮件,确实显得不大矜持,汗!
我们后台选用的第三方库和文件
我们后台采用: openresty框架+lua脚本+c函数+mongoDB数据库.这其中的技术细节我们都论证过,现把他们都链接粘出来。
- Lua调用mongo的驱动 github.com/bigplum/lua…
- OpenResty官网下载 openresty.org/en/download…
- Lua调用C函数blog.csdn.net/wuxiangege/…
架构思想和坑
想成为高手,得首先学会跟高手一样思考问题,我觉得这也是每一个有志向的程序员练级所必须经历的。下面是我跟架构师的工作交流时,从正面和侧面所总结的,即为什么要采用:openresty框架+lua脚本+c函数+mongoDB数据库作为后台的原因。
- 对于openresty,我的理解是openresty = web服务器nginx + lua虚拟机。它的好处官网都有,如”能够处理超高并发、扩展性极高的动态 Web 应用、Web 服务和动态网关”
。对于我们的项目,架构师看中的似乎是openresty对nginx的lua扩展,因为接下来我们会调用第三方提供的dll文件,即lua调C。在操作数据库方面,openresty提供的很多精良的数据库驱动,如memcached、mysql、redis。虽然官方没有提供mongodb,但bigplum大神已经做到了,见上方链接。经过测试,bigplum大神提供的测试文件可用,对文档的数据库、集合和文档的增删改查均可用,点个赞。 - openresty官方已经实现了redis的驱动,我们为什么选用mongodb而不是redis?架构师是这么回答我的,1、redis太重了,mongodb稍微轻一点点,而且我们的项目是在win上部署的对内存有一些要求,架构师希望它在普通的pc上也能运行;2、项目要求数据库同步,也就是a/b/c/d/四台机器数据保持数据的一致性。在这一点上,我们采取的是mongodb的副本集。
讨论太廉价了,直接上代码吧
nginx.conf文件
worker_processes 1; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; lua_package_path '/c/Users/wuxian/Desktop/BlackHole/openresty-1.9.15.1-win32/lualib/resty/mongol/init.lua;;'; sendfile on; keepalive_timeout 65; server { listen 80; server_name localhost; location / { #解决跨域问题 if ($request_method = 'OPTIONS') { add_header 'Access-Control-Allow-Origin' '*'; add_header 'Access-Control-Allow-Headers' 'Content-Type'; return 204; } if ($request_method = 'POST') { add_header 'Access-Control-Allow-Origin' '*'; } #处理业务的文件 default_type text/html; content_by_lua_file './lua_script/app.lua'; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } } }
app.lua文件
local mongo = require "resty.mongol" local cjson = require "cjson.safe" ----------------------------------------------------------------------------- --lua call c module square = package.loadlib("./ADD.dll", "isquare") alert = package.loadlib("./ADD.dll", "alert") add = package.loadlib("./ADD.dll", "l_add") sub = package.loadlib("./ADD.dll", "l_sub") ----------------------------------------------------------------------------- --Connect mongodb database conn = mongo:new() ok, err = conn:set_timeout(5000) ok, err = conn:connect("127.0.0.1", 27017) if not ok then ngx.say("connect failed: "..err) end local db = conn:new_db_handle("tamigroup") if not db then ngx.say(db) end local col = db:get_col("number") ----------------------------------------------------------------------------- -- Process request data local function post_request(data) local result = {} local request = cjson.decode(data) if not request or not request["cmd"] then result["result"] = "failed" result["reason"] = "no 'cmd' field or not a json struct" return result end local sql_str = "" --测试 if request["cmd"] == "demo" then local result = {} result["result"] = "ok" result["reason"] = "This is a test cmd" return result end --插入人员 if request["cmd"] == "add" then local result = {} local t = {} table.insert(t, {name=request["name"], id"]}) r, err = col:insert(t, nil, true) if not r then result["result"] = "insert failed: "..err else result["result"] = "ok" end return result end --删除人员 if request["cmd"] == "delete" then local result = {} r, err = col:delete({name=request["name"]}, nil, true) if not r then request["result"] = "delete failed: "..err else result["request"] = "ok" end return result end --修改人员 if request["cmd"] == "update" then local result = {} r,err = col:update({name=request["old"]},{name=request["new"]}, nil, nil, true) if not r then request[result] = "update failed: "..err else request[result] = "ok" end return result end --查询人员 if request["cmd"] == "find" then local result = {} r = col:find({name=result["name"]}) r:limit(1) for i , v in r:pairs() do result["data"] = v["name"]; end if not result["data"] then result["result"] = "He or she don't exist" else result["result"] = "ok" end return result end --调用c模块 if request["cmd"] == "lua_call_c" then local result = {} result["data"] = square(12) result["add"] = add(100, 50) result["result"] = "ok" return result end end ----------------------------------------------------------------------------- -- Parse request body ngx.req.read_body() local method = ngx.var.request_method if method ~= "POST" then local result = {} result["result"] = "failed" result["reason"] = "use POST method" ngx.say(cjson.encode(result)) else local data = ngx.req.get_body_data() ngx.say(cjson.encode(post_request(data))) end
后记
整个项目的大致思路就是这酱紫的。在这里面,我们曾调研lua在win下怎样调用c;openresty怎样驱动mongodb;mongodb搭建集群数据怎么保持一致…….也傻乎乎的给春哥和云风写过邮件等等。最终前期调研终于顺利完成,累。
原文出处:juejin -> https://juejin.im/entry/5b5435c0f265da0f652385a1
本站所发布的一切资源仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。如果侵犯你的利益,请发送邮箱到 [email protected],我们会很快的为您处理。