openresty中如何写redis或者mysql的wraper
ngx_lua获取post字段参数
在用户请求为POST方式时,如果想获取post中的各参数字段,比如post数据为 “uid=100&ip=10.13.112.53”,此时想获取该字段的话,可以调用ngx.req.get_post_args函数。按惯例返回table类型,post数据的各字段为table的key
|
|
关于HTTP的POST提交数据的方式,网上有很多讨论
- 四种常见的POST提交数据方式
- application/x-www-form-urlencoded
- multipart/form-data
- application/json
- text/xml
- HTTP header头的一些字段
ngx_lua同样提供了读写HTTP请求中uri参数,读写HTTP请求中的HEADER头部,这些在ngx_lua开发中为我们提供了丰富的工具,非常好的功能。
最后回到主题,当我读出uid字段后,有时候会发现报错"requesty body in temp file not supported",原因在于nginx会将用户请求的body字段缓存起来,如果超出缓存大小,则将用户body数据写到文件中;而ngx.req.get_post_args()是不支持从文件中读取数据的。因此解决办法是:适当加大 nginx 的 client_body_buffer_size 配置, 当 client_body_buffer_size 配置为和 client_max_body_size 一样大时,nginx就不会把请求体缓冲到文件系统了(但也要仔细内存占用)。
对于client_max_body_size来说,
|
|
设置允许的client body最大值,对http server来说是种保护。
对于client_body_buffer_size来说,
|
|
如果client body size大于默认值,则nginx将会把body缓存在文件中。将client body buffer size设置为和client_max_body_size一样大,nginx将不会把它写进文件中。
ngx_lua中判断table为空
- lua的table中,有两类kv,一类是以数字为index,比如{‘abc’, ’efg’}中,{k=1, v=abc}, {k=2, v=efg},另一类以自己kv存储,比如{[‘abc’] = ’efg’},k为abc的元素,v为efg
- #table中,#标识符是返回以数字为index的key,从1开始算,连续的key的数量
|
|
- 因此#号不能获得table的真实大小,也不能用于判断table是否为空
- table.maxn(tab),maxn返回table中以数字为key的元素中,数字最大的那个
|
|
-
next就是pairs遍历table时用来取下一个内容的函数,因此next(tab)可以用来判断table是否为空,如果next(tab)返回为nil的话,说明第一个元素不存在,所以该table为空
ngx_lua中的参数获得
ngx_lua中获得req参数有如下几个方法:
-
ngx.var.arg_city 获取city参数
- host:port/uri?city=abc ngx.var.arg_city = abc
- host:port/uri?city= ngx.var.arg_city = ‘’, and its length is 0
- host:port/uri?city ngx.var.arg_city = nil,cause it doesn’t exist yet
-
ngx.req.get_headers()[‘city’],获取http请求头中的city参数
- host:port/uri -H ‘city:abc’ 结果为abc
- host:port/uri -H ‘city:’ 结果为nil
-
- 虽然init_worker_by_lua阶段不能使用cosocket,不过可以先通过一个timer(定时时间为0让其立即调用)来发出对外的socket io操作,以实现一些初始化的目的。
- openresty的两个缓存中,ngx shared dict是跨worker共享的,是一个单纯的kv缓存;预计接下来会有patch能够支持lpush等redis操作;lua-resty-lrucache是每个worker的Lua VM空间内缓存,不能跨worker共享,优点是可以存储所有lua对象,比如table,而不需要序列化和反序列化
-
worker 启动时,upstream 是空的,即 _M.data={},所以这个时候是不能提供服务的。所以每次 reload config 都会导致一段时间内服务不可访问。
- 在 init_worker_by_lua 执行 cosocket 相关的 API 是不允许的(后期可能会添加支持),但可以调用标准 SOCKET 完成初始化加载,例如借助 luasocket 完成数据源获取并初始化 _M 。
-
不清楚 init_worker_by_lua 里是否可以进行文件操作?
- 是可以的,这个确定。
-
在ngx lua性能分析方面,agentzh提出一系列的工具,主要是nginx-systemtap-toolkit和stapxx两个工程。我们使用的脚本,说明文档
|
|
|
|
- 通过a.bt生成火焰图
|
|
- 通过脚本ngx-lua-conn-pools来追踪ngx lua connection pool的工作情况。
|
|