1. 程式人生 > >極限優化:php巧用tcp長連線

極限優化:php巧用tcp長連線

不錯轉行做專案經理  有力的PMP課程


一、面向人群

如果你的站點架構滿足以下幾點,那麼本文的優化方案會非常適合你:
1)使用php等指令碼語言作為開發語言
2)需要連線後端服務,例如RPC服務、memcache或redis等
3)流量非常大

二、解決的問題

常見的web架構如上:
1)最前端是APP或者web頁面
2)伺服器上層是web-server進行接入
3)php指令碼語言呼叫後端資料,完成業務邏輯,拼接頁面
4)最後端是服務、快取、資料庫
我們都知道,php是一種指令碼語言,不像C++/Java那樣程序能夠常駐,所以它連線後端的服務都是使用短連線

上圖是一種典型場景,站點php部署在機器A上,快取memcache部署在機器B上,之間通過短連線通訊,過程為:
1)php建立tcp短連線
2)按照memcache協議傳送資料
3)接收memcache返回的資料
4)php關閉tcp短連線
在站點流量小時,上述過程沒有任何問題,當站點流量非常大,

QPS很高的情況下,php對memcache的tcp建立+關閉tcp短連線的開銷便不能忽略了,有可能成為效能的瓶頸,如何進行優化是本文即將討論的核心。

三、UNIX Domain Socket技術介紹
話鋒一轉,先一起來看看UNIX Domain Socket技術。
UNIX Domain Socket是一種程序間IPC通訊機制,它不需要經過網路協議棧,不需要打包拆包、計算校驗和、維護序號和應答等,只是將應用層資料從一個程序拷貝到另一個程序。它可以用於同一臺主機上兩個沒有親緣關係的程序,並且是全雙工的,提供可靠訊息傳遞(訊息不丟失、不重複、不錯亂)的IPC機制

四、優化方案
可以看到,UNIX Domain Socket的效率會遠高於tcp短連線,但它只能用於同一臺主機間的程序通訊,而我們的php應用和後端服務往往是部署在不同的機器上的,此時我們能否利用它來進行優化呢,答案是肯定的。

優化後的簡易架構圖如上,我們在php應用伺服器上部署一個local-proxy,php與local-proxy之間使用UNIX Domain Socket來通訊,而local-proxy與後端服務進行TCP長連線通訊,這樣就大大提升了通訊效率,免除了每次請求都要進行的建立+關閉tcp短連線的開銷。

五、local-proxy要點
要實現上述優化方案,local-proxy是實現要點,在實現local-proxy時,有這麼幾點需要注意
1)協議設計:local-proxy本身沒有任何業務邏輯,只負責請求轉發,上游傳送過來memcache協議,透傳給後端的memchace,這樣的話,上游客戶端不需要進行任何程式碼的修改
2)通訊方式

:如上文所述,local-proxy與上游使用UNIX Domain Socket進行通訊,與下游使用tcp長連線進行通訊
3)高效框架:這種方案是為了解決tcp短連線的效率損耗,這樣對local-proxy的效率要求就非常高,可以選用成熟高效的網路框架(例如libevent)和tcp長連線連線池技術來實現
4)請求對映:需要將上游發過來的請求與發往下游的請求一一對映起來,這樣才能正確的對應上請求包與響應包

六、具體應用
優酷內部的Memcached Agent專案已經應用了這種方案。