Nginx Lua拓展模块操作Redis、Mysql
# Nginx的拓展模块 # ngx_lua模块 # 淘宝开发的ngx_lua模块通过lua解释器集成近Nginx,可以采用lua脚本实现业务逻辑,由于lua的紧凑、快速以及内建协程,所以在保证宝兵法服务能力的同时极大地降低了业务逻辑实现成本 # ngx_lua模块环境准备 # 方式一:OpenRestry # OpenRestry是由淘宝工程师开发的,其官网是(http://openresty.org/),其上提供了大量的Lua库、第三方模块以及大多数的依赖项。 # 用于方便地搭建能够处理超高并发、扩展性极高的动态Web应用、Web服务和动态网站。 # 所以OpenResty内部就已经集成了Nginx和Lua,所以我们使用起来会更加方便。 # 安装 # 1.下载:https://openresty.org/download/openresty-1.19.9.1.tar.gz # 2.解压缩:tar -zxf openresty-1.19.9.1.tar.gz # 3.进入解压缩后的目录:cd openresty-1.19.9.1 # 4.执行配置命令:./configure # 5.执行编译和安装: make && make install # 6.进入openresty目录,找到Nginx:cd /usr/local/openresty/nginx/ # 7.在conf目录下的Nginx.conf添加如下内容 location /lua { default_type 'text/html'; content_by_lua 'ngx.say("<h1>Hello world,openresty</h1>")'; } # 8.在sbin目录下启动nginx # 9.通过浏览器访问测试 # 直接进入使用例子: location /getByGender { default_type 'text/html'; # set_by_lua set_by_lua $param " --获取请求URL上的参数对应值 name gender local uri_args = ngx.req.get_uri_args() local name = uri_args['name'] local gender = uri_args['gender'] -- 条件判断 if gender=='1' then return name..'先生' elseif gender=='0' then return name..'女士' else return name end " charset utf-8; return 200 $param } # lua操作redis # Redis在系统中经常作为数据缓存、内存数据库使用,在大型系统中扮演者非常重要的作用。在Nginx核心系统中,Redis是常备主键。 # Nginx支持3种方法访问Redis,分别是:HttpRedis模块、HttpRedis2Module、lua-resty-redis库。 # 这三种方式中HttpRedis模块提供的指令少,功能单一,合适做简单的缓存,HttpRedis2Module模块比HttpRedis模块操作更灵活,功能更强大。 #lua-resty-redis库是OpenResty提供的一个Redis的接口库,可根据自己的业务情况来做一些逻辑处理,社和做复杂的业务逻辑。 # 步骤一:lua-resty-redis环境准备:准备一台redis的服务器 # 步骤二:准备对应的API # lua-resty-redis提供了访问Redis的详细API,包括创建对接、链接、操作、数据处理等。这些api基本上与Redis的操作一一对应 # 1.lua导入lua-resty-redis redis = require "resty.redis" # 2.new 语法。创建一个Redis对象 redis,err = redis:new() # 3.connect 设置链接Redis的链接信息 ok,err=redis:connect(host,port[,options_table]) # ok:连接成功返回1,连接失败返回nil # err:返回报错信息 # 4.set_timeout,设置请求操作Redis的超时时间 redis:set_timeout(time) # 5.close 关闭当前链接。成功返回1,失败返回nil和错误信息 ok,err = redis:close() # 6.redis命令对应的方法 # 在lua-resty-redis中,所有的Redis命令独有自己的方法,方法名字和命令明智相同,只是全是小写。 # 实例: location /testRedis{ default_type "text/html"; content_by_lua_block{ local redis = require "resty.redis" local redisObj = redis:new() redisObj:set_timeout(1000) local ok,err = redisObj:connect("192.168.200.111", 6379) if not ok then ngx.say("failed to connection redis", err) return end ok,err = redisObj:set("username", "ROSE") if not ok then ngx.say("faild to set username", err) return end local username, err = redisObj.get("username") if not username then ngx.say("faild to get username",err) return else ngx.say(username) redisObj:close() } } # ngx_lua操作Mysql # 用ngx_lua模块和lua-resty-mysql模块:这两个模块是OpenResty默认安装的 # 你也可以用drizzle_nginx_module(HttpDrizzleModule)模块:这个库不在OpenResty中,所以需要独立安装 # lua-resty-mysql的使用 # API: # 引入"resty.mysql"模块 local mysql = require "resty.mysql" # new 创建一个Mysql连接对象,错误时返回Nil和错误信息 db,err = mysql:new() # connect 连接Mysql服务器,options是一个Lua表结构,里边包含数据库连接的相关信息 # host(服务器ip或者名字)、port(Mysql服务的端口)、user(Mysql的登录用户)、password(登录密码)、database(要连接的数据库名) ok,err = db:connect(options) # set_timeout 设置请求超时时间(ms),包括connect,可以在connect之前设置 db:set_timeout(time) # close 关闭当前连接 db:close() # send_query 异步想远程Mysql发送一个查询语句 bytes,err=db:send_query(sql) # read_result 从Mysql服务器返回的结果中读取一行数据。 res,err,errcode,sqlstate = db:read_result() res,err,errcode,sqlstate = db:read_result(rows) # 返回参数 # res:返回一个描述ok包,或结果集包的Lua表 # err:错误信息 # errcode:mysql的错误码 # sqlstate:sql语句的错误码 # 参数:rows:指定返回结果集的最大行数,默认4 # 如果成功 { {id=1,username="Tom"}, {id=2,username="Jerry"}, } # 如果是增删改: { omsert_id = 0, server_status=2, warning_count=1, affected_rows=2, message=Nil } # 例一: location /testMysql { default_type "text/html"; content_by_lua_block{ local mysql = require "resty.mysql" local db = mysql:new() local ok,err = db:connect{ host="127.0.0.1", port=3306, user="root", password="123456", database="nginx_db" } db:set_timeout(1000) db:send_query("select * from from users") local res,err,errcode,sqlstate = db:read_result(4) ngx.say(res[1].id..","..res[1].username) db:close() } } # 例一的基础上,我们返回json字符串 location /testMysql { default_type "text/html"; content_by_lua_block{ local mysql = require "resty.mysql" local cjson = require "cjson" local db = mysql:new() local ok,err = db:connect{ host="127.0.0.1", port=3306, user="root", password="123456", database="nginx_db" } db:set_timeout(1000) db:send_query("select * from from users") local res,err,errcode,sqlstate = db:read_result(4) --ngx.say(res[1].id..","..res[1].username) ngx.say(cjson.encode(res)) db:close() } } # 在Nginx中配置全局变量init_ty_lua_block导入其他地方也要用到的cjson,防止重复require导入报错 init_ty_lua_block { cjson = require "cjson" } # query快捷方法。query集成了send_query和read_result方法。 # 语法: res,err,errcode,sqlstate = db:query(sql[, rows])