<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                ## 場景 我們先定義一個`location`塊級指令`phase_echo`來處理客戶端發過來請求URI處理 ``` location /phase_echo { set $name "Tinywan"; echo $name; set $name "開源技術小棧"; echo $name; set $name "Tinywan 開源技術小棧"; echo $name; } ``` 請求訪問輸出結果 ```ts curl -i http://openresty.tinywan.com/phase_echo HTTP/1.1 200 OK Server: openresty/1.17.8.2 Date: Sun, 14 Jul 2024 00:31:18 GMT Content-Type: application/octet-stream Transfer-Encoding: chunked Connection: keep-alive Tinywan 開源技術小棧 Tinywan 開源技術小棧 Tinywan 開源技術小棧 ``` > 為什么輸出全部是:`Tinywan 開源技術小棧`,也就是最后一個設置的變量值呢?前面設置的怎么都沒生效嗎? 這是因為Nginx處理每一個用戶請求時,都是按照若干個不同階段依次處理的,而不是根據配置文件上的順序。以上配置涉及到了 兩個階段 `rewrite`和`content`階段 * `set`屬于`rewrite`階段 * `echo`屬于`content`階段 而實際執行執行是 `rewrite`階段的指令在 `content`階段指令之前執行。實際的執行順序應當是 ``` set $name "Tinywan"; set $name "開源技術小棧"; set $name "Tinywan 開源技術小棧"; echo $name; echo $name; echo $name; ``` 所以這就是為什么最終會輸出`Tinywan 開源技術小棧`。通過以上配置文件中執行的指令,讓我進入Nginx執行流程與階段一探究竟。 ## Nginx執行階段 Nginx處理請求的過程一共劃分為11個階段,按照執行順序依次是post-read、server-rewrite、find-config、rewrite、post-rewrite、 preaccess、access、post-access、try-files、content、log。 所以整個請求的過程,是按照不同的階段執行的,在某個階段執行完該階段的指令之后,再進行下一個階段的指令執行。 > 執行階段示例 ![](https://img.kancloud.cn/80/41/80410da3fa56732e682c3f952a119115_3505x1805.png) 1. **post-read**:讀取請求內容階段,nginx讀取并解析完請求頭之后就立即開始運行。例如模塊 `ngx_realip` 就在 `post-read` 階段注冊了處理程序。它的功能是迫使 Nginx 認為當前請求的來源地址是指定的某一個請求頭的值。 2. **server-rewrite**:`server`請求地址重寫階段,當`ngx_rewrite`模塊的`set`配置指令直接書寫在`server`配置塊中時,基本上都是運行在`server-rewrite`階段。 3. **find-config**:配置查找階段,這個階段并不支持Nginx模塊注冊處理程序,而是由Nginx核心來完成當前請求與location配置塊之間的配對工作。 4. **rewrite**:`location`請求地址重寫階段,當`ngx_rewrite`指令用于`location`中,就是再這個階段運行的。另外`ngx_set_misc(設置md5、encode_base64等)`模塊的指令,還有`ngx_lua`模塊的`set_by_lua`指令和`rewrite_by_lua`指令也在此階段。 5. **post-rewrite**:請求地址重寫提交階段,當nginx完成rewrite階段所要求的內部跳轉動作,如果rewrite階段有這個要求的話。 6. **preaccess**:訪問權限檢查準備階段,`ngx_limit_req`和`ngx_limit_zone`在這個階段運行,`ngx_limit_req`可以控制請求的訪問頻率,`ngx_limit_zone`可以控制訪問的并發度; 7. **access**:訪問權限檢查階段,標準模塊`ngx_access`、第三方模塊`ngx_auth_request`以及第三方模塊`ngx_lua`的`access_by_lua` 指令就運行在這個階段。配置指令多是執行訪問控制相關的任務,如檢查用戶的訪問權限,檢查用戶的來源IP是否合法。 8. **post-access**:訪問權限檢查提交階段;主要用于配合`access`階段實現標準`ngx_http_core`模塊提供的配置指令`satisfy`的功能。 `satisfy all`(與關系),`satisfy any`(或關系) 9. **try-files**:配置項`try_files`處理階段;專門用于實現標準配置指令`try_files`的功能,如果前`N-1`個參數所對應的文件系統對象都不存在,`try-files` 階段就會立即發起`內部跳轉`到最后一個參數(即第 N 個參數)所指定的URI. 10. **content**:內容產生階段,是所有請求處理階段中最為重要的階段,因為這個階段的指令通常是用來生成HTTP響應內容并輸出 HTTP 響應的使命. 11. **log**:日志模塊處理階段,記錄日志 ## OpenResty 的運行機制 ![](https://img.kancloud.cn/42/42/42425619c662528c8ae5a5d315a7826f_867x383.png) 圖片來源:https://yxudong.github.io ## OpenResty 執行階段 OpenResty發起一個請求時,會有相應的執行流程,Nginx與Lua編寫腳本的基本構建塊是指令執行順序的 ![](https://img.kancloud.cn/9a/c9/9ac922e4648df2a49d879ab8ba7e73d6_1005x910.png) > 從圖中可知,OpenResty 處理請求大致分為4個大階段,11個小階段 #### 四個大階段 * 初始化階段(Initialization Phase) master進程啟動預加載/生成worker進程預加載 * 重寫、轉發、訪問階段(Rewrite / Access Phase) url轉發,權限判斷 * 內容處理/生成階段(Content Phase) 內容生成 * 日志階段(Log Phase)日志記錄 #### 七個小階段 * **init_by_lua_file**:master-initing 階段,初始化全局配置或模塊 * **init_worker_by_lua_file**:worker-initing 階段,初始化進程專用功能 * **ssl_certificate_by_lua_file**:ssl 階段,在握手時設置安全證書 * **set_by_lua_file**:rewrite 階段,改寫 Nginx 變量 * **rewrite_by_lua_file**:rewrite 階段,改寫 URI ,實現跳轉或重定向 * **access_by_lua_file**:access 階段,訪問控制或限速 * **content_by_lua_file**:content 階段,產生響應內容 * **balancer_by_lua_file**:content 階段,反向代理時選擇后端服務器 * **header_filter_by_lua_file**:filter 階段,加工處理響應頭 * **body\_filter\_by\_lua\_file**:filter 階段,加工處理響應體 * **log\_by\_lua\_file**:log 階段,記錄日志或其他的收尾工作 > 這些指令通常有三種形式 * `xxx_by_lua`:執行字符串形式的 Lua 代碼: * `xxx_by_lua_block`:功能相同,但指令后是{ ...}的 Lua 代碼塊 * `xxx_by_lua_file`:功能相同,但執行磁盤上的 Lua 源碼文件。 這邊推薦使用 `xxx_by_lua_file`,它徹底分離了配置文件與業務代碼,讓兩者可以獨立部署,而且文件形式也讓我們更容易以模塊的方式管理組織 Lua 程序。 ### OpenResty 執行階段和 Nginx 的對照 ![](https://img.kancloud.cn/07/83/07832e73bca0abb528ad1f4a5b743273_1351x818.png) 圖片來源:https://blog.51cto.com/lisea/2425794 ``` server { listen 80; server_name openresty.tinywan.com; location /run_phase { set_by_lua_block $a { ngx.log(ngx.ERR, "Tinywan is set_by_lua_block phase") } rewrite_by_lua_block { ngx.log(ngx.ERR, "Tinywan is rewrite_by_lua_block phase") } access_by_lua_block { ngx.log(ngx.ERR, "Tinywan is access_by_lua_block phase") } content_by_lua_block { ngx.log(ngx.ERR, "Tinywan is content_by_lua_block phase") } header_filter_by_lua_block { ngx.log(ngx.ERR, "Tinywan is header_filter_by_lua_block phase") } body_filter_by_lua_block { ngx.log(ngx.ERR, "Tinywan is body_filter_by_lua_block phase") } log_by_lua_block { ngx.log(ngx.ERR, "Tinywan is log_by_lua_block phase") } } } ``` 執行請求訪問 ``` curl -i http://openresty.tinywan.com/run_phase ``` 查看錯誤日志文件內容 ``` 2024/07/13 12:38:43 [error] 7#7: *2 [lua] set_by_lua:2: Tinywan is set_by_lua_block phase, client: 172.18.0.1, server: openresty.tinywan.com, request: "GET /run_phase HTTP/1.1", host: "openresty.tinywan.com" 2024/07/13 12:38:43 [error] 7#7: *2 [lua] rewrite_by_lua(openresty.tinywan.com.conf:18):2: Tinywan is rewrite_by_lua_block phase, client: 172.18.0.1, server: openresty.tinywan.com, request: "GET /run_phase HTTP/1.1", host: "openresty.tinywan.com" 2024/07/13 12:38:43 [error] 7#7: *2 [lua] access_by_lua(openresty.tinywan.com.conf:22):2: Tinywan is access_by_lua_block phase, client: 172.18.0.1, server: openresty.tinywan.com, request: "GET /run_phase HTTP/1.1", host: "openresty.tinywan.com" 2024/07/13 12:38:43 [error] 7#7: *2 [lua] content_by_lua(openresty.tinywan.com.conf:26):2: Tinywan is content_by_lua_block phase, client: 172.18.0.1, server: openresty.tinywan.com, request: "GET /run_phase HTTP/1.1", host: "openresty.tinywan.com" 2024/07/13 12:38:43 [error] 7#7: *2 [lua] header_filter_by_lua:2: Tinywan is header_filter_by_lua_block phase, client: 172.18.0.1, server: openresty.tinywan.com, request: "GET /run_phase HTTP/1.1", host: "openresty.tinywan.com" 2024/07/13 12:38:43 [error] 7#7: *2 [lua] body_filter_by_lua:2: Tinywan is body_filter_by_lua_block phase, client: 172.18.0.1, server: openresty.tinywan.com, request: "GET /run_phase HTTP/1.1", host: "openresty.tinywan.com" 2024/07/13 12:38:43 [error] 7#7: *2 [lua] log_by_lua(openresty.tinywan.com.conf:38):2: Tinywan is log_by_lua_block phase while logging request, client: 172.18.0.1, server: openresty.tinywan.com, request: "GET /run_phase HTTP/1.1", host: "openresty.tinywan.com" ``` 通過日志文件記錄可以看到執行是按照階段順序進行輸出
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看