<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                swoole的官網文檔其實非常詳細,基礎知識可以直接上官網查看文檔: https://wiki.swoole.com/wiki/page/1.html >[info] 本小冊只針對swoole的常用特性以及實際應用做記錄以及部分框架擴展源碼分析,因為我們一般都是基于框架開發,而絕大多數框架都有對應的擴展包(就算沒有,我們知道原理后也可以自己封裝一個),我們這里是**拿thinkphp-swoole來分析其源碼和使用場景**,弄清楚thinkphp-swoole的原理后,easyswoole等其他swoole框架都是大同小異。 ## 使用swoole要注意的 * 在`4.2.0`以前的版本不要在代碼中執行`sleep`以及其他睡眠函數,這樣會導致整個進程阻塞。**最新的`4.2.0`版本增加了對`sleep`函數的`Hook`**,底層替換了`sleep`、`usleep`、`time_nanosleep`、`time_sleep_until`四個函數。當調用這些睡眠函數時會自動切換為協程定時器調度。不會阻塞進程。注意要先開啟 `\Swoole\Runtime::enableCoroutine();` * `exit/die`是危險的,會導致worker進程退出 * 可通過`register_shutdown_function`來捕獲致命錯誤,在進程異常退出時做一些請求工作,具體參看[/wiki/page/305.html](https://wiki.swoole.com/wiki/page/305.html) * PHP代碼中如果有異常拋出,必須在回調函數中進行`try/catch`捕獲異常,否則會導致工作進程退出 * swoole不支持`set_exception_handler`,必須使用`try/catch`方式處理異常 * Worker進程不得共用同一個`Redis`或`MySQL`等網絡服務客戶端,Redis/MySQL創建連接的相關代碼可以放到`onWorkerStart`回調函數中。原因是如果共用1個連接,那么返回的結果無法保證被哪個進程處理。持有連接的進程理論上都可以對這個連接進行讀寫,這樣數據就發生錯亂了。具體參考[/wiki/page/325.html](https://wiki.swoole.com/wiki/page/325.html) * 不能使用類的屬性保存客戶端連接信息,因為一個worker進程可以處理多個客戶端連接,導致類屬性數據錯亂。常量則是可以的。 * 要注意 [進程隔離](https://wiki.swoole.com/wiki/page/1038.html) 問題,多進程要共用的變量數據建議通過用`Redis`來處理。 ## 知識點理解 1. 不管是http,還是WebSocket,都是繼承于server。所以Server中方法httpserver和websocketServer都可以用。 2. 要理解Swoole是基于**事件回調**的,當作為Server時,[回調函數](https://wiki.swoole.com/wiki/page/41.html)有很多 * 進程啟動時執行的:onStart、onManagerStart、onWorkerStart;onWorkerStop、onManagerStop、onShutdown;onWorkerError * 客戶端交互時觸發的:onReceive/onRequest/onPacket/onMessage、onOpen/onConnect、onClose * Task:onTask、onFinish * Timer:onTimer 3. 事件執行順序 * 所有事件回調均在`$server->start`后發生 * 服務器關閉程序終止時最后一次事件是`onShutdown` * 服務器啟動成功后,`onStart/onManagerStart/onWorkerStart`會在不同的進程內并發執行。 * `onReceive/onConnect/onClose/onTimer`在worker進程(包括task進程)中各自觸發 * worker/task進程啟動/結束時會分別調`用onWorkerStart/onWorkerStop` * `onTask`事件僅在task進程中發生 * `onFinish`事件僅在worker進程中發生 * `onStart/onManagerStart/onWorkerStart`3個事件的執行順序是不確定的 * UDP協議下只有`onReceive`事件,沒有`onConnect/onClose`事件 * 如果未設置`onPacket`回調函數,收到UDP數據包默認會回調`onReceive`函數 * `onOpen`事件回調是可選的:當WebSocket客戶端與服務器建立連接并完成握手后會回調此函數 4. 理解其進程和線程模型 * `Master`進程是一個多線程進程,其中有一組非常重要的線程,叫做`Reactor`線程(組),每當一個客戶端連接上服務器的時候,都會由Master進程從已有的Reactor線程中,根據一定規則挑選一個,專門負責向這個客戶端提供維持鏈接、處理網絡IO與收發數據等服務。分包拆包等功能也是在這里完成。 * `Manager`進程,某種意義上可以看做一個代理層,它本身并不直接處理業務,其主要工作是將Master進程中收到的數據轉交給Worker進程,或者將Worker進程中希望發給客戶端的數據轉交給Master進程進行發送。同時還負責監控Worker進程,如果Worker進程因為某些意外掛了,Manager進程會重新拉起新的Worker進程,有點像Supervisor的工作。而這個特性,也是最終實現熱重載的核心機制。 * `Worker`進程其實就是處理各種業務工作的進程,Manager將數據包轉交給Worker進程,然后Worker進程進行具體的處理,并根據實際情況將結果反饋給客戶端 ![](https://i.loli.net/2019/04/17/5cb6d34f4d29a.jpg) 5. `Manager`進程下的`TaskWorker進程` * 接受由`Worker`進程通過`swoole_server->task/taskwait`方法投遞的任務 * 處理任務,并將結果數據返回(使用`swoole_server->finish`)給`Worker`進程 * 完全是**同步阻塞**模式 * `TaskWorker`以多進程的方式運行 6. Reactor、Worker、TaskWorker的關系 * 可以理解為`Reactor`就是`nginx`,`Worker`就是`php-fpm`。`Reactor`線程異步并行地處理網絡請求,然后再轉發給`Worker`進程中去處理。`Reactor`和`Worker`間通過`UnixSocket`進行通信。 * 在`php-fpm`的應用中,經常會將一個任務異步投遞到`Redis`等隊列中,并在后臺啟動一些`php`進程異步地處理這些任務。`Swoole`提供的`TaskWorker`是一套更完整的方案,將任務的投遞、隊列、`php`任務處理進程管理合為一體。通過底層提供的`API`可以非常簡單地實現異步任務的處理。另外`TaskWorker`還可以在任務執行完成后,再返回一個結果反饋到`Worker`。 * `Swoole`的`Reactor`、`Worker`、`TaskWorker`之間可以緊密的結合起來,提供更高級的使用方式。一個更通俗的比喻,假設`Server`就是一個工廠,那`Reactor`就是銷售,接受客戶訂單。而`Worker`就是工人,當銷售接到訂單后,`Worker`去工作生產出客戶要的東西。而`TaskWorker`可以理解為行政人員,可以幫助`Worker`干些雜事,讓`Worker`專心工作。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看