誰說php不能搞長鏈接?

聽說,php是世界上最好的語言?
畫外音:phper說,不服能夠點贊來辯。php

若是站點架構知足如下幾點:前端

  • 使用php這類腳本語言開發
  • 須要鏈接後端服務,例如RPC服務、memcache、redis等
  • 流量很是大

此時,經過短鏈接訪問RPC服務、mc、redis會出現什麼問題呢?
誰說php不能搞長鏈接?web

典型的web架構如上:
(1) 最前端是APP或者web頁面;
(2) 服務器上層是web-server進行接入;
(3) php調用後端,完成業務邏輯,拼接頁面;
(4) 最後端是服務、緩存、數據庫;redis

php做爲腳本語言,不像C++/Java那樣進程常駐,因此它鏈接後端的服務都是使用短鏈接。
畫外音:有朋友說,能夠用C寫擴展?
誰說php不能搞長鏈接?數據庫

上圖是一種典型場景,站點php部署在機器A上,緩存memcache部署在機器B上,之間經過短鏈接通訊,過程爲:
(1) php創建tcp短鏈接;
(2) 按照memcache協議發送數據;
(3) 接收memcache返回的數據;
(4) php關閉tcp短鏈接;後端

在流量小時,上述過程沒有任何問題,當網站流量很是大的狀況下,短鏈接可能會成爲性能瓶頸,有什麼優化辦法嗎?
畫外音:創建鏈接,銷燬鏈接很耗時。緩存

話鋒一轉,什麼是UNIX Domain Socket?
UNIX Domain Socket是一種IPC機制,它不須要通過網絡協議棧,不須要打包拆包、計算校驗和、維護序號和應答等,只是將應用層數據從一個進程拷貝到另外一個進程。
畫外音:IPC, Inter-Process Communication, 進程間通訊。服務器

它能夠用於同一臺主機上兩個沒有親緣關係的進程,而且是全雙工的,提供可靠消息傳遞(消息不丟失、不重複、不錯亂)的IPC機制。
畫外音:親緣關係是指,父子進程或者兄弟進程這種「特殊的」進程關係。網絡

能夠看到,UNIX Domain Socket的效率會遠高於tcp短鏈接,但它只能用於同一臺主機間的進程通信,而php應用和後端服務每每是部署在不一樣的機器上的,此時可否利用它來進行優化呢?
誰說php不能搞長鏈接?架構

優化後的簡易架構圖如上:
(1) 在php應用服務器上部署一個local-proxy;
(2) php與local-proxy之間使用UNIX Domain Socket來通信;
(3) local-proxy與後端服務進行TCP長鏈接通信;

這樣就大大提高了通信效率,免除了每次請求都要進行的創建與關閉tcp短鏈接的開銷。

實現local-proxy有什麼要注意的?

local-proxy很是注重通用性設計,由於php有RPC、mc、redis等多種後端:

  • 協議設計:local-proxy自己沒有任何業務邏輯,只負責請求轉發,上游發送過來redis協議,透傳給後端的redis
    畫外音:這樣,上游客戶端不須要進行任何代碼修改。
  • 通信方式:如上文所述,local-proxy與上游使用UNIX Domain Socket進行通信,與下游使用tcp長鏈接進行通訊
  • 高效框架:這種方案是爲了解決tcp短鏈接的效率損耗,這樣對local-proxy的效率要求就很是高,能夠選用成熟高效的網絡框架和tcp長鏈接鏈接池技術來實現
    畫外音:例如libevent。
  • 請求映射:須要將上游發過來的請求與發往下游的請求一一映射起來,這樣才能正確的對應上請求包與響應包
    誰說php不能搞長鏈接?
    思考過程比結論重要,但願對你有啓示。

架構師之路-分享可落地的技術文章

相關推薦:《Google FileSystem架構啓示》《Google MapReduce到底解決什麼問題?》《Google BigTable到底解決什麼問題?》

相關文章
相關標籤/搜索