Swoole 程式設計須知
這個頻道內會詳細介紹非同步程式設計與同步程式設計的不同之處以及需要注意的事項。
注意事項
- 不要在程式碼中執行 sleep以及其他睡眠函式,這樣會導致整個程式阻塞
- exit/die是危險的,會導致worker程式退出
- 可通過 register_shutdown_function來捕獲致命錯誤,在程式異常退出時做一些請求工作
- PHP程式碼中如果有異常丟擲,必須在回撥函式中進行 try/catch捕獲異常,否則會導致工作程式退出
- swoole不支援 set_exception_handler,必須使用 try/catch方式處理異常
- Worker程式不得共用同一個 Redis或 MySQL等網路服務客戶端,Redis/MySQL建立連線的相關程式碼可以放到 onWorkerStart回撥函式中。
類/函式重複定義
新手非常容易犯這個錯誤,由於swoole是常駐記憶體的,所以載入類/函式定義的檔案後不會釋放。因此引入類/函式的php檔案時必須要使用 include_once或 require_once,否會發生 cannot redeclare function/class 的致命錯誤。
記憶體管理
PHP守護程式與普通Web程式的變數生命週期、記憶體管理方式完全不同。請參考 swoole_server記憶體管理 頁面。 編寫 swoole_server或其他常駐程式時需要特別注意。
程式隔離
程式隔離也是很多新手經常遇到的問題。修改了全域性變數的值,為什麼不生效,原因就是全域性變數在不同的程式,記憶體空間是隔離的,所以無效。所以使用swoole開發Server程式需要了解 程式隔離問題。
- 不同的程式中PHP變數不是共享,即使是全域性變數,在A程式內修改了它的值,在B程式內是無效的
- 如果需要在不同的Worker程式內共享資料,可以用 Redis、 MySQL、 檔案、 Swoole\Table、 APCu、 shmget等工具實現
- 不同程式的檔案控制程式碼是隔離的,所以在A程式建立的Socket連線或開啟的檔案,在B程式內是無效,即使是將它的fd傳送到B程式也是不可用的
sleep/usleep的影響
在非同步IO的程式中, 不得使用sleep/usleep/time_sleep_until/time_nanosleep。(下文中使用sleep泛指所有睡眠函式)
- sleep函式會使程式陷入睡眠阻塞
- 直到指定的時間後作業系統才會重新喚醒當前的程式
- sleep過程中,只有訊號可以打斷
- 由於swoole的訊號處理是基於signalfd實現的,所以即使傳送訊號也無法中斷sleep
swoole提供的 swoole_event_add、 swoole_timer_tick、 swoole_timer_after、 swoole_process::signal、 非同步swoole_client 在程式sleep後會停止工作。 swoole_server也無法再處理新的請求。
例項程式
$serv = new swoole_server("127.0.0.1", 9501);$serv->on('receive', function ($serv, $fd, $from_id, $data) { sleep(100); $serv->send($fd, 'Swoole: '.$data); });$serv->start();
onReceive事件中執行了sleep函式,server在100秒內無法再收到任何客戶端請求。
exit/die函式的影響
在swoole程式中禁止使用exit/die,如果PHP程式碼中有 exit/die,當前工作的Worker程式、Task程式、User程式、以及swoole_process程式會立即退出。
建議使用try/catch的方式替換exit/die,實現中斷執行跳出PHP函式呼叫棧。
function swoole_exit($msg) { //php-fpm的環境 if (ENV=='php') { exit($msg); } //swoole的環境 else { throw new Swoole\ExitException($msg); } }
異常處理的方式比 exit/die更友好,因為異常是可控的, exit/die不可控。在最外層進行try/catch即可捕獲異常,僅終止當前的任務。Worker程式可以繼續處理新的請求,而 exit/die會導致程式直接退出,當前程式儲存的所有變數和資源都會被銷燬。如果程式內還有其他任務要處理,遇到 exit/die也將全部丟棄。
while迴圈的影響
非同步程式如果遇到死迴圈,事件將無法觸發。非同步IO程式使用 Reactor模型,執行過程中必須在 reactor->wait處輪詢。如果遇到死迴圈,那麼程式的控制權就在while中了, reactor無法得到控制權,無法檢測事件,所以IO事件回撥函式也將無法觸發。
密集運算的程式碼不是阻塞
例項程式
$serv = new swoole_server("127.0.0.1", 9501);$serv->on('receive', function ($serv, $fd, $from_id, $data) { while(1) { $i ++; } $serv->send($fd, 'Swoole: '.$data); });$serv->start();
onReceive事件中執行了死迴圈,server在無法再收到任何客戶端請求,必須等待迴圈結束才能繼續處理新的事件。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70018476/viewspace-2902541/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 大話 swoole 非同步程式設計非同步程式設計
- 新手程式設計師須知30個技巧!少走彎路程式設計師
- 零程式設計開發資料視覺化大屏須知程式設計視覺化
- 程式設計師須知,Python匯入模組的幾種姿勢!程式設計師Python
- Java程式設計師須知:分散式微服務為什麼很難?Java程式設計師分散式微服務
- Git 行尾設定須知Git
- JAVA程式設計師“黃金5年”必須要掌握的知識技能Java程式設計師
- 強烈推薦:程式設計師必須懂的資料庫知識程式設計師資料庫
- 一網打盡:Java 程式設計師必須瞭解的計算機底層知識!Java程式設計師計算機
- 程式設計師必須走向專業化程式設計師
- 作為一個程式設計師,CPU的這些硬核知識你必須會!程式設計師
- PLC程式設計—基本知識C程式程式設計
- 程式設計基礎知識程式設計
- 程式設計師必須瞭解的知識點——你搞懂mysql索引機制了嗎?程式設計師MySql索引
- shell程式設計必須要掌握的命令-xargs程式設計
- @程式設計師,安全問題必須重視!程式設計師
- 程式設計師必須要了解的web安全程式設計師Web
- java程式設計師進階架構師你必須掌握的架構知識體系Java程式設計師架構
- 利用swoole_process和eventloop實現php非同步程式設計OOPPHP非同步程式設計
- 成為更好的程式設計師必須學習的 4 種程式設計結構程式設計師
- 好程式設計師分享SpringBoot須掌握的註解程式設計師Spring Boot
- iOS 程式設計師必須收藏的資源大全iOS程式設計師
- 程式設計的知識點 (不斷積累,終身程式設計)程式設計
- java併發程式設計系列:java併發程式設計背景知識Java程式設計
- Swoole+Lumen:同步程式設計風格呼叫MySQL非同步查詢程式設計MySql非同步
- Java程式設計常用計算機小知識Java程式設計計算機
- PHP程式設計師必須知道的兩種日誌PHP程式設計師
- 程式設計師必須掌握的資料結構 2程式設計師資料結構
- 程式設計師必須掌握的資料結構 1程式設計師資料結構
- Java程式設計師必須掌握的5個註解!Java程式設計師
- 網路程式設計基礎知識程式設計
- 雲端計算工程師培訓須知工程師
- 軟體設計師:程式設計語言基礎知識程式設計
- 現代化程式設計 — 在 Swoole 上開發 Laravel 框架的應用程式設計Laravel框架
- 網路程式設計框架t-io的程式設計基本知識介紹程式設計框架
- 聊聊程式設計師面試時,那些必須注意的事情程式設計師面試
- 程式設計師必須掌握的核心演算法有哪些?程式設計師演算法
- 7個Web前端程式設計師必須會用CSS技巧Web前端程式設計師CSS