webman采用阻塞worker模式運行為什么性能還這么高?
既然這樣的話那么假如開啟了100個worker進程,那么在瞬時只能實時處理100個請求,每個請求假如500ms,那么第101個請求過來是會被阻塞500ms左右,最后第101次執(zhí)行完成需要耗時500ms + 500ms,這樣的一個機制難道不會在并發(fā)情況下出現(xiàn)很大的性能問題嗎?
php-fpm、swoole、go,它們都是可以非阻塞的接收請求,不會出現(xiàn)第101個請求打進來時受其他請求的影響,所以哪位能給說說這種情況難道真的可以接受嘛?
php-fpm 能非阻塞接受請求 ???????????????????????????????????????????
fpm開500個進程,每個進程是獨立的,不會受其他進程的影響,而worker的這種模式是復用worker,所以會造成worker進程本身的阻塞,這是兩碼事。
“webman 有協(xié)程加持,可以處理請求第三方請求阻塞問題了”,5.0我看過了,目前還沒有發(fā)布正式版本。但真實業(yè)務中不單單是請求第三方curl,每一個可能存在耗時(IO、cup密集計算等)的操作都會出現(xiàn)以上阻塞情況。
fpm是阻塞處理,雖然可以設置動態(tài)進程數(shù),但也并不是一個請求創(chuàng)建一個進程。現(xiàn)在基本沒有一個請求創(chuàng)建一個進程的服務器軟件了,因為那樣性能極低。
webman支持fiber協(xié)程調用第三方接口,第三方接口慢不會阻塞業(yè)務。
另外看了下源碼,webman也支持swoole/swow作為驅動,應該可以使用swoole或swow的協(xié)程。
fpm是同步處理沒有問題,但是我的意思是它的每一次請求都是在一個獨立的進程內完成的,所以不會因為當前的進程沒有處理完成而導致其他進程出現(xiàn)阻塞請求(前提未達到設定的最大進程數(shù)量時,因為這又是另外一個概念了),可能我描述的概念不夠清晰,總之一個復用進程,一個獨占進程。
那么就目前而言,webman這個機制處理一些io操作確實不如swoole這種非阻塞的模式合適。。
fpm也一樣,100個進程,瞬間第101個請求過來時也是在排隊阻塞等待處理,這和webman沒有多少區(qū)別。
webman本身io處理機制和swoole是一樣的,都是基于event-loop加非阻塞IO,差別也不大。但是webman身為php層面的框架無法改變PHP內置函數(shù)(如PDO)的IO接口阻塞問題,而swoole作為擴展可以hook這些阻塞接口變成非阻塞。區(qū)別實際在于這里。說得通俗一點,webman本身的IO是異步非阻塞的,但是業(yè)務代碼可能是阻塞的。
另外webman本身也支持swoole驅動,可以hook PHP內置的IO接口,達到非阻塞調用,但是帶來的負面影響就是和swoole一樣,需要管理上下文。
有棧/無棧協(xié)程本身不具備并發(fā)處理能力,僅僅只是將異步編碼同步化的能力,說白了就是整理代碼執(zhí)行順序的能力,讓你通過簡單的同步書寫的方法就可以輕松實現(xiàn)異步的執(zhí)行;
在主線程上運行的協(xié)程本質上和同步阻塞沒有太大區(qū)別:
所以現(xiàn)在的協(xié)程調度器至少都是另起一個/多個線程來執(zhí)行,保證不阻塞主線程,主線程主要負責接收,然后拆分丟給協(xié)程調度器,看起來就是一個迷你的基于線程的master-worker模型;
再說回MySQL或者Redis等服務,他們是C/S架構的服務,所以一個進程/線程上可以啟動多個client,多個client在宏觀上看起來就是多個線程,因為可以并行執(zhí)行(Redis客戶端也同樣,但執(zhí)行命令時是單線程),這個時候利用多個協(xié)程來向多個client發(fā)起請求的時候,本質上是利用了多線程,因為每個client的消息是不會相互阻塞的,本質上也是因為這些服務是支持并行處理的;而workerman這邊只是顆粒度粗一些,是一個進程對應一個/多個client,但是相互阻塞排隊的;
結論:看性能的話,主要看最后并行的情況,和縮減阻塞等待的時間,并行就是利用多核,目前來說利用多核就是進程/線程,不論是自身利用還是所使用的服務利用,都是利用。