生產環境下的負載均衡配置

一、簡介

最近新上了一個營銷項目(和微信結合),後臺用的是Tomcat。開始上線的時候因爲人數不多感覺沒太多問題,隨着正式環境的發佈,開人有人反映服務器頁面無法打開,連入tomcat查看時發現連接數已滿且CPU也用到了極限,初始的架構如下圖所示,其使用1臺tomcat和一臺數據庫服務器。

wKiom1S9zSvD2uzEAAB3eHHsWEc575.jpg

wKiom1S9zXzjip8xAAPnpT7ToT4562.jpg

該業務系統主要用於微信營銷,顧客在微信上下單購買(搶)對應的商品,搶購成功後該商品(券)會自動生成條形碼保存在該用戶的註冊信息中。用戶憑券到實體店完成支付和取貨操作。因爲涉及券覈銷的問題(支付完成後即時覈銷),因此該業務無法放在雲端(覈銷的數據和實體店銷售數據需即時交互),最終只能通過本地的方案來解決。

首先考慮到的是將網上的連接通過負載均衡的方式分散來減輕服務器的壓力,這方面可以使用nginx代理來實現;其次需要解決的問題是session,對比了幾種方案發現nginx內置的ip_hash策略可以解決該問題,最終網絡的架構變成了下圖所示,在該方案中增加了4臺服務器,其中一臺nginx負載轉發,另外四臺爲新增的tomcat服務。

  wKioL1S9zmfDf8wUAAD6Q7j0vNk557.jpg

二、安裝Nginx

  Nginx的安裝配置十分簡單,我這裏實際用的是tengine版本,具體的安裝方法可以參考” nginx配置指南之一”。這裏需要注意的是它的編譯參數,記得它的配置文件和日誌文件的存放位置。

wKioL1S9zurRnmscAADQz6NjgzY877.jpg

三、優化系統資源

文件限制

  Linux系統中文件的打開個數及單用戶最多擁有的進程數是有限制的,可以通過“ulimit -n”或“ulimit -u”來查看,詳細的設置可以參考“ORACLE 11G在Linux下的標準安裝方法(上)”。先修改/etc/security/limit.conf中的限制,如下圖所示。

wKioL1S9z-3wngCYAACwV866fhU301.jpg

內核優化

  內核中涉及的TCP相關的選項在大併發連接的情況下也需要做相應的調整否則可以出“TCP: time wait bucket table overflow” 的錯誤提示。具體修改/etc/sysctl.conf文件,如有特殊要求請結合實際情況修改。具體如下所示:

wKiom1S9z1WCg2aWAAEi_bz2I6E101.jpg

tcp_max_tw_buckets    系統在同時所處理的最大 timewait sockets 數目。如果超過此數的話﹐time-waitsocket 會被立即刪除並且顯示警告信息。

ip_local_port_range    用於向外連接的端口範圍。

netdev_max_backlog    每個網絡接口接收數據包的速率比內核處理這些包的速率快時,允許送到隊列的數據包的最大數目,對重負載服務器而言,該值需要調高一點。

tcp_max_orphans    處理不屬於任何進程的套接字數量,不屬於任程進程的進程就是“孤兒(orphans)進程”,在快速、大量的連接中這種進程會很多因此要適當的設置該參數,也可以用來防禦簡單的DoS***。

tcp_max_syn_backlog    用於記錄尚未收到客戶端確認信息的連接請求的最大值。

四、優化Nginx

  epoll爲linux下的必須模型,適用於2.6以後的內核版本,如下圖所示:

wKiom1S9z8vQfdNFAABZ6i7eduk205.jpg

優化代理配置

  需要注意的是“proxy_max_temp_file_size”,它主要用來設置臨時文件的最大值。當被請求的文件內容大於代理緩存的大小時,該文件會被存儲到這個臨時文件,但是如果被請求文件的內容大於這個值的時候,那麼將會從上游的服務器(被代理的服務器)上直接同步傳遞,而不再使用代理緩存。該指令的默認值爲1GB,如果設置爲0,那麼意味着禁止使用臨時文件。

wKiom1S9z-XC4ompAACAuQvtLZY466.jpg

五、配置Nginx

  Nginx配置如下所示,其中upstreambackend配置的是後端的tomcat應用,ip_hash表示啓用該策略,用戶的目的是爲了解決後端session不一致的問題(在nginx前端還有CDN或是局域網的環境中須慎用)。

wKioL1S90OiBkNaSAALQDiCdOQg016.jpg

wKiom1S90BWgrAR4AAEUirCW6Y8883.jpg

  server段配置的是轉發的路徑和端口,需要注意“proxy_set_header Host $host:8162;”的寫法。如果該變量後沒有加8162端口則實際的轉發會導致頁面無法正常顯示。其後的兩條語句可以參考nginx日誌的記錄內容,主要用來記錄外網實際的訪問請求。($HOST 在使用80端口的時候ok,非80端口可以使用$http_host。感謝ontheway2015指點)

wKiom1S90ECCJzaOAAFHeu47xdQ141.jpg

  log_format字段用來生成指定的日誌格式文件,相應的變量對應日誌文件中的訪問記錄,可以對照下圖來查看。

wKioL1S90SDSc0ljAAQlowGMR30647.jpg

六、Nginx安全限制

  隨着業務的增加,網絡連接的流量越來越大,合理的控制訪問請求及連接數非常重要,否則仍會出現失去響應的情況。

七、增加IP限制功能

  最簡單也最容易實現的的方式是Nginx自帶的IP訪問控制,由模塊ngx_http_limit_conn_module和來ngx_http_limit_req_module實現,通過它們可以實現對IP地址連接數及服務器訪問請求數的控制。

要限制連接,必須先有一個容器對連接進行計數,在http段加入如下代碼:"zone=" 給它一個名字,可以隨便叫,這個名字要跟下面的limit_conn 一致,$binary_remote_addr = 用二進制來儲存客戶端的地址,1m 可以儲存 32000 個併發會話。

  限制請求數的方式和限制連接數類似,其中“rate=10r/s”表示一秒中處理的請求爲10個,如果需要限制爲每分鐘不超過30個則表示爲“rate=30r/m”;一個具體的設定如下所示:

http {
limit_req_zone$binary_remote_addr zone=one:10m rate=10r/s;
limit_conn_zone$binary_remote_addr zone=two:10m;
     }

  在server段中加入以下內容,其中“burst=5”表示同時允許超過頻率限制的請求數不多於5個;“limit_conn two 15”表示對於同一IP的連接數限制爲15個。

limit_req zone=one burst=5;
limit_conn two 15;


  後續WAF模塊的添加以及nginx相關的監控待整理。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章