Swoole之初體驗
如果你會workerman、nodejs、python、java、golang,你可以不用會swoole
--Rango老師?魯訊?
當年公司需要開發一個互動插件(大屏幕展現用戶搖一搖的數據)
老王:用WebSocket啊?
我:WebSocket?(不能讓他知道我不知道websocket),沒必要,沒必要,已經能滿足業務場景了。
現在的我,已不是當年那個年輕、美麗、可愛、青春的我了。
現在的我,絕壁用WebSocket啊!!!
老王:那你為什麼現在要用WebSocket?
我:因為剛學了Swoole,肯定要拿來……嘿嘿嘿
(當年老王是讓我用NodeJS作為服務端來實現這個功能。)
面向生產環境的PHP非同步網路通信引擎
--Swoole
老王:用swoole寫可以,那考考你,看看你有沒有入門swoole
我:來吧。出招吧!
老王:什麼是非同步?
我:Ajax的async屬性,設置為true時,下面邏輯不需要等待伺服器返回。同步的話,必須等待伺服器返回,下面邏輯才可以執行。
老王:PHP中是如何實現非同步的呢?
我:PHP中沒有非同步實現方式。
但是可拓展Swoole,Swoole中的task()就可以實現非同步,在task回調中處理耗時邏輯。
還有非同步文件讀寫、非同步redis、非同步mysql、非同步毫秒定時器……
老王:為什麼要使用非同步呢?
我:用戶註冊時發送手機驗證碼,Ajax向服務端發送請求。
服務端執行發送簡訊邏輯(一般使用第三方發送簡訊業務),等待第三方返回結果,再返回給客戶端。
如果第三方10s後才返回,用戶至少等待10s+。
簡訊發送邏輯放在Task里,服務端直接給用戶返回,表明已經接收到要發簡訊這個指令。
老王:Nginx+PHP-FPM和Swoole的區別在哪?
我:常駐內存、多進程模式、支持更多協議。
PHP-FPM每次運行後銷毀內存,當再有請求過來時,重新載入代碼到內存。
Swoole服務啟動時初始化PHP代碼,載入到內存中。直到重新啟動服務代碼才會再次載入內存。
不過代碼運行期間修改PHP代碼,一定要重啟Swoole服務。
PHP-FPM多進程模式:Master主進程/Worker多進程。每個worker對應一個連接。
Swoole多進程模式:Master主進程/Worker多進程。連接並不會獨佔worker進程。
PHP-FPM依賴web伺服器,不支持Websocket協議。
Swoole可自行實現Http伺服器、Websocket伺服器,並支持Websocket協議。
要死要死,不能比不能比……
老王:php是怎麼實現子進程的?
我:pcntl擴展可以創建子進程。(不深入講,因為沒有用過)
Swoole不依賴與pcntl,自身實現創建子進程。相比於pcntl擴展,實現了進程間通信、重定向標準輸入輸出等。
老王:聊聊HttpServer、WebSocketServer?
我:首先,HttpServer分為同步模式和非同步模式。
同步模式等同於 Nginx+PHP-FPM,Worker進程內可以使用同步阻塞IO,編程方式與普通PHPWeb程序完全一致。(普通PHPWeb程序,你一定懂得)。
與PHP-FPM不同的是,客戶端連接並不會獨佔進程,伺服器依然可以應對大量並發連接。
非同步模式下整個伺服器是非同步非阻塞的,伺服器可以應對大規模的並發連接和並發請求。
(官方文檔上說:HttpServer性能幾乎接近與Nginx的靜態文件處理,遠遠超過PHP-FPM)
WebSocketServer和HttpServer都繼承swoole_server。WebSocketServer可以同時作為HttpServer。但是並不是所有客戶端都支持WebSocket。
Nginx做為高性能的web伺服器,也可以做負載均衡。
生產環境架構中採用Nginx+SwooleServer模式。
老王:crontab 和 swoole_timer的區別,如何使用swoole_timer實現的監控?
我:crontab是Linux中的定時器,最小時間粒度是分鐘。往往不能滿足監控。
swoole實現的swoole_timer,最小時間粒度是毫秒。
對SwooleServer狀態監控,如果用swoole_timer監控,再1s內管理員就能收到異常通知。使用crontab的話,可能SwooleServer已經死透了。
老王:感覺你可以重構一下你插件了。
我:我不想寫了!!!!!!!!
老王是誰?
推薦閱讀:
※猿創|2018年技術棧展望
※nodejs和php實現圖片訪問實時處理
※編譯型語言和解釋型語言區別之我見
※memcache的初級使用