用openresty做后台服务器

文章目录

[隐藏]

  • 与OpenResty及其原作者邂逅
  • 我们后台选用的第三方库和文件
  • 架构思想和坑
  • 讨论太廉价了,直接上代码吧
  • 后记

【腾讯云】校园优惠再度来袭cloud.tencent.com

与OpenResty及其原作者邂逅

OpenResty是一个优秀的开源项目,作者是章亦春。官网是openresty.org/en/。这已经是我第二次在公司项目中使用它展开业务了。分享使用经历的时候,顺便帮春哥推广一下:

其实,我想说的是春哥真的像知乎上传的一样,热情,专业。同时也希望大家都到邮件列表里问问题,像我一样莽莽撞撞直接私发邮件,确实显得不大矜持,汗!

我们后台选用的第三方库和文件

我们后台采用: openresty框架+lua脚本+c函数+mongoDB数据库.这其中的技术细节我们都论证过,现把他们都链接粘出来。

  1. Lua调用mongo的驱动 github.com/bigplum/lua…
  2. OpenResty官网下载 openresty.org/en/download…
  3. 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],我们会很快的为您处理。