1. <em id="vzzs9"></em>
      <tbody id="vzzs9"></tbody>

    2. <span id="vzzs9"></span>
      <progress id="vzzs9"></progress>
      首頁 運維干貨OpenResty搭建高性能服務端

      OpenResty搭建高性能服務端

      運維派隸屬馬哥教育旗下專業運維社區,是國內成立最早的IT運維技術社區,歡迎關注公眾號:yunweipai
      領取學習更多免費Linux云計算、Python、Docker、K8s教程關注公眾號:馬哥linux運維

      OpenResty搭建高性能服務端插圖

      Socket編程

      Linux Socket編程領域為了處理大量連接請求場景,需要使用非阻塞I/O和復用,select、poll、epoll是Linux API提供的I/O復用方式,自從Linux2.6中加入了epoll之后,高性能服務器領域得到廣泛的應用,Nignx就是使用epoll來實現I/O復用支持高并發。

      對于“高性能”服務端而言,我們所關注的并不是語言的性能,而是緩存和語言支持異步非阻塞。

      緩存

      針對緩存要明白通信速度的快慢順序

      • 內存>SSD>機械磁盤
      • 本機>網絡
      • 進程內 > 進程間

      緩存系統的目標是希望在進程內的命中率是最高的,那么此時緩存系統整體的效率也是最高的。

      異步非阻塞

      希望訪問數據庫、訪問網絡,訪問一些比較慢的IO設備時,不要在等待上耗費大量時間。而是使用事件驅動的方式,當系統完成某項任務后再來通知我們。這樣就可以將服務器CPU的空閑資源,用來服務客戶端連接。

      OpenResty

      OpenResty是基于Ngnix和Lua的高性能web平臺,內部集成精良的LUa庫、第三方模塊、依賴項。用于方便搭建能夠處理高并發、擴展性極高的動態web應用、web服務、動態網關??梢允褂肔ua腳本調用Ngnix支持的C以及Lua模塊,快速構建10K~1000K單機并發連接的高性能web應用系統。OpenResty的目標是讓web服務直接運行在Nginx服務內部,利用Ngnix的非阻塞IO模型,對HTTP客戶端請求和后端DB進行一致的高性能響應。

      OpenResty的出現可以說是顛覆了高性能服務端的開發模式。OpenResty實際上是Nginx+LuaJIT的完美組合。

      OpenResty工作方式

      由于Nginx采用的是master-worker模型,也就是一個master主進程管理多個worker進程,基本的事件處理都是放在worker中,master僅負責一些全劇初始化,以及對worker的管理。在OpenResty中,每個worker使用一個LuaVM,每個請求被分配到worker時,將在這個LuaVM中創建一個coroutine協程。協程之間數據隔離,每個協程具有獨立的全局變量_G。

      Lua中的協程和多線程下的線程類似,都有自己的堆棧、局部變量、指令指針…,但是和其他協程程序共享全局變量等信息。線程和協程主要不同在于:多處理器的情況下,概念上來說多線程是同時運行多個線程,而協程是通過代碼來完成協程的切換,任何時刻只有一個協程程序在運行。并且這個在運行的協程只有明確被要求掛起時才會被掛起。

      根據實際測試,OpenResty性能接近于Nginx 性能之王c module,甚至超過。

      OpenResty 架構

      • 負載均衡

      LVS+HAProxy將流量轉發給核心Nginx1和Nginx2,即實現了流量的負載均衡。

      負載均衡

      • 單機閉環

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

      單機閉環

      • 分布式閉環

      單機閉環會遇到2個主要問題

      1.數據不一致
      例如沒有主從架構導致不同服務器數據不一致

      2.遇到存儲瓶頸
      磁盤或內存遇到天花板

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

      分布式閉環

      • 接入網關

      接入網關又叫接入層,即接收流量的入口,在入口處做如下事情:

      接入網關

      OpenResty環境搭建

      安裝前準備,必須安裝perl、libpcre、libssl庫。

      # 從系統路徑中查看必備庫是否已經安裝
      $ sudo ldconfig -v
      
      # 安裝必備庫
      $ sudo apt install libpcre3-dev libssl-dev perl make build-essential curl libreadline-dev libncurses5-dev
      

      下載并解壓OpenResty后進入其目錄

      $ wget https://openresty.org/download/ngx_openresty-1.13.6.1.tar.gz
      $ tar -zxvf ngx_openresty-1.13.6.1.tar.gz
      $ mv openresty-1.13.6.1 openresty
      $ cd openresty
      $ ./configure
      

      默認會被安裝到/usr/local/openresty目錄下

      # 編譯并安裝
      $ sudo make && make install
      $ cd /usr/local/openresty
      

      啟動Nginx

      $ sudo /usr/local/openresty/nginx/sbin/nginx
      $ ps -ef | grep nginx
      $ service nginx status
      

      Nginx啟動若出現

      nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
      nginx: [emerg] still could not bind()
      

      說明80端口并占用,查看80端口被占用的端口并重啟。原因在于nginx先監聽了ipv4的80端口之后又監聽了ipv6的80端口,于是就重復占用了。

      $ sudo netstat -ntlp | grep 80
      $ sudo killall -9 nginx
      

      重新編輯Nginx配置文件

      $ sudo vim /etc/nginx/conf/nginx.conf
      
      listen 80;
      listen [::]:80 ipv6only=on default_server;
      

      使用curl工具或在瀏覽器訪問默認80端口

      $ curl 127.0.0.1
      

      瀏覽器輸入http://127.0.0.1/

      將Nginx工具配置到當前用戶的系統環境變量中

      $ sudo vim ~/.bashrc
      export PATH=$PATH:/usr/local/openresty/nginx/sbin
      $ source ~./bashrc
      $ cd ~
      $ nginx -s reload
      nginx: [alert] kill(12267, 1) failed (1: Operation not permitted)
      

      開發文檔

      ubuntu 安裝 vcode 或 sublime text 編輯器

      content_by_lua

      $ vim /usr/local/openresty/nginx/conf/nginx.conf
      location /test {
        default_type text/html;
        content_by_lua 'ngx.say("hello openresty")';
      }
      
      # 重啟Nginx
      $ /usr/local/openresty/nginx/sbin/nginx -s reload
      
      # 瀏覽器訪問 127.0.0.1/test
      

      content_by_lua_file

      $ vim nginx.conf
      location /test {
        content_by_lua_file 'html/test.lua';
      }
      $ vim ../html/test.lua
      ngx.say("hello lua")
      $ sudo /usr/local/nginx/sbin/nginx -s reload
      $ curl 127.0.0.1/test
      hello lua
      

      為避免每次修改都需要重啟Nginx,可在Nginx的server選項中配置lua_code_cache選項。

      $ vim nginx.conf
      server{
        lua_code_cache off;
        location /test{
          content_by_lua_file 'html/test.lua';
        }
      }
      $ sudo /usr/local/openresty/nginx/sbin/nginx -s reload
      nginx: [alert] lua_code_cache is off; this will hurt performance in /usr/local/openresty/nginx/conf/nginx.conf:48
      

      注意lua_code_cache off;是會引擎Nginx的性能的,在生產環境中是需要將其開啟的。

      小節

      在OpenResty中開發是分為兩步的,第一步是修改Nginx配置,第二步是使用Lua開發自己的腳本。

      OpenResty入門

      參考資料

      創建工作目錄

      OpenResty安裝之后就有配置文件及相關目錄,為了工作目錄和安裝目錄互不干擾,另外創建OpenResty工作目錄,并另寫配置。

      $ mkdir -p ~/openresty/test/logs ~/openresty/test/conf
      $ vim ~/openresty/test/conf/nginx.conf
      # 設置Nginx worker工作進程數量,即CPU核數。
      worker_processes 1;
      
      # 設置錯誤日志文件路徑
      error_log logs/error.log;
      # 配置Nginx服務器與用戶的網絡連接
      events{
          # 設置每個工作進程的最大連接數
          worker_connections 10224;
      }
      
      http{
          # 虛擬機主機塊定義
          server{
              # 監聽端口
              listen 8001;
              # 配置請求的路由
              location /{
                  default_type text/html;
                  content_by_lua_block{
                      ngx.say("hello world");
                  }
              }
          }
      }
      $ nginx -p ~/openresty/test
      $ curl 127.0.0.1:8001
      hello world
      
      $ vim nginx.conf
      location /test{
        content_by_lua_file "lua/test.lua";
      }
      $ cd .. && mkdir lua && cd lua
      $ vim test.lua
      local args = ngx.req.get_uri_args()
      local salt = args.salt
      if not salt then
        ngx.exit(ngx.HTTP_BAD_REQUEST)
      end
      local md5str = ngx.md5(ngx.time()..salt)
      ngx.say(md5str)
      
      $ sudo /usr/local/openresty/nginx/sbin/nginx -s reload
      $ curl -i 127.0.0.1/test?salt=lua
      HTTP/1.1 200 OK
      Server: openresty/1.13.6.2
      Date: Sun, 27 Jan 2019 10:07:17 GMT
      Content-Type: application/octet-stream
      Transfer-Encoding: chunked
      Connection: keep-alive
      
      b55b77f75e46b96b11778ca7edfe8d55
      

      若代碼中出現錯誤則需要直接查看Nginx的錯誤日志進行查看

      $ vim nginx/logs/error.log
      2019/01/27 17:37:15 [error] 15764#0: *6 failed to load external Lua file "/usr/local/openresty/nginx/test.lua": cannot open /usr/local/openresty/nginx/test.lua: No such file or...
      

      Windows系統下查看Nginx進程

      λ tasklist /fi "imagename eq nginx.exe"
      
      映像名稱                       PID 會話名              會話#       內存使用
      ========================= ======== ================ =========== ============
      nginx.exe                     9072 Console                    1      7,840 K
      nginx.exe                     7692 Console                    1     12,304 K
      nginx.exe                     8120 Console                    1      7,840 K
      nginx.exe                     4552 Console                    1     12,188 K
      nginx.exe                     9588 Console                    1      7,828 K
      nginx.exe                     6256 Console                    1     12,216 K
      nginx.exe                     7308 Console                    1      7,828 K
      nginx.exe                    10192 Console                    1     12,212 K
      
      λ taskkill /im nginx.exe /f
      成功: 已終止進程 "nginx.exe",其 PID 為 9072。
      

      ngx lua API

      參考資料

      本文鏈接:http://www.abandonstatusquo.com/39933.html

      網友評論comments

      發表評論

      您的電子郵箱地址不會被公開。

      暫無評論

      Copyright ? 2012-2022 YUNWEIPAI.COM - 運維派 京ICP備16064699號-6
      掃二維碼
      掃二維碼
      返回頂部
      久久久久亚洲国内精品|亚洲一区二区在线观看综合无码|欧洲一区无码精品色|97伊人久久超碰|一级a爱片国产亚洲精品