CatCoding

OpenResty 使用总结

2017-05-22

OpenResty

最近用 OpenResty 比较多,除了一些业务逻辑的实现也做了 AB 组灰度相关的实现。OpenResty 是在 Nginx 基础上做的扩展,应该算是国人开源项目中很成功的一个。在做的过程中写了不少 Lua 代码,写 Lua 代码的体验就是库好少,语言好简单。

OpenResty lua 编程相关参考

其中 Readme 要看完,大概会有一个全局的了解。最佳实践辅助看看。
理解 Nginx 处理的几个阶段:http://www.nginxguts.com/2011/01/phases/

处理 Response Body

在我们的实现中有一步需要给后端返回的结果里面加一段水印 (也就是一段 JS 代码),这步可以在 body_filter 这个里面做。不过需要注意 body_filter 是按流式方式处理的,需要把各个 buffer 存下来然后拼接起来。
而且后端返回的结果可能是 zip 压缩过的,所以需要解压,然后才能做替换或者拼接的操作

local chunk, eof = ngx.arg[1], ngx.arg[2] 
local buffered = ngx.ctx.buffered 
if not buffered then 
   buffered = {}  -- XXX we can use table.new here 
   ngx.ctx.buffered = buffered 
end

if chunk ~= "" then 
   buffered[#buffered + 1] = chunk 
   ngx.arg[1] = nil 
end

if eof then 
   local whole = table.concat(buffered) 
   ngx.ctx.buffered = nil

   -- try to unzip
   local status, debody = pcall(com.decode, whole)
   
   if status then whole = debody end
   -- try to add or replace response body
   local js_code = ....
   whole = whole .. js_code
   
   ngx.arg[1] = whole 
end

最后因为修改了 response body,所以需要修改 header filter 里面的部分:

ngx.header.content_length = nil
ngx.header.content_encoding = nil

容易出现的 bug

  1. 尽量使用 local 变量: 具体的解释,我在实践的过程中出现过变量乱窜的情况,结果发现是没有是用 local。

  2. ngx.ctx 比 ngx.var 性能要好很多,但是在执行了 ngx.exec 后在子请求里 ctx 不一样,在我们的项目里大部分是用的是 ngx.var。使用 ngx.var 需要注意的是需要在 Nginx 配置文件里面提前声明。另外ngx.ctx 在使用的时候也有需要注意的地方

  3. 不同阶段共享变量

  4. 不要使用错误码来做内部跳转,使用 ngx.exec 很方便。

  5. 是用推荐的方法来实现 module

公号同步更新,欢迎关注👻