php 堵塞 消息队列,PHP的并发处理
PHP如何處理并發
什么是進程、線程、協程
進程 Process計算機中的程序關于某數據集合上的一次運行活動,“一個執行中的程序”
系統進行資源分配和調度的基本單位
三態模型:
多道程序系統中,進程在處理器上交替運行,狀態不斷地發生變化運行:正在處理機上運行;
就緒:當一個進程獲得了除處理機以外的一切所需資源,一旦得到處理機即可運行,則稱處于就緒狀態。可按多個優先級來劃分隊列。如,當一個進程由于時間片用完而進入就緒狀態時,排入低優先級;當進程由IO操作完成而進入就緒狀態時,排入高優先級隊列。
阻塞:也稱為等待或睡眠狀態,一個進程正在等待某一事件發生(例如請求IO而等待IO完成等)而暫時停止運行,這時即使把處理機分配給進程也無法運行。
五態模型:活躍阻塞,是指進程已在主存,一旦等待的事件發生便進入活躍就緒狀態;
靜止阻塞,進程對換到輔存時的阻塞狀態,一旦等待的事件發生便進入靜止就緒狀態。
活躍就緒,指進程在主存并且可被調度的狀態;
靜止就緒,是指進程被對換到輔存時的就緒狀態,是不能被直接調度的狀態,只有當主存中沒有活躍就緒態進程,或者是掛起就緒態進程具有更高的優先級,系統將把掛起就緒態進程調回主存并轉換為活躍就緒。
新建態:進程剛剛被創建時沒有被提交的狀態,等待系統完成創建進程的所有必要信息。
活躍就緒/靜止就緒:
運行:-
活躍阻塞/靜止阻塞:
終止態:進程已結束運行,回收除進程控制塊之外的其他資源,并讓其他進程從進程控制塊中收集有關信息。
線程 Thread有時被稱為輕量級進程(LightWeight Process, LWP),程序執行流的最小單元。
一個相對獨立的、可調度的執行單元,系統獨立調度和分配CPU的基本單位。
共享進程的地址空間和資源。
狀態:就緒、阻塞、運行就緒狀態:具備運行的所有條件,邏輯上可以運行,在等待處理機
運行狀態:占有處理機正在運行
阻塞狀態:在等待一個事件(如某個信號量),邏輯上不可執行
協程 Coroutine一種用戶態的輕量級線程,調度完全由用戶控制
擁有自己的寄存器上下文和棧
調度切換時,將寄存器上下文和棧保存到其他地方,切回來的時候恢復,基本沒有內核切換的開銷
可以不加鎖的訪問全局變量
異步
什么是多進程、多線程
多進程
同一個時間里,同一個計算機系統中如果允許兩個或兩個以上的進程處于運行狀態,就是多進程
多線程
單個程序中同時運行多個線程完成不同的工作,就是多線程
同步阻塞模型
多進程,最早的服務端程序都是通過多進程、多線程來解決并發IO的問題;
一個請求創建一個進程,然后子進程進入循環同步堵塞地與客戶端連接進行交互,收發處理數據。
多線程,用多線程模式實現非常簡單,線程中直接向某一個客戶端連接發送數據。
缺點嚴重依賴進程的數量解決并發問題
啟動大量進程會帶來額外的進程調度消耗
異步非阻塞模型select 系統的查詢,一個進程內建立1024個連接,poll 模型,循環檢測是否有連接。
現在各種高并發異步IO的服務器程序都是基于 epoll 實現的。
IO復用異步非阻塞程序使用經典的 Reactor 模型,顧名思義就是反應堆的意思,本身不處理任何數據收發。只是可以監視一個socket句柄的事件變化。
Reactor模型Add: 添加一個socket到Reactor
Set: 修改socket對應的事件,如可讀可寫
Del: 從Reactor中移除,不再監聽事件
Callback: 事件發生后回調指定的函數
Nginx:多線程Reactor
Swoole:多線程Reactor + 多進程Worker
PHP并發編程實踐
Swoole擴展異步、并行、高性能網絡通信引擎,使用C語言編寫,提供了PHP語言的異步多線程服務器,異步TCP/UDP網絡客戶端,異步MySQL,異步Redis,數據庫連接池,AsyncTask,消息隊列,毫秒定時器,異步文件讀寫,異步DNS查詢
為PHP多進程的模式設計了多個并發數據結構和IPC通信機制,可以大大簡化多進程并發編程的工作
Swoole2.0支持了類似Go語言的協程,可以使用完全同步的代碼實現異步程序
消息隊列經典場景,注冊成功后發送郵件,發送短信
串行方式:注冊成功后,先發送郵件,在發送短信
并行方式:注冊成功后,同時發送郵件和短信
消息隊列方式(離線方式):注冊成功后,將成功消息寫入隊列,此時直接返回成功給用戶,寫入隊列的時間非常短,可以忽略不計,然后異步發送郵件和短信 -
應用解耦場景說明:用戶下單后,訂單系統需要通知庫存系統。
假如庫存系統無法訪問,則訂單減庫存將失敗,從而導致訂單失敗。
訂單系統與庫存系統耦合
引用隊列,用戶下單后,訂單系統完成持久化處理,將消息寫入消息隊列,返回用戶訂單下單成功。
訂閱下單的消息,采用拉/推的方式,獲取下單信息,庫存系統根據下單信息,進行庫存操作。
流量削峰秒殺活動,流量瞬時激增,服務器壓力過大。
用戶發起請求,服務器接收后,先寫入消息隊列。假如消息隊列長度超過最大值,則直接報錯或提示用戶。
后續程序讀取消息隊列再做處理。
控制請求量,緩解高流量。
日志處理場景:解決大量日志的傳輸
日志采集程序將程序寫入消息隊列,然后通過日志處理程序的訂閱消費日志。
消息通訊場景:聊天室
多個客戶端訂閱同一主題,進行消息發布和接收
常見消息隊列產品Kafka
ActiveMQ
ZeroMQ
RabbitMQ
Redis
接口的并發請求
curl_multi_init
總結
以上是生活随笔為你收集整理的php 堵塞 消息队列,PHP的并发处理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 在数学中10!代表10的阶乘。既代表1*
- 下一篇: php 获取agent,PHP代码 解析