openresty中⽂⽂档_OpenResty⼊门指南
⽂章标签:
OpenResty学习笔记
Nginx作为基础⽹关服务在现在主流服务端开发中占据重要作⽤,要在⽹关层⽀持更多的特性,这时候就需要OpenResty了,本⽂记录⼀下OpenResty 做api gateway的⼀些知识
概述
OpenResty: 是基于Nginx与Lua的⾼性能Web平台,带有很多优秀的Lua库,可以做动态服务⽹关。
OpenResty:设计哲学:对于不同的阶段,进⾏相应的不同的处理
Nginx⾮阻塞I/O模型
Lua:是⼀种扩展式的动态类型语⾔,没有main函数概念,只能嵌⼊宿主功能,⾼性能。关于Lua的语⾔介绍可参考Lua中⽂⼿册
架构
Nginx的请求处理阶段有11,其中最重要的也是最常见的3个阶段依次为rewrite, access,content.
下图为Lua Nginx Module指令的执⾏顺序图,可以根据具体的业务场景设置不同的lua脚本。⼏个重要的部分:init_by_lua init_by_lua_block: 运⾏在Nginx loading-config 阶段,注册Nginx Lua全局变量,和⼀些预加载模块。是Nginx master进程在加载Nginx配置时执⾏。
init_worker_by_lua: 在Nginx starting-worker阶段,即每个nginx worker启动时会调⽤,通常⽤来hook worker进程,并创建worker进⾏的计时器,⽤来健康检查,或者设置熔断记时窗⼝等等。
access_by_lua: 在access tail阶段,⽤来对每次请求做访问控制,权限校验等等,能拿到很多相关变量。例如:请求体中的值,header中的值,可以将值添加到, 在其他模块进⾏相应的控制
balancer_by_lua: 通过Lua设置不同的负载均衡策略, 具体可以参考lua-resty-balancer
content_by_lua: 在content阶段,即content handler的⾓⾊,即对于每个api请求进⾏处理,注意不能与proxy_pass放在同⼀个location下proxy_pass: 真正发送请求的⼀部分, 通常介于access_by_lua和log_by_lua之间
header_filter_by_lua:在output-header-filter阶段,通常⽤来重新响应头部,设置cookie等,也可以⽤来作熔断触发标记
body_filter_by_lua:对于响应体的content进⾏过滤处理
log_by_lua:记录⽇志即,记录⼀下整个请求的耗时,状态码等
常⽤命令
ngx.var.<arg>, lua使⽤nginx内置的绑定变量. _addr为获取远程的地址,ngx.var.http_cookie获取cookie信息
<: 每次请求的上下⽂,可以在ctx⾥记录,每次请求上下⽂的⼀些信息,例如:request_id, access_key等等
upstream块⾥的的balancer_by_lua_file, 使⽤ngx.balancer模块,可以实现不同的负载均衡策略,并调⽤set_current_peer函数设置当前query调⽤的backend
对Openresty写的⽹关,测试也⾄关重要,测试是基于perl的单元测试,包含了Nginx C model和OpenResty⽂档地址 OpenResty Test guide
ngx.shared.DICT dict = ngx.shared[name_var] : 获取共享内存的lua dict. 且shared.DICT在当前nginx server实例中被所有nginx worker进程共享。
ngx.shared.DICT当到达定义的⼤⼩限制时,再次调⽤set操作,会使⽤LRU淘汰⼀些key。set操作会返回三个值(success, err, forcible).
ngx.shared.DICT⽀持过期操作,expire等等
对于ngx.shared.DICT的并发安全,使⽤resty.lock库进⾏加速控制
cosocket可以理解为coroutine + socket: 协程特性⽀撑 + nginx事件循环回调机制
ngx.timer.at(delay, callback, user_arg1)为cosocket API,定时任务, 定时执⾏某些异步任务,即异步执⾏某些操作,不必等待结果返回时调⽤。
例如:统计⼀段窗⼝期的请求耗时,发送通知管理员邮件的等等。ngx.timer.at通过递归的⽅式,来实现每隔多长时间,执⾏某些操作。配置
lua_package_path: lua扩展的库的地址, ;;为设置默认的路径
lua_package_cpath: Lua 扩展c 的so库地址, ;;为设置默认的路径
1.
nginx和网关怎么配合使用# set search paths for pure Lua external libraries (';;' is the default path):
2.
lua_package_path '/foo/bar/?.lua;/blah/?.lua;;';
3.
4.
# set search paths for Lua external libraries written in C (can also use ';;'):
5.
lua_package_cpath '/bar/baz/?.so;/blah/blah/?.so;;';
server {
8.
location /lua_content {
9.
# MIME type determined by default_type:
10.
default_type 'text/plain';
11.
12.
content_by_lua_block {
13.
ngx.say('Hello,world!')
14.
}
15.
}
16.
17.
location /nginx_var {
18.
# MIME type determined by default_type:
19.
default_type 'text/plain';
20.
21.
# try access /nginx_var?a=hello,world
22.
content_by_lua_block {
23.
ngx.say(ngx.var.arg_a)
24.
}
25.
}
26.
27.
location = /request_body {
28.
client_max_body_size 50k;
29.
client_body_buffer_size 50k;
30.
31.
content_by_lua_block {
32.
local data = _body_data()
34.
if data then
35.
ngx.say("body data:")
36.
ngx.print(data)
37.
return
38.
end
39.
local file = _body_file()
42.
if file then
43.
ngx.say("body is in file ", file)
44.
else
45.
ngx.say("no body found")
46.
end
47.
}
48.
}
49.
50.
# transparent non-blocking I/O in Lua via subrequests 51.
# (well, a better way is to use cosockets)
52.
location = /lua {
53.
# MIME type determined by default_type:
54.
default_type 'text/plain';
55.
56.
content_by_lua_block {
57.
local res = ngx.location.capture("/some_other_location")
58.
if res then
59.
ngx.say("status: ", res.status)
60.
ngx.say("body:")
61.
ngx.print(res.body)
62.
end
63.
}
64.
}
65.
66.
location = /foo {
67.
rewrite_by_lua_block {
68.
res = ngx.location.capture("/memc",
69.
{ args = { cmd = "incr", key = ngx.var.uri } }
70.
)
71.
}
72.
73.
proxy_pass blah.blah;
76.
location = /mixed {
77.
rewrite_by_lua_file /path/to/rewrite.lua;
78.
access_by_lua_file /path/to/access.lua;
79.
content_by_lua_file /path/to/content.lua;
80.
}
81.
82.
# use nginx var in code path
83.
# CAUTION: contents in nginx var must be carefully filtered, 84.
# otherwise there'll be great security risk!
85.
location ~ ^/app/([-_a-zA-Z0-9/]+) {
86.
set $path $1;
87.
content_by_lua_file /path/to/lua/app/root/$path.lua;
88.
}
89.
90.
location / {
91.
client_max_body_size 100k;
92.
client_body_buffer_size 100k;
93.
94.
access_by_lua_block {
95.
-- check the client IP address is in our black list
96.
if _addr == "132.5.72.3" then
97.
98.
end
99.
100.
-- check if the URI contains bad words
101.
if ngx.var.uri and
102.
string.match(quest_body, "evil")
103.
then
104.
direct("/terms_of_use.html")
105.
end
106.
107.
-- tests passed
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论