> For the complete documentation index, see [llms.txt](https://idevz.gitbook.io/vanilla-zh/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://idevz.gitbook.io/vanilla-zh/za-xiang/nginx_phrase.md).

# Nginx执行阶段

## Openresty是什么？

重申一下Openresty是什么？截一张Openresty官网，春哥对Openresty的一个官方说明如下图： ![Openresty官方说明](/files/-LPs0nYLh0a90kNutVAT)

我的理解Openresty = Nginx + ngx*http\_lua\_module + lua\_resty*\*；它是一个原生Nginx合上一个HTTP\_LUA模块，在加上一系列Lua\_resty模块组成的一个Ngx\_Lua高性能服务生态。

## Openresty处理HTTP请求的执行阶段

Openrestry处理HTTP请求的执行阶段来自于Nginx，Nginx的HTTP框架依据常见的处理流程将处理阶段划分为11个阶段，其中每个处理阶段可以由任意多个HTTP模块流水式地处理请求，Openresty通过ngx\_http\_lua\_module将Lua特性嵌入Nginx，ngx\_http\_lua\_module属于一个Nginx的HTTP模块，为高性能服务开发封装了7个相应HTTP请求处理阶段如下：

* *set\_by\_lua*
* *content\_by\_lua*
* *rewrite\_by\_lua*
* *access\_by\_lua*
* *header\_filter\_by\_lua*
* *body\_filter\_by\_lua*
* *log\_by\_lua*

有同学会发现，Openresty所提供的LUA解析指令还有以下两个：

* *init\_by\_lua*
* *init\_worker\_by\_lua*

  `init_by_lua`作用在配置加载阶段，`init_worker_by_lua`作用在worker进程初始化阶段，并非HTTP请求处理阶段。

另外，需要重点提一下的是，Nginx输出过滤器是流式处理模型，一个数据块body filter就被调用一次。可以用以下简单的例子测试验证： *nginx.conf*

```
http {
    # use sendfile
    sendfile on;

    # Va initialization
    lua_package_path "...;;";
    lua_package_cpath "...;";
    lua_code_cache off;

    init_by_lua_block {ngx.log(ngx.ERR, '=======>init')}
    init_worker_by_lua_block {ngx.log(ngx.ERR, '=======>init_worker')}
    rewrite_by_lua_block {ngx.log(ngx.ERR, '=======>rewrite')}
    access_by_lua_block {ngx.log(ngx.ERR, '=======>access')}
    header_filter_by_lua_block {ngx.log(ngx.ERR, '=======>header_filter')}
    body_filter_by_lua_block {ngx.log(ngx.ERR, '=======>body_filter')}
    log_by_lua_block {ngx.log(ngx.ERR, '=======>log')}


    server {
        # List port
        listen 7200;
        set $template_root '';
        set_by_lua_block $a {ngx.log(ngx.ERR, '=======>set'); return 'xxx'}

        # Access log with buffer, or disable it completetely if unneeded
        access_log logs/development-access.log combined buffer=16k;
        # access_log off;

        # Error log
        error_log logs/development-error.log;

        # Va runtime
        location / {
            content_by_lua_block {
                ngx.log(ngx.ERR, '=======>content')
                ngx.say('----------')
                ngx.say('---ccc-------')
                ngx.say('---vvvv-------')
                ngx.say('---vdddv-------')
                ngx.say('---ggvv-------')
            }

            # content_by_lua_file ./pub/index.lua;
        }
    }
}
```

*logs/development-error.log截取*

```
set_by_lua:1: =======>set
rewrite_by_lua(development-nginx.conf:31):1: =======>rewrite
access_by_lua(development-nginx.conf:32):1: =======>access
content_by_lua(development-nginx.conf:60):2: =======>content
header_filter_by_lua:1: =======>header_filter
body_filter_by_lua:1: =======>body_filter
body_filter_by_lua:1: =======>body_filter
body_filter_by_lua:1: =======>body_filter
body_filter_by_lua:1: =======>body_filter
body_filter_by_lua:1: =======>body_filter
body_filter_by_lua:1: =======>body_filter
log_by_lua(development-nginx.conf:35):1: =======>log while logging request
```

可以看出body\_filter的执行次数等于ngx.say数量加一
