Appearance
OpenResty
参考资料
- https://www.nginx.com/resources/wiki/modules/lua/
- https://github.com/openresty/lua-nginx-module/blob/master/README.markdown
- https://moonbingbing.gitbooks.io/openresty-best-practices/content/
- http://openresty.org/en/getting-started.html
- http://mjvvv.cn/blogBrowse?blogId=82#_5
- http://mjvvv.cn/blogBrowse?blogId=81
- https://www.bilibili.com/video/BV1nU4y1x7Lt
- https://www.bilibili.com/video/BV18c411W7mb
- https://time.geekbang.org/column/article/
用做网关,openresty的配置
从以下网页来看,可配置
access_by_lua
https://blog.csdn.net/Long_xu/article/details/128501575
找了一下此配置
lua
location / {
root /usr/local/openresty/nginx/html;
index index.html index.htm;
access_by_lua '
local args = ngx.req.get_uri_args()
local salt = args.param
if salt == "auth" then
return
else
ngx.exit(ngx.HTTP_FORBIDDEN)
end
';
}
docker openresty 目录
/usr/local/openresty/nginx/conf/nginx.conf
/etc/nginx/conf.d
OpenResty入门
快速入门
http://openresty.org/en/getting-started.html#prepare-the-nginxconf-config-file
- /etc/nginx/conf.d/default.conf
nginx
server {
listen 80;
server_name localhost;
lua_code_cache off;
location / {
root /usr/local/openresty/nginx/html;
index index.html index.htm;
}
location /hello {
default_type text/html;
content_by_lua_block {
ngx.say("<p>hello, world</p>")
}
}
}
执行lua文件
/etc/nginx/conf.d/default.conf
nginx
server {
listen 80;
server_name localhost;
lua_code_cache off;
location / {
root /usr/local/openresty/nginx/html;
index index.html index.htm;
}
location /hello {
default_type text/html;
content_by_lua_file lua/hello.lua;
}
}
/usr/local/openresty/nginx/lua/hello.lua
lua
ngx.say("Hello World!!!")
关闭nginx缓存
修改lua代码之后,nginx执行的还是原来的代码,原因是默认nginx将缓存开启了
可使用
lua_code_cache
指令关闭缓存,可在以下位置配置
- http
- server
- location
- location if
案例
根据盐值,生成随机md5
/etc/nginx/conf.d/default.conf
nginx
server {
listen 80;
server_name localhost;
lua_code_cache off;
location / {
root /usr/local/openresty/nginx/html;
index index.html index.htm;
}
location /get_random_string {
default_type text/html;
content_by_lua_file lua/get_random_string.lua;
}
}
/usr/local/openresty/nginx/lua/get_random_string.lua
lua
local args = ngx.req.get_uri_args()
local salt = args.salt
if not salt then
ngx.exit(ngx.HTTP_BAD_REQUEST)
end
local string = ngx.md5(ngx.time() .. salt)
ngx.say(string)
案例
客户端发送base64,服务器解析后,响应json
nginx lua module 具备 40 多个指令和 120 多个 API
/etc/nginx/conf.d/default.conf
nginx
server {
listen 80;
server_name localhost;
lua_code_cache off;
location / {
root /usr/local/openresty/nginx/html;
index index.html index.htm;
}
location /decode_info {
default_type text/html;
content_by_lua_file lua/decode_info.lua;
}
}
/usr/local/openresty/nginx/lua/decode_info.lua
lua
local json = require "cjson"
ngx.req.read_body()
local args = ngx.req.get_post_args()
if not args or not args.info then
ngx.exit(ngx.HTTP_BAD_REQUEST)
end
local client_ip = ngx.var.remote_addr
local user_agent = ngx.req.get_headers()['user-agent'] or ''
local info = ngx.decode_base64(args.info)
local response = {}
response.info = info
response.ip = client_ip
response.user_agent = user_agent
ngx.say(json.encode(response))
bash
bash
curl -i --data 'info=5L2g5aW9' http://localhost/decode_info
连接数据库
- 连接redis
在以下页面搜redis,进入lua-resty-redis
https://github.com/openresty/lua-nginx-module/blob/master/README.markdown
进入 https://github.com/openresty/lua-resty-redis#synopsis
nginx
server {
listen 80;
server_name localhost;
lua_code_cache off;
location /test {
# need to specify the resolver to resolve the hostname
resolver 8.8.8.8;
content_by_lua_block {
local redis = require "resty.redis"
local red = redis:new()
red:set_timeouts(1000, 1000, 1000) -- 1 sec
-- or connect to a unix domain socket file listened
-- by a redis server:
-- local ok, err = red:connect("unix:/path/to/redis.sock")
-- connect via ip address directly
local ok, err = red:connect("127.0.0.1", 6379)
-- or connect via hostname, need to specify resolver just like above
local ok, err = red:connect("redis.openresty.com", 6379)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ok, err = red:set("dog", "an animal")
if not ok then
ngx.say("failed to set dog: ", err)
return
end
ngx.say("set result: ", ok)
local res, err = red:get("dog")
if not res then
ngx.say("failed to get dog: ", err)
return
end
if res == ngx.null then
ngx.say("dog not found.")
return
end
ngx.say("dog: ", res)
red:init_pipeline()
red:set("cat", "Marry")
red:set("horse", "Bob")
red:get("cat")
red:get("horse")
local results, err = red:commit_pipeline()
if not results then
ngx.say("failed to commit the pipelined requests: ", err)
return
end
for i, res in ipairs(results) do
if type(res) == "table" then
if res[1] == false then
ngx.say("failed to run command ", i, ": ", res[2])
else
-- process the table value
end
else
-- process the scalar value
end
end
-- put it into the connection pool of size 100,
-- with 10 seconds max idle time
local ok, err = red:set_keepalive(10000, 100)
if not ok then
ngx.say("failed to set keepalive: ", err)
return
end
-- or just close the connection right away:
-- local ok, err = red:close()
-- if not ok then
-- ngx.say("failed to close: ", err)
-- return
-- end
}
}
}
OpenResty缓存
shared_dict
多worker共享,线程不安全
- 定义
nginx.conf
nginx
# 指定shared_dict名字为my_cache,大小为128m
lua_shared_dict cache_ngx 128m;
- 使用
lua
function get_from_cache(key)
local cache_ngx = ngx.shared.cache_ngx
local value = cache_ngx:get(key)
return value
end
lua_resty_lrucache
- 不预设内存大小,只预存key个数
- 每个worker单独占用,线程安全,内存占用翻倍
- lurcache API只有get、set、delete
shared_dict
还可以add
、replace
、incr
、get_keys
、get_stake
案例
lua
local red = redis:new()
function set_to_cache(key, value, exptime)
if not exptime then
exptime = 0
end
local cache_ngx = ngx.shared.cache_ngx
local succ, err, forcible = cache_ngx:set(key, value, exptime)
return succ
end
function get_from_cache(key)
local cache_ngx = ngx.shared.cache_ngx
local value = cache_ngx:get(key)
if not value then
value = get_from_redis(key)
set_to_cache(key, value)
end
return value
end
function get_from_redis(key)
local res, err = red:get("dog)
if res then
return 'yes'
else
return 'no'
end
end
local res = get_from_cache('dog)
ngx.say(res)
bash
# 用100个终端,模拟100000次请求,查看qps
ab -n 100000 -c 100 -k http://localhost/get_value
lua-resty-casbin
参考以下链接安装,但需要注意的是,安装lua-resty-casbin时,文档中是使用url安装,实测装不上
https://github.com/casbin-lua/lua-resty-casbin/
安装casbin的系统依赖
bash
apt update
apt install make wget unzip zip gcc libpcre3 libpcre3-dev git
安装luarocks
bash
wget https://luarocks.org/releases/luarocks-3.9.2.tar.gz
tar zxpf luarocks-3.9.2.tar.gz
cd luarocks-3.9.2
# 以下的jit版本号: 2.1.0-beta3,可参考以下目录修改
# /usr/local/openresty/luajit/bin
./configure --prefix=/usr/local/openresty/luajit \
--with-lua=/usr/local/openresty/luajit/ \
--lua-suffix=jit-2.1.0-beta3 \
--with-lua-include=/usr/local/openresty/luajit/include/luajit-2.1
make
make install
安装casbin
bash
/usr/local/openresty/luajit/bin/luarocks install casbin
安装lua-resty-casbin
bash
/usr/local/openresty/luajit/bin/luarocks install lua-resty-casbin
干预-prefix参数的几种方式
- 在Dockerfile上看
https://github.com/openresty/docker-openresty/blob/master/centos/Dockerfile
发现有这样的一行
CMD ["/usr/bin/openresty", "-g", "daemon off;"]
可以在docker-compose.yml文件上改
说明并没有设置-p参数
进入容器,使用openresty -h命令,提示出以下信息
Options:
-?,-h : this help
-v : show version and exit
-V : show version and configure options then exit
-t : test configuration and exit
-T : test configuration, dump it and exit
-q : suppress non-error messages during configuration testing
-s signal : send signal to a master process: stop, quit, reopen, reload
-p prefix : set prefix path (default: /usr/local/openresty/nginx/)
-e filename : set error log file (default: logs/error.log)
-c filename : set configuration file (default: conf/nginx.conf)
-g directives : set global directives out of configuration file
说明-p参数的默认值是/usr/local/openresty/nginx
- 使用nginx指令
lua_package_path
lua_package_path "$prefix/lua/?.lua;$prefix/lua/vendor/?.lua;;";
注意是两个分号
其中prefix就是启动时的-p参数