程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> 關於PHP編程 >> PHP沒有數據庫連接池怎麼破?PHP環境下使用Nginx ngx_http_limit_req_module模塊的高負載解決方案

PHP沒有數據庫連接池怎麼破?PHP環境下使用Nginx ngx_http_limit_req_module模塊的高負載解決方案

編輯:關於PHP編程

PHP沒有數據庫連接池怎麼破?PHP環境下使用Nginx ngx_http_limit_req_module模塊的高負載解決方案


線上運行了一套輔助系統是利用了開源的PHP改的,之前也沒怎麼玩過PHP,沒想到這玩意兒還是有不少坑的。突然某一天一個用戶做線上活動推廣,然後短時間內湧進來了上萬的請求,然後數據庫連接耗盡,短時間內幾乎拖垮了整個系統。導致系統奔潰的有多方面原因,今天主要針對PHP沒有數據庫連接池的原因來分析。

在PHP裡,數據庫連接在請求到達時建立,請求結束時釋放。如果同時幾千個請求到達,那就同時會建立幾千個數據庫連接,非常恐怖。而且PHP木有比較好的數據庫連接池驅動方案,所以我們得另想辦法。

解決這種問題有三種辦法:
1.使用Mysql Proxy中間件。Mysql Proxy提供了連接池管理的功能。但是我們沒有采用此方法,因為情況緊急,沒有人熟悉這玩意兒。
2.使用PHP-FPM。PHP-FPM是PHP的一個FastCGI進程管理器。通過配置可以控制同時處理PHP請求的進程數。
具體可以參考:http://www.linuxde.net/2013/06/14638.html
但是我們也沒用使用此方案,因為安裝配置過程比較麻煩。
3.使用Nginx的ngx_http_limit_req_module來控制請求。
此模塊可以通過自定義的鍵值來限制請求頻率。限制的方法就像漏斗,每秒固定處理請求數,然後推遲超出的請求,最後超出最大值的直接503返回拒絕。
我們使用了此方案,是因為只需簡單配置,而且可以靈活控制限制請求的場景。例如,對於靜態資源的請求我們不做限制,而對於PHP的請求做限制。還可以從URL地址裡提取出變量信息作為鍵,來達到更細的請求限制。
下面貼部分我們的配置給大家講解下。

http {
    ......
    limit_req_zone $limit_key zone=limit_one:50m rate=30r/s;
    #定義limit_key為Key的變量名,用於後面賦值,每個Key都有自己的計數器。limit_one為zone的名稱。rate表示每秒最多接受30個同時請求。
    server {
        ......
        if ( $request_uri ~* .*php.* ) {
              set $mp_limit_key $binary_remote_addr;
              #對於全部PHP首先有個默認的Key,使用客戶端的IP作為Key。相當於每個客戶端IP都會在zone的限制內。
         }
        if ( $query_string ~* .*id/(d+).php.* ) {
              set $mp_limit_key $1;
              #提取id後面的值作為Key。
        }
        if ( $query_string ~* .*appid/wx(.*).html.* ) {
              set $mp_limit_key $1;
              #提取appid作為Key。
        }
        limit_req zone=limit_one burst=200;
        #限制limit_one在此server內的漏斗容量為200。假設一個Key對應的請求數為200,那麼第一秒內在處理的為30個請求,其余的170個請求在等待排隊。假設一個Key對應的請求數為300,那麼超出200的部分將直接返回503。
        .......
    }
}

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved