文章目录
- 一、nginx介绍
- 1、定义
- 2、优点
- 3、使用场景
- 二、lua介绍
- 1、定义
- 2、优点
- 3、使用场景
- 三、nginx中使用lua
- 四、lua API介绍
- 五、demo举例
一、nginx介绍
1、定义
Nginx 作为一款面向性能设计的HTTP服务器,相较于Apache、lighttpd具有占有内存少,稳定性高等优势。
2、优点
占用内存少,稳定性高、模块化
3、使用场景
网页服务器、反向代理服务器以及电子邮件(IMAP/POP3)代理服务器,高并发大流量站点常用来做接入层的负载均衡,还有非常常见的用法是作为日志采集服务器等。
二、lua介绍
1、定义
是一个简洁、轻量、可扩展的脚本语言
2、优点
轻量级、可拓展、高性能、可移植性
3、使用场景
在很多时候,我们可以将Lua直接嵌入到我们的应用程序中,如游戏、监控服务器等。这样的应用方式对于程序的最终用户而言是完全透明的。
将Lua视为一种独立的脚本语言,通过它来帮助我们完成一些软件产品的辅助性工具的开发。
三、nginx中使用lua
ngx_lua_module 是一个nginx http模块,它把 lua 解析器内嵌到 nginx,用来解析并执行lua 语言编写的网页后台脚本。
下载最新的lua-nginx-module
模块
GitHub地址:https://github.com/openresty/lua-nginx-module/tags
重新编译nginx。
四、lua API介绍
指令 | 所处处理阶段 | 使用范围 | 解释 |
---|---|---|---|
init_by_lua; init_by_lua_file | loading-config | http | nginx Master进程加载配置时执行;通常用于初始化全局配置/预加载Lua模 |
init_worker_by_lua; init_worker_by_lua_file | starting-worker | http | 每个Nginx Worker进程启动时调用的计时器,如果Master进程不允许则只会在init_by_lua之后调用;通常用于定时拉取配置/数据,或者后端服务的健康检查 |
set_by_lua; set_by_lua_file | rewrite | server,server if,location,location if | 设置nginx变量,可以实现复杂的赋值逻辑;此处是阻塞的,Lua代码要做到非常快; |
rewrite_by_lua; rewrite_by_lua_file | rewrite tail | http,server,location,location if | rrewrite阶段处理,可以实现复杂的转发/重定向逻辑; |
access_by_lua; access_by_lua_file | access tail | http,server,location,location if | 请求访问阶段处理,用于访问控制content_by_lua; content_by_lua_file |
header_filter_by_lua; header_filter_by_lua_file | output-header-filter | http,server,location,location if | 设置header和cookie信息 |
body_filter_by_lua; body_filter_by_lua_file | output-body-filter | http,server,location,location if | 对响应数据进行过滤,比如截断、替换 |
log_by_lua; log_by_lua_file | log | http,server,location,location if | log阶段处理,比如记录访问量/统计平均响应时间 |
五、demo举例
upstream kurento {
server 127.0.0.1:8443;
server 127.0.0.1:7443;
}
server {
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
server_name slive.xxwolo.com;
lua_need_request_body on;
listen 443 ssl;
ssl_certificate /usr/local/openresty/nginx/ca/1_xxwolo.com_bundle.crt;
ssl_certificate_key /usr/local/openresty/nginx/ca/2_xxwolo.com.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
location /call {
proxy_pass http://127.0.0.1:8443;
#set $backend '';
#rewrite_by_lua_file /usr/local/openresty/nginx/conf/vhosts/test.lua;
#proxy_pass http://$backend;
#content_by_lua_file /usr/local/openresty/nginx/conf/vhosts/test.lua;
#proxy_pass http://kurento;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header X-Real-IP $remote_addr;
}
location /frist {
proxy_pass http://127.0.0.1:8443;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header X-Real-IP $remote_addr;
}
location /second {
proxy_pass http://127.0.0.1:7443;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header X-Real-IP $remote_addr;
}
location / {
proxy_buffer_size 128k;
proxy_buffers 32 128k;
proxy_busy_buffers_size 256k;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
#proxy_pass http://localhost:8443;
proxy_pass http://kurento;
}
location /call_2 {
#default_type 'text/html';
#lua_code_cache on;
content_by_lua_block {
ngx.req.read_body()
local data = ngx.req.get_body_data()
ngx.say(data)
}
#content_by_lua_file /usr/local/openresty/nginx/conf/vhosts/print.lua;
#proxy_http_version 1.1;
#proxy_set_header Upgrade $http_upgrade;
#proxy_set_header Connection "Upgrade";
#proxy_set_header X-Real-IP $remote_addr;
}
location /register {
#default_type 'text/html';
lua_code_cache on;
content_by_lua_file /usr/local/openresty/nginx/conf/vhosts/register.lua;
}
location /createRoom {
default_type 'text/html';
lua_code_cache on;
content_by_lua_file /usr/local/openresty/nginx/conf/vhosts/createRoom.lua;
}
location /addRoom {
default_type 'text/html';
lua_code_cache on;
content_by_lua_file /usr/local/openresty/nginx/conf/vhosts/addRoom.lua;
}
location /delRoom {
default_type 'text/html';
lua_code_cache on;
content_by_lua_file /usr/local/openresty/nginx/conf/vhosts/delRoom.lua;
}
location /getRoom {
default_type 'text/html';
lua_code_cache on;
content_by_lua_file /usr/local/openresty/nginx/conf/vhosts/getRoom.lua;
}
}
createRoom.lua 的实现如下:
local function close_redis(red)
if not red then
return
end
local ok, err = red:close()
if not ok then
ngx.say("close redis error : ", err)
end
end
local redis = require("resty.redis")
--创建实例
local red = redis:new()
--设置超时(毫秒)
red:set_timeout(1000)
--建立连接
local ip = "127.0.0.1"
local port = 6379
local ok, err = red:connect(ip, port)
if not ok then
ngx.say("connect to redis error : ", err)
return close_redis(red)
end
-- 验证密码
local res, err = red:auth("123456")
if not res then
ngx.say("failed to authenticate: ", err)
return
end
---- 验证获取key
--local ret, err = red:get("11111111")
--if not ret or ret == ngx.null or ret == nil then
-- -- 从zset中,移除,如果key不存在,则忽略
-- ngx.log("lua:移除过期key:")
-- close_redis()
--end
--ngx.say("lua:获取得结果为:", ret);
--close_redis()
-- 读取缓存并打印
local resp, err = red:zrangebyscore("test_zset", 0, 100000)
if not resp then
ngx.say("get msg error : ", err)
return close_redis(red)
end
--得到的数据为空处理
if resp == nil then
ngx.say("lua: 可用服务器列表为空 : ", resp)
return close_redis(red)
end
-- 判断数据是否过期,如果过期,删除重新获取,直到满足条件
local retVal
for key, value in ipairs(resp)
do
ngx.log(ngx.ERR, key, value)
local ret, err = red:get(value)
if not ret or ret == nil or ret == ngx.null then
-- 从zset中,移除,如果key不存在,则忽略
ngx.log(ngx.ERR, value)
red:zrem("test_zset", value)
else
retVal = value
break
end
-- 重新获取resp
resp, err = red:zrangebyscore("test_zset", 0, 100000)
if not resp then
ngx.say("get msg error : ", err)
return close_redis(red)
end
end
ngx.say("lua: 可用服务器的userID为 : ", retVal)
close_redis(red)