Swoole擴(kuò)展的6種模式深入詳解
前言
并發(fā)問(wèn)題可以理解為兩個(gè)問(wèn)題
- 并發(fā)連接數(shù),就是支持同時(shí)接受多少客戶(hù)端TCP連接
- 并發(fā)請(qǐng)求數(shù),每秒能處理多少請(qǐng)求
Swoole底層基于epoll,所以第一個(gè)問(wèn)題在Swoole擴(kuò)展中實(shí)際上不存在任何問(wèn)題。使用Swoole可以輕松應(yīng)對(duì)10萬(wàn)甚至100萬(wàn)長(zhǎng)連接。開(kāi)發(fā)者唯一需要做的就是修改
ulimit -n
將系統(tǒng)最大文件描述符改為 10萬(wàn)或更大。
不同的模型每秒能處理多少請(qǐng)求數(shù),這個(gè)是應(yīng)用層需要考慮的問(wèn)題。而且不同的場(chǎng)景下有些模式無(wú)法使用。真正的難題就是在這里。實(shí)際上
工具永遠(yuǎn)是死的,而人是活的。
再?gòu)?fù)雜艱難的場(chǎng)景也阻擋不了聰明的工程師。合理利用Swoole提供的各項(xiàng)功能可以巧妙解決各種難題。
第一 Worker同步阻塞
這個(gè)模式的使用方法:
- swoole_server設(shè)置為SWOOLE_PROCESS
- 只使用Worker進(jìn)程
- 根據(jù)不同的情況設(shè)置worker_num的數(shù)值
- 設(shè)置dispatch_mode參數(shù)為1或3
- Worker進(jìn)程內(nèi)使用同步阻塞的代碼編寫(xiě)方式,這里不使用任何異步IO接口
這個(gè)模式的瓶頸就在與onRequest或onReceive里代碼邏輯的處理速度。按照快慢可以分為幾種
- 外網(wǎng)CURL調(diào)用。這個(gè)最慢,快的數(shù)百毫秒,慢的情況可能需要幾十秒
- 內(nèi)網(wǎng)RPC或Http接口,這個(gè)取決與這個(gè)接口的速度
- MySQL復(fù)雜查詢(xún),一條SQL如果沒(méi)有索引可能需要幾百毫秒,甚至幾秒或更長(zhǎng)時(shí)間。而如果是主鍵查詢(xún)或者索引足夠有效可能只需要幾毫秒
- Redis/Memcache,內(nèi)存數(shù)據(jù)庫(kù)局域網(wǎng)而且是長(zhǎng)連接,調(diào)用一次可能只需要幾百微秒也就是0.x毫秒就能返回
- 讀取磁盤(pán)文件,普通機(jī)械磁盤(pán)未命中PageCache引起磁盤(pán)尋道,可能需要幾十毫秒。SSD磁盤(pán)速度就快多了幾毫秒即可完成隨機(jī)讀取。
- 內(nèi)存文件系統(tǒng)或共享內(nèi)存,讀取/tmp或/dev/shm下的共享文件本質(zhì)上是讀取共享內(nèi)存,僅需幾微妙到幾十微秒即可完成。如果是直接讀共享內(nèi)存可能更快,納秒級(jí)別。
進(jìn)程數(shù)量
根據(jù)上面的IO耗時(shí),設(shè)置適當(dāng)?shù)倪M(jìn)程數(shù)量即可。
- IO很慢就設(shè)置幾百個(gè)Worker進(jìn)程,如操作MySQL、CURL、大量讀寫(xiě)磁盤(pán)
- IO很快就可設(shè)置少量進(jìn)程,如操作Redis、內(nèi)存文件系統(tǒng)、共享內(nèi)存
投遞模式
如果請(qǐng)求是無(wú)狀態(tài)的可以使用dispatch_mode=1或3,輪循投遞或者區(qū)分忙閑投遞。
長(zhǎng)連接應(yīng)用
比如聊天室,網(wǎng)絡(luò)游戲。連接之間需要交互的應(yīng)用。 可以使用 MySQL/Redis/文件 存儲(chǔ)用戶(hù)的連接fd,分組信息。要向某個(gè)用戶(hù)發(fā)數(shù)據(jù)可以根據(jù)UID查出對(duì)應(yīng)的fd,發(fā)送數(shù)據(jù)即可。發(fā)送分組,可以根據(jù)分阻ID查詢(xún)出fd列表,循環(huán)發(fā)送數(shù)據(jù)即可。
第二 Worker非阻塞+Task
這種模式是典型的同步+異步,復(fù)雜的業(yè)務(wù)邏輯使用同步阻塞在Task進(jìn)程中處理,簡(jiǎn)單要求高并發(fā)的邏輯使用異步非阻塞在Worker進(jìn)程中處理。
使用方法
- 使用SWOOLE_PROCESS模式
- dispatch_mode 設(shè)置為2(默認(rèn)就是2,可不做任何設(shè)置)
- worker_num 設(shè)置為CPU核數(shù)
- task_worker_num 根據(jù)業(yè)務(wù)邏輯的耗時(shí)情況進(jìn)行設(shè)置,如果平均耗時(shí)較長(zhǎng),需要設(shè)置數(shù)百個(gè)進(jìn)程,耗時(shí)較短可設(shè)置幾十個(gè)進(jìn)程
Worker進(jìn)程
在這個(gè)模式中,Worker進(jìn)程不能有任何同步阻塞的操作,只處理請(qǐng)求響應(yīng)或數(shù)據(jù)接收發(fā)送,僅進(jìn)行PHP數(shù)組或?qū)ο蟛僮骰蚱渌?jì)算邏輯。具體參考 模式3 Worker進(jìn)程全異步。
Task進(jìn)程
無(wú)狀態(tài)地處理任務(wù),并返回結(jié)果。需要注意單個(gè)Task的執(zhí)行時(shí)間,避免處理時(shí)間太長(zhǎng)導(dǎo)致Task排隊(duì)過(guò)多。
第三 Worker全異步
這個(gè)模式就是真正的異步非阻塞編程,在代碼中只能使用Swoole提供的異步非阻塞IO操作,不得執(zhí)行任何普通的PHP阻塞IO函數(shù),如curl、mysql、redis、fsockopen、stream、socket、proc_open等。
與模式二 不同的是全異步服務(wù)器不使用Task進(jìn)程,即使是很復(fù)雜的業(yè)務(wù)邏輯也在Worker進(jìn)程中執(zhí)行。純異步編程需要對(duì)開(kāi)發(fā)者要求較高。
使用方法
- dispatch_mode設(shè)置為2
- worker_num 設(shè)置為CPU核數(shù)
邏輯實(shí)現(xiàn)
Worker進(jìn)程內(nèi)的PHP代碼只能進(jìn)行下列3種操作:
- 使用swoole_redis、swoole_mysql、swoole_http_client、swoole_client+async操作
- 進(jìn)行PHP數(shù)組、對(duì)象操作或其他內(nèi)存計(jì)算邏輯
- 使用swoole_server的send、push、close、response->end等操作
適用場(chǎng)景
- 長(zhǎng)連接服務(wù)
- 對(duì)并發(fā)能力和吞吐量有較高要求
- 團(tuán)隊(duì)開(kāi)發(fā)者技術(shù)水平較高
弊端和解決方案
- 純異步需要使用嵌套回調(diào)的方式編寫(xiě)代碼,與傳統(tǒng)的編程模式完全不同,異步是事件驅(qū)動(dòng)式的,代碼不是順序執(zhí)行的。
- 異步嵌套回調(diào)的方式在程序邏輯復(fù)雜后會(huì)變得難以維護(hù)
可使用 Promise 或 Yield/Generator 簡(jiǎn)化異步編程。
第四 Base模式+同步阻塞
Base模式是一個(gè)簡(jiǎn)化版本,Base模式下Swoole的運(yùn)行原理與Node.js完全一致,是單線(xiàn)程的。對(duì)TCP客戶(hù)端的Accept、Send、Recv、Close都是同一個(gè)進(jìn)程內(nèi)操作的。
與Process同步阻塞模式不同的是BASE模式下Worker進(jìn)程的調(diào)度由操作系統(tǒng)實(shí)現(xiàn)。因此可以實(shí)現(xiàn)一個(gè)Leader-Follower模式的服務(wù)器程序。
使用方法
- 使用SWOOLE_BASE模式
- worker_num根據(jù)邏輯代碼的耗時(shí)情況設(shè)置幾百或幾十
- worker進(jìn)程內(nèi)使用同步阻塞IO操作
適用場(chǎng)景
- 適合短連接 & 請(qǐng)求響應(yīng)式 服務(wù),如Web服務(wù)、RPC服務(wù)
- 這種模式不能實(shí)現(xiàn)單連接并發(fā),客戶(hù)端的連接被某個(gè)Worker進(jìn)程Accept之后,只能在此進(jìn)程內(nèi)處理請(qǐng)求
第五 Process
Process提供了對(duì)進(jìn)程管理的封裝。基于Process可實(shí)現(xiàn):
多進(jìn)程+進(jìn)程間通信編程
將其他語(yǔ)言編寫(xiě)的程序包裝為子進(jìn)程,重定向標(biāo)準(zhǔn)輸入輸出到管道,與該程序進(jìn)行通信。可實(shí)現(xiàn)任意編程語(yǔ)言為我PHP所用。
第六 sendMessage
到此這篇關(guān)于Swoole擴(kuò)展的6種模式深入詳解的文章就介紹到這了,更多相關(guān)Swoole擴(kuò)展的5種模式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 詳解PHP Swoole與TCP三次握手
- php中Swoole的熱更新實(shí)現(xiàn)代碼實(shí)例
- swoole鎖的機(jī)制代碼實(shí)例講解
- windows系統(tǒng)php環(huán)境安裝swoole具體步驟
- linux系統(tǒng)虛擬主機(jī)開(kāi)啟支持Swoole Loader擴(kuò)展的方法
- Swoole源碼中如何查詢(xún)Websocket的連接問(wèn)題詳解
- 在Windows系統(tǒng)上安裝Cygwin搭建Swoole測(cè)試環(huán)境的圖文教程
- php使用goto實(shí)現(xiàn)自動(dòng)重啟swoole、reactphp、workerman服務(wù)的代碼
- Centos7安裝swoole擴(kuò)展操作示例
- 詳解Swoole TCP流數(shù)據(jù)邊界問(wèn)題解決方案
相關(guān)文章
ThinkPHP3.1.x修改成功與失敗跳轉(zhuǎn)頁(yè)面的方法
這篇文章主要介紹了ThinkPHP3.1.x修改成功與失敗跳轉(zhuǎn)頁(yè)面的方法,涉及thinkPHP底層源文件中相關(guān)跳轉(zhuǎn)代碼的設(shè)置與修改操作技巧,需要的朋友可以參考下2017-09-09
thinkphp3.2框架集成QRcode生成二維碼的方法分析
這篇文章主要介紹了thinkphp3.2框架集成QRcode生成二維碼的方法,結(jié)合實(shí)例形式分析了QRcode的下載、擴(kuò)展以及thinkphp3.2使用QRcode生成二維碼的相關(guān)操作技巧,需要的朋友可以參考下2020-03-03
laravel Model 執(zhí)行事務(wù)的實(shí)現(xiàn)
今天小編就為大家分享一篇laravel Model 執(zhí)行事務(wù)的實(shí)現(xiàn),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-10-10
Laravel使用swoole實(shí)現(xiàn)websocket主動(dòng)消息推送的方法介紹
這篇文章主要給大家介紹了關(guān)于Laravel使用swoole實(shí)現(xiàn)websocket主動(dòng)消息推送的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者使用Laravel具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-10-10
在TP5數(shù)據(jù)庫(kù)中四個(gè)字段實(shí)現(xiàn)無(wú)限分類(lèi)的示例
今天小編就為大家分享一篇在TP5數(shù)據(jù)庫(kù)中四個(gè)字段實(shí)現(xiàn)無(wú)限分類(lèi)的示例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-10-10
PHP實(shí)現(xiàn)簡(jiǎn)易blog的制作
本篇文章主要介紹了PHP實(shí)現(xiàn)簡(jiǎn)易blog的制作,可以顯示添加刪除blog,有需要的可以了解一下。2016-10-10
淺析ThinkPHP中execute和query方法的區(qū)別
初學(xué)ThinkPHP的時(shí)候,很多人都對(duì)execute()和query()方法的區(qū)別搞不懂,本文就此淺析二者的區(qū)別,需要的朋友可以參考下2014-06-06

