1. 程式人生 > >OpenResty(Nginx+Lua)高併發最佳實踐

OpenResty(Nginx+Lua)高併發最佳實踐

文章目錄

OpenResty簡介

以下內容來源與OpenResty官網,更多資訊可進入官網瞭解
OpenResty® 是一個基於 Nginx 與 Lua 的高效能 Web 平臺,其內部集成了大量精良的 Lua 庫、第三方模組以及大多數的依賴項。用於方便地搭建能夠處理超高併發、擴充套件性極高的動態 Web 應用、Web 服務和動態閘道器。

OpenResty® 通過匯聚各種設計精良的 Nginx 模組(主要由 OpenResty 團隊自主開發),從而將 Nginx 有效地變成一個強大的通用 Web 應用平臺。這樣,Web 開發人員和系統工程師可以使用 Lua 指令碼語言調動 Nginx 支援的各種 C 以及 Lua 模組,快速構造出足以勝任 10K 乃至 1000K 以上單機併發連線的高效能 Web 應用系統。

OpenResty® 的目標是讓你的Web服務直接跑在 Nginx 服務內部,充分利用 Nginx 的非阻塞 I/O 模型,不僅僅對 HTTP 客戶端請求,甚至於對遠端後端諸如 MySQL、PostgreSQL、Memcached 以及 Redis 等都進行一致的高效能響應

Nginx優點

可參考以下文章
https://blog.csdn.net/nangeali/article/details/60143560

Lua基礎學習

可參考菜鳥教程

環境搭建

window下環境搭建
  • 資源下載
    本人電腦64位作業系統,這裡下載windows 32位的版本,後續有他用
    點選下載32位版
    64位版下載

  • 解壓壓縮包

  • 建立lua目錄原始檔目錄,用於寫測試指令碼
    進入lualib目錄,建立testcode目錄

  • 編寫測試lua指令碼
    在testcode目錄下建立testlua.lua,並編寫以下指令碼資訊

    --用於接收前端資料的物件
    local args=nil
    --獲取前端的請求方式 並獲取傳遞的引數   
    local request_method = ngx.var.request_method
    --判斷是get請求還是post請求並分別拿出相應的資料
    if"GET" == request_method then
            args = ngx.req.get_uri_args()
    elseif "POST" == request_method then
            ngx.req.read_body()
            args = ngx.req.get_post_args()
            --相容請求使用post請求,但是傳參以get方式傳造成的無法獲取到資料的bug
            if (args == nil or args.data == null) then
                    args = ngx.req.get_uri_args()
            end
    end
    
    --獲取前端傳遞的name值
    local name = args.name
    --響應前端
    ngx.say("hello:"..name)
    

  • 編輯nginx配置
    按以下目錄編輯對應配置檔案

    在80的server中新增以下配置:

    		location /luatest
    		{
    			default_type text/html;
    			#這裡的lua檔案的路徑為絕對路徑,請根據自己安裝的實際路徑填寫
    			#記得斜槓是/這個。從window中拷貝出來的是\這樣,這樣是有問題的,務必注意
    			content_by_lua_file F:/DATA/software/other/openresty-1.13.6.2-win32/lualib/testcode/testlua.lua;
    		}
    

  • 啟動服務openresty的Nginx服務

    • 進入cmd,並進入到openresty對應的目錄
    • 使用nginx -t 檢測nginx的配置是否正確
    • 啟動nginx服務

  • 測試nginx是否正常
    開啟瀏覽器,輸入:http://127.0.0.1/ ,得到以下介面說明Nginx配置正常且已經正常執行

  • 測試OpenResty
    開啟瀏覽器,輸入:http://127.0.0.1/luatest?name=openresty

  • 到這裡,window下的OpenResty環境即搭建完成

Linux(CentOS 7)下環境搭建

