• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            Fork me on GitHub
            隨筆 - 215  文章 - 13  trackbacks - 0
            <2018年5月>
            293012345
            6789101112
            13141516171819
            20212223242526
            272829303112
            3456789


            專注即時通訊及網游服務端編程
            ------------------------------------
            Openresty 官方模塊
            Openresty 標準模塊(Opm)
            Openresty 三方模塊
            ------------------------------------
            本博收藏大部分文章為轉載,并在文章開頭給出了原文出處,如有再轉,敬請保留相關信息,這是大家對原創作者勞動成果的自覺尊重!!如為您帶來不便,請于本博下留言,謝謝配合。

            常用鏈接

            留言簿(1)

            隨筆分類

            隨筆檔案

            相冊

            Awesome

            Blog

            Book

            GitHub

            Link

            搜索

            •  

            積分與排名

            • 積分 - 215473
            • 排名 - 118

            最新評論

            閱讀排行榜

            http://jinnianshilongnian.iteye.com/blog/2280928
            在互聯網公司,Nginx可以說是標配組件,但是主要場景還是負載均衡、反向代理、代理緩存、限流等場景;而把Nginx作為一個Web容器使用的還不是那么廣泛。Nginx的高性能是大家公認的,而Nginx開發主要是以C/C++模塊的形式進行,整體學習和開發成本偏高;如果有一種簡單的語言來實現Web應用的開發,那么Nginx絕對是把好的瑞士軍刀;目前Nginx團隊也開始意識到這個問題,開發了nginxScript:可以在Nginx中使用JavaScript進行動態配置一些變量和動態腳本執行;而目前市面上用的非常成熟的擴展是由章亦春將Lua和Nginx粘合的ngx_lua模塊,并且將Nginx核心、LuaJIT、ngx_lua模塊、許多有用的Lua庫和常用的第三方Nginx模塊組合在一起成為OpenResty,這樣開發人員就可以安裝OpenResty,使用Lua編寫腳本,然后部署到Nginx Web容器中運行。從而非常輕松就能開發出高性能的Web服務。

             

            接下來我們就認識下Nginx、Lua、ngx_lua模塊和ngx_lua到底能開發哪些類型的web應用。

             

             

            一、ngx_lua簡介

            1、Nginx優點

            Nginx設計為一個主進程多個工作進程的工作模式,每個進程是單線程來處理多個連接,而且每個工作進程采用了非阻塞I/O來處理多個連接,從而減少了線程上下文切換,從而實現了公認的高性能、高并發;因此在生成環境中會通過把CPU綁定給Nginx工作進程從而提升其性能;另外因為單線程工作模式的特點,內存占用就非常少了。

            Nginx更改配置重啟速度非常快,可以毫秒級,而且支持不停止Nginx進行升級Nginx版本、動態重載Nginx配置。

            Nginx模塊也是非常多,功能也很強勁,不僅可以作為http負載均衡,Nginx發布1.9.0版本還支持TCP負載均衡,還可以很容易的實現內容緩存、web服務器、反向代理、訪問控制等功能。

             

            2、Lua的優點

            Lua是一種輕量級、可嵌入式的腳本語言,這樣可以非常容易的嵌入到其他語言中使用。另外Lua提供了協程并發,即以同步調用的方式進行異步執行,從而實現并發,比起回調機制的并發來說代碼更容易編寫和理解,排查問題也會容易。Lua還提供了閉包機制,函數可以作為First Class Value 進行參數傳遞,另外其實現了標記清除垃圾收集。

            因為Lua的小巧輕量級,可以在Nginx中嵌入Lua VM,請求的時候創建一個VM,請求結束的時候回收VM。

             

            3、什么是ngx_lua

            ngx_lua是Nginx的一個模塊,將Lua嵌入到Nginx中,從而可以使用Lua來編寫腳本,這樣就可以使用Lua編寫應用腳本,部署到Nginx中運行,即Nginx變成了一個Web容器;這樣開發人員就可以使用Lua語言開發高性能Web應用了。

            ngx_lua提供了與Nginx交互的很多的API,對于開發人員來說只需要學習這些API就可以進行功能開發,而對于開發web應用來說,如果接觸過Servlet的話,其開發和Servlet類似,無外乎就是知道接收請求、參數解析、功能處理、返回響應這幾步的API是什么樣子的。

             

            4、開發環境

            我們可以使用OpenResty來搭建開發環境,OpenResty將Nginx核心、LuaJIT、許多有用的Lua庫和Nginx第三方模塊打包在一起;這樣開發人員只需要安裝OpenResty,不需要了解Nginx核心和寫復雜的C/C++模塊就可以,只需要使用Lua語言進行Web應用開發了。

            如何安裝可以參考《跟我學Nginx+Lua開發》。

             

            5、OpenResty生態

            OpenResty提供了一些常用的ngx_lua開發模塊:如

              lua-resty-memcached

              lua-resty-mysql

              lua-resty-redis

              lua-resty-dns

              lua-resty-limit-traffic

              lua-resty-template

            這些模塊涉及到如mysql數據庫、redis、限流、模塊渲染等常用功能組件;另外也有很多第三方的ngx_lua組件供我們使用,對于大部分應用場景來說現在生態環境中的組件已經足夠多了;如果不滿足需求也可以自己去寫來完成自己的需求。

             

            6、場景

            理論上可以使用ngx_lua開發各種復雜的web應用,不過Lua是一種腳本/動態語言,不適合業務邏輯比較重的場景,適合小巧的應用場景,代碼行數保持在幾十行到幾千行。目前見到的一些應用場景:

            web應用:會進行一些業務邏輯處理,甚至進行耗CPU的模板渲染,一般流程:mysql/redis/http獲取數據、業務處理、產生JSON/XML/模板渲染內容,比如京東的列表頁/商品詳情頁

            接入網關:實現如數據校驗前置、緩存前置、數據過濾、API請求聚合、AB測試、灰度發布、降級、監控等功能,比如京東的交易大Nginx節點、無線部門正在開發的無線網關、單品頁統一服務、實時價格、動態服務

            Web防火墻:可以進行IP/URL/UserAgent/Referer黑名單、限流等功能;

            緩存服務器:可以對響應內容進行緩存,減少到后端的請求,從而提升性能;

            其他:如靜態資源服務器、消息推送服務、縮略圖裁剪等。

             

            二、基于Nginx+Lua的常用架構模式

            1、負載均衡


            如上圖,我們首先通過LVS+HAProxy將流量轉發給核心Nginx 1和核心Nginx 2,即實現了流量的負載均衡,此處可以使用如輪訓、一致性哈希等調度算法來實現負載的轉發;然后核心Nginx會根據請求特征如“Host:item.jd.com”,轉發給相應的業務Nginx節點如單品頁Nginx 1。此處為什么分兩層呢?

            1、核心Nginx層是無狀態的,可以在這一層實現流量分組(內網和外網隔離、爬蟲和非爬蟲流量隔離)、內容緩存、請求頭過濾、故障切換(機房故障切換到其他機房)、限流、防火墻等一些通用型功能;

            2、業務Nginx如單品頁Nginx,可以在在業務Nginx實現業務邏輯、或者反向代理到如Tomcat,在這一層可以實現內容壓縮(放在這一層的目的是減少核心Nginx的CPU壓力,將壓力分散到各業務Nginx)、AB測試、降級;即這一層的Nginx跟業務有關聯,實現業務的一些通用邏輯。

            不管是核心Nginx還是業務Nginx,都應該是無狀態設計,可以水平擴容。



             

            業務Nginx一般會把請求直接轉發給后端的業務應用,如Tomcat、PHP,即將請求內部轉發到相應的業務應用;當有的Tomcat出現問題了,可以在這一層摘掉;或者有的業務路徑變了在這一層進行rewrite;或者有的后端Tomcat壓力太大也可以在這一層降級,減少對后端的沖擊;或者業務需要灰度發布時也可以在這一層Nginx上控制。

             

            2、單機閉環

            所謂單機閉環即所有想要的數據都能從本服務器直接獲取,在大多數時候無需通過網絡去其他服務器獲取。



             

            如上所示,主要有三種應用模式:

            2.1、第一張圖應用場景是Nginx應用誰也不依賴,比如我們的Cookie白名單應用,其目的是不在白名單中的Cookie將被清理,防止大家隨便將Cookie寫到jd.om根下;大家訪問http://www.jd.com時,會看到一個http://ccc.jd.com/cookie_check的請求用來清理Cookie的;對于這種應用非常簡單,不需要依賴數據源,直接單應用閉環即可。

             

            2.2、第二張圖,是讀取本機文件系統,如靜態資源合并:比如訪問http://item.jd.com/1856584.html,查看源碼會發現【<link type="text/css" rel="stylesheet" href="//misc.360buyimg.com/jdf/1.0.0/unit/??ui-base/1.0.0/ui-base.css,shortcut/2.0.0/shortcut.css,global-header/1.0.0/global-header.css,myjd/2.0.0/myjd.css,nav/2.0.0/nav.css,shoppingcart/2.0.0/shoppingcart.css,global-footer/1.0.0/global-footer.css,service/1.0.0/service.css"/>】這種請求,即多個請求合并為一個發給服務端,服務端進行了文件資源的合并;


             

            目前有成熟的Nginx模塊如nginx-http-concat進行靜態資源合并;因為我們使用了OpenResty,那么我們完全可以使用Lua編寫程序實現該功能,比如已經有人寫了nginx-lua-static-merger來實現這個功能。

             

            還一些業務型應用場景如下圖所示


             

            商品頁面是由商品框架和其他維度的頁面片段(面包屑、相關分類、商家信息、規格參數、商品詳情)組成;或者首頁是由首頁框架和一些頁面片段(分類、輪播圖、樓層1、樓層N)組成;分維度是因為不同的維度是獨立變化的。對于這種靜態內容但是需要進行框架內容嵌入的方式,Nginx自帶的SSI(Server Side Include)可以很輕松的完成;也可以使用Lua程序更靈活的完成(讀取框架、讀取頁面片段、合并輸出)。

             

            比如商品頁面的架構我們可以這樣:


             

            首先接收到商品變更消息,商品頁面同步Worker會根據消息維度生成相關的頁面推送到Nginx服務器;Nginx應用再通過SSI輸出。目前京東商品詳情頁沒有再采用這種架構,具體架構可以參考《構建需求響應式億級商品詳情頁》。

             

            對于首頁的架構是類似的,因為其特點(框架變化少,樓層變化較頻繁)和個性化的要求,樓層一般實現為異步加載。

             

            2.3、 第三張圖和第二張圖的不同處是不再直接讀取文件系統,而是讀取本機的Redis或者Redis集群或者如SSDB這種持久化存儲或者其他存儲系統都是可以的,比如直接說的商品頁面可以使用SSDB進行存儲實現。文件系統一個很大的問題是當多臺服務器時需要Worker去寫多臺服務器,而這個過程可以使用SSDB的主從實現。



             
            此處可以看到,不管是圖二還是圖三架構,都需要Worker去進行數據推送;假設本機數據丟了可怎么辦?因此實際大部分應用不會是完全單機閉環的,而是會采用如下架構:

             





               

            即首先讀本機,如果沒數據會回源到相應的Web應用從數據源拉取原始數據進行處理。這種架構的大部分場景本機都可以命中數據,只有很少一部分情況會回源到Web應用。

             

            如京東的實時價格/動態服務就是采用類似架構。

             

            3、分布式閉環

            單機閉環會遇到如下兩個主要問題: 1、數據不一致問題(比如沒有采用主從架構導致不同服務器數據不一致);2、遇到存儲瓶頸(磁盤或者內存遇到了天花板)。

            解決數據不一致的比較好的辦法是采用主從或者分布式集中存儲;而遇到存儲瓶頸就需要進行按照業務鍵進行分片,將數據分散到多臺服務器。

             

            如采用如下架構,按照尾號將內容分布到多臺服務器。


             

            即第一步先讀取分布式存儲(JIMDB是京東的一個分布式緩存/存儲系統,類似于Redis);如果不命中則回源到Tomcat集群(其會調用數據庫、服務總線獲取相關數據)來獲取相關數據。可以參考《構建需求響應式億級商品詳情頁》來獲取更詳細的架構實現。

             

            JIMDB集群會進行多機房主從同步,各自機房讀取自己機房的從JIMDB集群,如下圖


             

             

            4、接入網關

            接入網關也可以叫做接入層,即接收到流量的入口,在入口我們可以進行如下事情:


             

            4.1、核心接入Nginx會做如下事情:

            1、動態負載均衡;1、普通流量走一致性哈希,提升命中率;熱點流量走輪訓減少單服務器壓力;2、根據請求特征將流量分配到不同分組并限流(爬蟲、或者流量大的IP);3、動態流量(動態增加upstream或者減少upstream或者動態負載均衡)可以使用balancer_by_lua或者微博開源的upsync;

            2、防DDOS攻擊限流:可以將請求日志推送到實時計算集群,然后將需要限流的IP推送到核心Nginx進行限流;

            3、非法請求過濾:比如應該有Referer卻沒有,或者應該帶著Cookie卻沒有Cookie;

            4、請求聚合:比如請求的是http://c.3.cn/proxy?methods=a,b,c,核心接入Nginx會在服務端把Nginx并發的請求并把結果聚合然后一次性吐出;

            5、請求頭過濾:有些業務是不需要請求頭的,因此可以在往業務Nginx轉發時把這些數據過濾掉;

            6、緩存服務:使用Nginx Proxy Cache實現內容頁面的緩存;

             

            4.2、業務Nginx會做如下事情:

            1、緩存:對于讀服務會使用大量的緩存來提升性能,我們在設計時主要有如下緩存應用:首先讀取Nginx本地緩存  Shared Dict或者Nginx Proxy Cache,如果有直接返回內容給用戶;如果本地緩存不命中,則會讀取分布式緩存如Redis,如果有直接返回;如果還是不命中則回源到Tomcat應用讀取DB或調用服務獲取數據。另外我們會按照維度進行數據的緩存。

            2、業務邏輯:我們會進行一些數據校驗/過濾邏輯前置(如商品ID必須是數字)、業務邏輯前置(獲取原子數據,然后在Nginx上寫業務邏輯)。

            3、細粒度限流:按照接口特征和接口吞吐量來實現動態限流,比如后端服務快扛不住了,那我們就需要進行限流,被限流的請求作為降級請求處理;通過lua-resty-limit-traffic可以通過編程實現更靈活的降級邏輯,如根據用戶、根據URL等等各種規則,如降級了是讓用戶請求等待(比如sleep 100ms,這樣用戶請求就慢下來了,但是服務還是可用)還是返回降級內容。

            4、降級:降級主要有兩種:主動降級和被動降級;如請求量太大扛不住了,那我們需要主動降級;如后端掛了或者被限流了或者后端超時了,那我們需要被動降級。降級方案可以是:1、返回默認數據如庫存默認有貨;2、返回靜態頁如預先生成的靜態頁;3、部分用戶降級,告訴部分用戶等待下再操作;4、直接降級,服務沒數據,比如商品頁面的規格參數不展示;5、只降級回源服務,即可以讀取緩存的數據返回,實現部分可用,但是不會回源處理;

            5、AB測試/灰度發布:比如要上一個新的接口,可以通過在業務Nginx通過Lua寫復雜的業務規則實現不同的人看到不同的版本。

            6、服務質量監控:我們可以記錄請求響應時間、緩存響應時間、反向代理服務響應時間來詳細了解到底哪塊服務慢了;另外記錄非200狀態碼錯誤來了解服務的可用率。

             

            京東的交易大Nginx節點、無線部門正在開發的無線Nginx網關、和單品頁統一服務都是接入網關的實踐,而單品頁統一服務架構可以參考《京東商品詳情頁服務閉環實踐》。

             

            5、Web應用

            此處所說的Web應用指的是頁面模板渲染類型應用或者API服務類型應用;比如京東列表頁/商品詳情頁就是一個模板渲染類型的應用,核心業務邏輯都是使用Lua寫的,部署到Nginx容器。目前核心業務代碼行數有5000多行,模板頁面有2000多行,涉及到大量的計算邏輯,性能數據可以參考《構建需求響應式億級商品詳情頁》。



             

            整體處理過程和普通Web應用沒什么區別:首先接收請求并進行解析;然后讀取JIMDB集群數據、如果沒有則回源到Tomcat獲取;然后進行業務邏輯處理;渲染模板;將響應內容返回給用戶。

             

            三、如何使用Nginx+Lua開發Web應用

            開發一個Web應用我們需要從項目搭建、功能開發、項目部署幾個層面完成。

             

            3.1、項目搭建 

            Java代碼  收藏代碼
            1. /export/App/nginx-app  
            2.  -------bin(腳本)  
            3.  ------------start.sh  
            4.  ------------stop.sh  
            5.  -------config(配置文件)  
            6.  ------------nginx.conf  
            7.  ------------domain  
            8.  ----------------nginx_product.conf  
            9.  ------------resources.properties  
            10.  -------lua(業務代碼)  
            11.  ------------init.lua  
            12.  ------------product_controller.lua  
            13.  -------template(模板)  
            14.  --------------prodoct.html  
            15.  -------lualib(公共Lua庫)  
            16.  ------------jd  
            17.  ----------------product_util.lua  
            18.  ----------------product_data.lua  
            19.  ------------resty  
            20.  ----------------redis.lua  
            21.  ----------------template.lua  

              

             整個項目結構從啟停腳本、配置文件、公共組件、業務代碼、模板代碼幾塊進行劃分。

             

            1、啟停腳本

            啟停腳本放在項目目錄/export/App/nginx-app/bin/下。

            start.sh是啟動和更新腳本,即如果nginx沒有啟動則啟動起來,否則reload: 

            Java代碼  收藏代碼
            1. if nginx沒啟動 then  
            2.   sudo /export/servers/nginx/sbin/nginx  -t -c /export/App/nginx-app/config/nginx.conf  
            3.   sudo /export/servers/nginx/sbin/nginx  -c /export/App/nginx-app/config/nginx.conf  
            4. else  
            5.   sudo /export/servers/nginx/sbin/nginx  -t  
            6.   sudo /export/servers/nginx/sbin/nginx  -s reload  
            7. end    

            stop.sh是停止Nginx腳本: 

            Java代碼  收藏代碼
            1. sudo /export/servers/nginx/sbin/nginx  -s quit   

             

            2、配置文件

            配置文件放在/export/App/nginx-app/config目錄下,包括了nginx.conf配置文件、nginx項目配置文件和資源配置文件。

             

            nginx.confg配置文件  

            Java代碼  收藏代碼
            1. worker_processes  1;  
            2. events {  
            3.     worker_connections  1024;  
            4. }  
            5. http {  
            6.    include       mime.types;  
            7.    default_type  text/html;  
            8.    #gzip相關  
            9.    #超時時間  
            10.    #日志格式  
            11.    #反向代理配置  
            12.   
            13.    #lua依賴路徑  
            14.    lua_package_path  "/export/App/nginx-app/lualib/?.lua;;";  
            15.    lua_package_cpath  "/export/App/nginx-app/lualib/?.so;;";  
            16.   
            17.    #server配置  
            18.    include /export/App/nginx-app/config/domains/*;  
            19.   
            20.    #初始化腳本  
            21.    init_by_lua_file "/export/App/nginx-app/lua/init.lua";  
            22. }   

            對于nginx.conf會進行一些通用的配置,如工作進程數、超時時間、壓縮、日志格式、反向代理等相關配置;另外需要指定如下配置:

            lua_package_path、lua_package_cpath指定我們依賴的通用Lua庫從哪里加載;

            include /export/App/nginx-app/config/domains/*:用于加載server相關的配置,此處通過*可以在一個nginx下指定多個server配置;

            init_by_lua_file "/export/App/nginx-app/lua/init.lua":執行項目的一些初始化配置,比如加載配置文件。

             

            nginx項目配置文件

            /export/App/nginx-app/config/domains/nginx_product.conf用于配置當前web應用的一些server相關的配置: 

            Java代碼  收藏代碼
            1. #upstream  
            2. upstream item_http_upstream {  
            3.     server 192.168.1.1 max_fails=2 fail_timeout=30s weight=5;  
            4.     server 192.168.1.2 max_fails=2 fail_timeout=30s weight=5;  
            5. }  
            6. #緩存  
            7. lua_shared_dict item_local_shop_cache 600m;  
            8. server {  
            9.      listen                   80;  
            10.      server_name              item.jd.com item.jd.hk;  
            11.      #模板文件從哪加載  
            12.     set $template_root "/export/App/nginx-app/template ";  
            13.      #url映射  
            14.         location ~* "^/product/(\d+)\.html$" {  
            15.             rewrite /product/(.*)    http://item.jd.com/$1 permanent;  
            16.         }  
            17.     location ~* "^/(\d{6,12})\.html$" {  
            18.             default_type text/html;  
            19.             charset gbk;  
            20.             lua_code_cache on;  
            21.             content_by_lua_file "/export/App/nginx-app/lua/product_controller.lua";  
            22.         }  
            23. }   

            我們需要指定如upstream、共享字典配置、server配置、模板文件從哪加載、url映射,比如我們訪問http://item.jd.com/1856584.html將交給/export/App/nginx-app/lua/product_controller.lua處理;也就是說我們項目的入口就有了。

             

            資源配置文件resources.properties包含了我們的一些比如開關的配置、緩存服務器地址的配置等等。

             

            3、業務代碼

            /export/App/nginx-app/lua/目錄里存放了我們的lua業務代碼,init.lua用于讀取如resources.properties來進行一些項目初始化;product_controller.lua可以看成Java Web中的Servlet,接收、處理、響應用戶請求。

             

            4、模板

            模板文件放在/export/App/nginx-app/template/目錄下,使用相應的模板引擎進行編寫頁面模板,然后渲染輸出。

             

            5、公共Lua

            存放了一些如redis、template等相關的公共Lua庫,還有一些我們項目中通用的工具庫如product_util.lua。

             

            到此一個簡單的項目的結構就介紹完了,對于開發一個項目來說還會牽扯到分模塊等工作,不過對于我們這種Lua應用來說,建議不要過度抽象,盡量小巧即可。

             

            3.2、功能開發

            接下來就需要使用相應的API來實現我們的業務了,比如product_controller.lua:

            Java代碼  收藏代碼
            1. --加載Lua模塊庫  
            2. local template = require("resty.template")    
            3. --1、獲取請求參數中的商品ID  
            4. local skuId = ngx.req.get_uri_args()["skuId"];  
            5. --2、調用相應的服務獲取數據  
            6. local data = api.getData(skuId)  
            7.   
            8. --3、渲染模板  
            9. local func = template.compile("product.html")    
            10. local content = func(data)    
            11. --4、通過ngx API輸出內容    
            12. ngx.say(content)     

            開發完成后將項目部署到測試環境,執行start.sh啟動nginx然后進行測試。

            詳細的開發過程和API的使用,請參考《跟我學Nginx+Lua開發》。此處不做具體編碼實現。

             

            參考源碼:Nginx+Lua(OpenResty) HelloWorld

             

            四、基于Nginx+Lua的常用功能總結

            到此我們對于Nginx開發已經有了一個整體的認識,對于Nginx粘合Lua來開發應用可以說是一把鋒利的瑞士軍刀,可以幫我們很容易的解決很多問題,可以開發Web應用、接入網關、API網關、消息推送、日志采集等應用,不過個人認為適合開發業務邏輯單一、核心代碼行數較少的應用,不適合業務邏輯復雜、功能繁多的業務型或者企業級應用;最后我們總結下基于Nginx+Lua的常用架構模式中一些常見實踐和場景:

              動態負載均衡;

              防火墻(DDOS、IP/URL/UserAgent/Referer黑名單、防盜鏈等)

              限流;

              降級;

              AB測試/灰度發布;

              多級緩存模式;

              服務端請求聚合;

              服務質量監控。

             

            一些問題

            1、在開發nginx應用時使用UTF-8編碼可以減去很多麻煩;

            2、GBK轉碼解碼時使用GB18030,否則一些特殊字符會出現亂碼;

            3、cjson庫對于如\uab1這種錯誤的unicode轉碼會失敗,可以使用純Lua編寫的dkjson;

            4、社區版nginx不支持upstream的域名動態解析;可以考慮proxy_pass http://p.3.local/prices/mgets$is_args$args,然后配合resolver來實現;或者在lua中進行http調用;如果DNS遇到性能瓶頸可以考慮在本機部署如dnsmasq來緩存;或者考慮使用balancer_by_lua功能實現動態upstream;

            5、為響應添加處理服務器IP的響應頭,方便定位問題;

            6、根據業務設置合理的超時時間;

            7、走CDN的業務當發生錯誤時返回的500/503/302/301等非正常響應不要設置緩存。

             

            五、參考文資料

            深入 Nginx:我們是如何為性能和規模做設計的

              http://blog.jobbole.com/88766/

            Nginx變量漫談/配置指令的執行順序

              http://blog.sina.com.cn/openresty

            ngx_lua文檔

              https://github.com/openresty/lua-nginx-module#readme

            OpenResty最佳實踐

              https://moonbingbing.gitbooks.io/openresty-best-practices/content/lua/brief.html

            跟我學Nginx+Lua開發

              http://jinnianshilongnian.iteye.com/blog/2190344

            構建需求響應式億級商品詳情頁

              http://jinnianshilongnian.iteye.com/blog/2235572

            京東商品詳情頁服務閉環實踐

              http://jinnianshilongnian.iteye.com/blog/2258111 

            Upsync:微博開源基于Nginx容器動態流量管理方案

              http://toutiao.com/a6254279391729139970/  

            posted on 2016-08-26 18:01 思月行云 閱讀(1728) 評論(0)  編輯 收藏 引用 所屬分類: Nginx\Openresty
            久久人妻少妇嫩草AV无码蜜桃| 精品水蜜桃久久久久久久| 久久综合精品国产一区二区三区| 久久66热人妻偷产精品9| 久久久久av无码免费网| 亚洲人成无码www久久久 | 久久99精品久久久久久秒播| 91精品国产高清久久久久久io| 热re99久久精品国99热| 亚洲色婷婷综合久久| 色综合久久久久综合体桃花网| 久久精品国产亚洲AV香蕉| 久久99久国产麻精品66| 精品国产青草久久久久福利| 久久精品国产AV一区二区三区| 久久久久亚洲AV无码专区首JN| 日韩人妻无码一区二区三区久久99| 久久久精品久久久久久| 亚洲Av无码国产情品久久| 久久国产亚洲精品| 无码人妻久久一区二区三区免费丨| 久久婷婷五月综合国产尤物app| 国产精品一区二区久久国产| 国产精品久久久久久久久鸭| 岛国搬运www久久| 久久久WWW免费人成精品| 亚洲综合久久久| 五月丁香综合激情六月久久| 久久99国产精品久久99果冻传媒| 97精品伊人久久久大香线蕉| 亚洲а∨天堂久久精品| 亚洲AV无码久久精品狠狠爱浪潮| 99精品国产在热久久无毒不卡| 国产 亚洲 欧美 另类 久久| 午夜精品久久影院蜜桃| 久久久久久国产精品免费无码 | 久久精品天天中文字幕人妻| 亚洲国产精品久久久久婷婷老年| 亚洲国产成人精品女人久久久| 伊人久久久AV老熟妇色| 国产视频久久|