上QQ阅读APP看书,第一时间看更新
4.3 OpenResty工作原理
在本节中,我们会详细描述OpenResty工作原理。一个请求进入OpenResty服务器,经过一系列处理后生成响应,最后返给客户端。工作流程大致可以分为4个阶段:Init阶段、Rewrite/Access阶段、Content阶段和Log阶段。图4-2描述了各阶段对应的生命周期以及其中包含的细节。
从图4-2中可以看出,4大阶段又可以细分为11个小阶段。这11个小阶段的指令、所在处理阶段、使用范围和用途如表4-1所示。
多个阶段的存在应该是OpenResty与其他Web平台相比最显著的特征了。Nginx把一个请求分成多个阶段,这样第三方模块就可以挂载到不同阶段进行处理。OpenResty也应用了同样的原理。不同的是,OpenResty挂载的是用户自定义的Lua代码。这些阶段有各自的处理顺序,我们可以通过代码清单4-5查看。
图4-2 OpenResty工作流程
表4-1 OpenResty阶段描述
程序清单4-5 nginx.conf配置文件
46 ... 47 location /mixed { 48 set_by_lua_block $variable { 49 ngx.log(ngx.ERR, "set_by_lua*") 50 } 51 access_by_lua_block { 52 ngx.log(ngx.ERR, "rewrite_by_lua*") 53 } 54 rewrite_by_lua_block { 55 ngx.log(ngx.ERR, "access_by_lua*") 56 } 57 content_by_lua_block { 58 ngx.log(ngx.ERR, "content_by_lua*") 59 } 60 body_filter_by_lua_block { 61 ngx.log(ngx.ERR, "header_filter_by_lua*") 62 } 63 header_filter_by_lua_block { 64 ngx.log(ngx.ERR, "body_filter_by_lua*") 65 } 66 log_by_lua_block { 67 ngx.log(ngx.ERR, "log_by_lua*") 68 } 69 } 70 ...
我们在nginx.conf配置文件中添加了一个新的接口:/mixed,其中包含7个执行阶段。重新启动OpenResty,调用该接口,可以在错误日志中看到如下信息。
[error] 84177#5569291: *417 [lua] set_by_lua:2: set_by_lua* [error] 84177#5569291: *417 [lua] rewrite_by_lua:2: rewrite_by_lua* [error] 84177#5569291: *417 [lua] access_by_lua:2: access_by_lua* [error] 84177#5569291: *417 [lua] content_by_lua:2: content_by_lua* [error] 84177#5569291: *417 [lua] header_filter_by_lua:2: header_filter_by_lua* [error] 84177#5569291: *417 [lua] body_filter_by_lua:2: body_filter_by_lua* [error] 84177#5569291: *417 [lua] log_by_lua:2: log_by_lua*
从输出信息中可以看出,这几个阶段的执行顺序依次为set、rewrite、access、content、header、body、log。实际上,我们可以使用content阶段来完成所有的请求处理,但这样做会使代码臃肿拖沓,后期维护变得困难。在实践中,我们应该将不同的逻辑放在不同的阶段进行处理,这样分工明确、代码独立。