更多linux版本下的原始碼安裝,請參考官網
你可以在你的 CentOS 系統中新增 openresty 倉庫,這樣就可以便於未來安裝或更新我們的軟體包(通過 yum update 命令)。

  • 執行下面的命令就可以新增openresty 的倉庫:

    sudo yum install yum-utils
    sudo yum-config-manager --add-repo https://openresty.org/package/centos/openresty.repo
    
  • 然後就可以像下面這樣安裝軟體包,比如 openresty:

    sudo yum install openresty
    
  • 如果你想安裝命令列工具 resty,那麼可以像下面這樣安裝 openresty-resty 包:

    sudo yum install openresty-resty
    
  • 命令列工具 opm 在 openresty-opm 包裡,而 restydoc 工具在 openresty-doc 包裡頭。
    列出所有 openresty 倉庫裡頭的軟體包:

    sudo yum --disablerepo="*" --enablerepo="openresty" list available
    
  • 新增lua的指令碼目錄
    cd /usr/local/openresty/lualib/
    mkdir testcode
    cd testcode

  • 建立測試lua指令碼
    cd /usr/local/openresty/lualib/testcode
    vim testlua.lua
    新增以下指令碼內容

    --用於接收前端資料的物件
    local args=nil
    --獲取前端的請求方式 並獲取傳遞的引數   
    local request_method = ngx.var.request_method
    --判斷是get請求還是post請求並分別拿出相應的資料
    if"GET" == request_method then
            args = ngx.req.get_uri_args()
    elseif "POST" == request_method then
            ngx.req.read_body()
            args = ngx.req.get_post_args()
            --相容請求使用post請求,但是傳參以get方式傳造成的無法獲取到資料的bug
            if (args == nil or args.data == null) then
                    args = ngx.req.get_uri_args()
            end
    end
    
    --獲取前端傳遞的name值
    local name = args.name
    --響應前端
    ngx.say("linux hello:"..name)
    

    儲存:wq!

  • 配置ngnix關聯lua檔案
    cd /usr/local/openresty/nginx/conf/
    vi nginx.conf
    在80的server中新增以下配置資訊

            location /luatest
            {       
                    default_type text/html;
                    #這裡的lua檔案的路徑為絕對路徑,請根據自己安裝的實際路徑填寫
                    #記得斜槓是/這個。
                    content_by_lua_file /usr/local/openresty/lualib/testcode/testlua.lua;
            } 
    

  • 啟動nginx服務
    cd /usr/local/openresty/nginx
    sbin/nginx

  • 測試nginx是否正常
    開啟瀏覽器,輸入linux的ip地址,如:http://192.168.1.130/ 顯示如下效果,說明nginx已經正常啟動

  • 測試OpenResty是否正常
    開啟瀏覽器,輸入:http://192.168.1.130/luatest?name=openresty 顯示如下效果,說明OpenResty正常

linux下ab效能測試

  • linux伺服器環境說明
    測試使用的是window下安裝的VM虛擬機器,linux的硬體分配為1核 700兆記憶體

  • linux下ab工具安裝
    yum -y install httpd-tools

  • 檢視ab版本
    ab -v

  • 壓力測試

    • 1W併發
      ab -c 10000 -n 100000 127.0.0.1/luatest
      注:10000個併發,一共請求10萬次
      測試結果:

    • 1.5W併發
      ab -c 15000 -n 100000 127.0.0.1/luatest

    • 2W併發
      ab -c 20000 -n 100000 127.0.0.1/luatest

總結

優點
  • 高併發
    根據以上的測試來看,一臺1核700兆的linux虛擬機器即可跑出2W的併發,足以說明OpenResty處理高併發的能力,由於ab工具的限制,只能測試上限2W的併發,因此,這裡也只做到了2W的測試。

  • 熱更新
    Lua屬於指令碼語言,編譯之後即可執行;Nginx具備優雅重啟的功能;因此,線上業務如果出現問題需要及時修復的,更新修改Lua指令碼之後,重啟Nginx即可完成更新發布;如果沒有配置Lua快取功能的話,只要更新Lua指令碼即可更新修復線上問題,不重啟Nginx也可以。

缺點
  • 不適合處理複雜的業務邏輯
    由於功能性的東西主要使用Lua進行開發,受Lua語言特性的影響,不太適合做業務比較複雜的功能。

  • 網際網路上資料比較少
    網際網路上可以找的資料比較少;不過,本身Lua的學習過程不是特別的複雜,所以,這基本不會成為你學習它的障礙

可適用的場景

  • 高訪問下的應用及官網的主頁
    如商城,諮詢類的應用首頁,會存在大量的請求,由於涉及到的內容比較多;所以可是私用預載入的形式,將主頁的資料放置在redis中;使用OpenResty+redis實現首頁,官網主頁的高併發載入

  • 商城類的秒殺功能
    秒殺功能會存在短時間的請求洪峰,如果處理不當可能會造成down機的風險,可以結合OpenResty+redis實現秒殺的功能

  • ip限流
    網際網路系統可能存在非法使用者惡意暴力請求,導致正常的使用者無法使用,可以通過OpenResty+redis實現ip的白名單機制,去攔截非法的使用者ip

  • APP灰度升級釋出
    可以根據系統的資料及條件實現APP的灰度升級測試