<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>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                # swoole_server高級特性 --- [TOC=2,3] --- ## **1.改變Worker進程的用戶/組** 在某些情況下,主進程需要使用Root來啟動,比如需要監聽80端口。這時Worker進程的業務代碼也會運行在root用戶下,這是非常不安全的。 業務代碼的漏洞可能會導致整個服務器被攻破,所以需要將Worker進程所屬用戶和組改為其他用戶。 在PHP中使用posix系列函數即可完成此操作。可在swoole的[onWorkerStart](https://github.com/LinkedDestiny/swoole-doc/blob/master/doc/02.swoole_server%E4%BA%8B%E4%BB%B6%E5%9B%9E%E8%B0%83%E5%87%BD%E6%95%B0.md#3onworkerstart)回調中加入以下代碼: ```php $user = posix_getpwnam('www-data'); posix_setuid($user['uid']); posix_setgid($user['gid']); ``` 另外,在PHP代碼中訪問/etc/目錄,就是指文件系統的/etc/,這樣是不安全的。比如PHP代碼中誤操作執行**rm -rf /**。會帶來嚴重的后果。 可以使用chroot函數,將根目錄重定向到另外一個安全的目錄。 ```php chroot('/tmp/root/'); ``` ## **2.回調函數中的from_id和fd** - from_id是來自于哪個reactor線程 - fd是tcp連接的文件描述符 調用swoole_server_send/swoole_server_close函數需要傳入這兩個參數才能被正確的處理。如果業務中需要發送廣播,可以先通過[connection_list](https://github.com/LinkedDestiny/swoole-doc/blob/master/doc/03.swoole_server%E5%87%BD%E6%95%B0%E5%88%97%E8%A1%A8.md#swoole_serverconnection_list)獲取全部連接的fd,然后通過[connection_info](https://github.com/LinkedDestiny/swoole-doc/blob/master/doc/03.swoole_server%E5%87%BD%E6%95%B0%E5%88%97%E8%A1%A8.md#swoole_serverconnection_info)查詢到fd對應的from_id。 ## **3.Buffer和EOF_Check的使用** 在外網通信時,有些客戶端發送數據的速度較慢,每次只能發送一小段數據。這樣[onReceive](https://github.com/LinkedDestiny/swoole-doc/blob/master/doc/02.swoole_server%E4%BA%8B%E4%BB%B6%E5%9B%9E%E8%B0%83%E5%87%BD%E6%95%B0.md#1onreceive)到的數據就不是一個完整的包。 還有些客戶端是逐字節發送數據的,如果每次回調[onReceive](https://github.com/LinkedDestiny/swoole-doc/blob/master/doc/02.swoole_server%E4%BA%8B%E4%BB%B6%E5%9B%9E%E8%B0%83%E5%87%BD%E6%95%B0.md#1onreceive)會拖慢整個系統。<br> Swoole提供了buffer和eof_check的功能,在C擴展底層檢測到如果不是完整的請求,會等待新的數據到達,組成完成的請求后再回調[onReceive](https://github.com/LinkedDestiny/swoole-doc/blob/master/doc/02.swoole_server%E4%BA%8B%E4%BB%B6%E5%9B%9E%E8%B0%83%E5%87%BD%E6%95%B0.md#1onreceive)。<br> 在[swoole_server_set](https://github.com/LinkedDestiny/swoole-doc/blob/master/doc/03.swoole_server%E5%87%BD%E6%95%B0%E5%88%97%E8%A1%A8.md#swoole_serverset)中增加,[open_eof_check](https://github.com/LinkedDestiny/swoole-doc/blob/master/doc/01.swoole_server%E9%85%8D%E7%BD%AE%E9%80%89%E9%A1%B9.md#13open_eof_check)和[package_eof](https://github.com/LinkedDestiny/swoole-doc/blob/master/doc/01.swoole_server%E9%85%8D%E7%BD%AE%E9%80%89%E9%A1%B9.md#14package_eof-)來開啟此功能。[open_eof_check](https://github.com/LinkedDestiny/swoole-doc/blob/master/doc/01.swoole_server%E9%85%8D%E7%BD%AE%E9%80%89%E9%A1%B9.md#13open_eof_check)=1表示啟用buffer檢查,[package_eof](https://github.com/LinkedDestiny/swoole-doc/blob/master/doc/01.swoole_server%E9%85%8D%E7%BD%AE%E9%80%89%E9%A1%B9.md#14package_eof-)設置數據包結束符<br> > buffer功能會將所有收到的數據放到內存中,會占用較多內存<br> 通過設置[package_max_length](https://github.com/LinkedDestiny/swoole-doc/blob/master/doc/01.swoole_server%E9%85%8D%E7%BD%AE%E9%80%89%E9%A1%B9.md#19package_max_length)<br> 來設定每個連接最大緩存多少數據,超過此大小的連接將會被關閉<br> ```php swoole_server_set($serv, array( 'package_eof' => "\r\n\r\n", //http協議就是以\r\n\r\n作為結束符的,這里也可以使用二進制內容 'open_eof_check' => 1, )); ``` ## **4.固定包頭+包體協議自動分包** swoole-1.7.3版本重構了length_check特性的代碼,對于固定包頭+包體格式的協議可以直接在master進程中進行分包和組包,worker進程中可以一次性收到一個完整的包。帶來的好處是:<br> - C擴展層進行協議的處理,性能最佳,原PHP代碼雖然也可以實現協議處理,但需要耗費較多CPU - TCP連接與業務邏輯分離,有效利用所有Worker進程,即使只有1個TCP連接,也可以利用所有Worker 使用時,僅需打開[open_length_check](https://github.com/LinkedDestiny/swoole-doc/blob/master/doc/01.swoole_server%E9%85%8D%E7%BD%AE%E9%80%89%E9%A1%B9.md#15open_length_check)配置項,并設置相應的配置選項即可。<br> 相關配置項查看[swoole_server配置選項](https://github.com/LinkedDestiny/swoole-doc/blob/master/doc/01.swoole_server配置選項.md)第15項到第19項 ## **5.Worker與Reactor通信模式** Worker進程如何與Reactor進程通信,Swoole提供了3種方式。通過[swoole_server_set](https://github.com/LinkedDestiny/swoole-doc/blob/master/doc/03.swoole_server%E5%87%BD%E6%95%B0%E5%88%97%E8%A1%A8.md#swoole_serverset)參數中修改[dispatch_mode](https://github.com/LinkedDestiny/swoole-doc/blob/master/doc/01.swoole_server%E9%85%8D%E7%BD%AE%E9%80%89%E9%A1%B9.md#5dispatch_mode)的值來配置。<br> | dispatch_mode | 名稱 | 介紹 | | ---- | ----- | ---- | | 1 | 輪詢模式 | 收到的請求數據包會輪詢發到每個Worker進程。 | | 2 | FD取模 | 數據包根據fd的值%worker_num來分配,這個模式可以保證一個TCP客戶端連接發送的數據總是會被分配給同一個worker進程。 | | 3 | Queue模式 | 此模式下,網絡請求的處理是搶占式的,這可以保證總是最空閑的worker進程才會拿到請求去處理,缺點是客戶端連接對應的worker是隨機的。不確定哪個worker會處理請求。無法保存連接狀態(可借助第三方庫或者[swoole_table](https://github.com/LinkedDestiny/swoole-doc/blob/master/doc/13.swoole_table.md)實現)| ## **6.TCP-Keepalive死連接檢測** 在TCP中有一個Keep-Alive的機制可以檢測死連接,應用層如果對于死鏈接周期不敏感或者沒有實現心跳機制,可以使用操作系統提供的keepalive機制來踢掉死鏈接。 在[swoole_server_set](https://github.com/LinkedDestiny/swoole-doc/blob/master/doc/03.swoole_server%E5%87%BD%E6%95%B0%E5%88%97%E8%A1%A8.md#swoole_serverset)中增加[open_tcp_keepalive](https://github.com/LinkedDestiny/swoole-doc/blob/master/doc/01.swoole_server%E9%85%8D%E7%BD%AE%E9%80%89%E9%A1%B9.md#24open_tcp_keepalive)=>1表示啟用tcp keepalive。 另外,有3個選項可以對keepalive的細節進行調整。<br> | 名稱 | 介紹 | | ---- | ----- | | tcp_keepidle | 單位秒,連接在n秒內沒有數據請求,將開始對此連接進行探測 | | tcp_keepcount | 探測的次數,超過次數后將close此連接 | | tcp_keepinterval | 探測的間隔時間,單位秒 | ## **7.TCP服務器心跳維持方案** 正常情況下客戶端中斷TCP連接時,會發送一個FIN包,進行4次斷開握手來通知服務器。但一些異常情況下,如客戶端突然斷電斷網或者網絡異常,服務器可能無法得知客戶端已斷開連接。<br> 尤其是移動網絡,TCP連接非常不穩定,所以需要一套機制來保證服務器和客戶端之間連接的有效性。<br> Swoole擴展本身內置了這種機制,開發者只需要配置兩個個參數即可啟用。Swoole在每次收到客戶端數據會記錄一個時間戳,當客戶端在一定時間內未向服務器端發送數據,那服務器會自動切斷連接。<br> ```php $serv->set(array( 'heartbeat_check_interval' => 5, 'heartbeat_idle_time' => 10 )); ``` 上面的設置就是每5秒偵測一次心跳,一個TCP連接如果在10秒內未向服務器端發送數據,將會被切斷。[點此查看參數說明](https://github.com/LinkedDestiny/swoole-doc/blob/master/doc/01.swoole_server%E9%85%8D%E7%BD%AE%E9%80%89%E9%A1%B9.md#11heartbeat_check_interval)<br> 使用[swoole_server::heartbeat()](https://github.com/LinkedDestiny/swoole-doc/blob/master/doc/03.swoole_server%E5%87%BD%E6%95%B0%E5%88%97%E8%A1%A8.md#swoole_serverheartbeat)函數手工檢測心跳是否到期。此函數會返回閑置時間超過[heartbeat_idle_time](https://github.com/LinkedDestiny/swoole-doc/blob/master/doc/01.swoole_server%E9%85%8D%E7%BD%AE%E9%80%89%E9%A1%B9.md#12heartbeat_idle_time)的所有TCP連接。程序中可以將這些連接做一些操作,如發送數據或關閉連接。<br> ## **8.多端口監聽的使用** Swoole提供了多端口監聽的機制,這樣可以同時監聽UDP和TCP,同時監聽內網地址和外網地址。內網地址和端口用于管理,外網地址用于對外服務。<br> [點此查看教程](https://github.com/LinkedDestiny/swoole-doc/blob/master/04.Swoole%E5%A4%9A%E7%AB%AF%E5%8F%A3%E7%9B%91%E5%90%AC%E3%80%81%E7%83%AD%E9%87%8D%E5%90%AF%E4%BB%A5%E5%8F%8ATimer%E8%BF%9B%E9%98%B6%EF%BC%9A%E7%AE%80%E5%8D%95crontab.md#1%E5%A4%9A%E7%AB%AF%E5%8F%A3%E7%9B%91%E5%90%AC)<br> ## **9.捕獲Server運行期致命錯誤** Server運行期一旦發生致命錯誤,那客戶端連接將無法得到回應。如Web服務器,如果有致命錯誤應當向客戶端發送Http 500 錯誤信息。<br> 在PHP中可以通過register_shutdown_function + error_get_last 2個函數來捕獲致命錯誤,并將錯誤信息發送給客戶端連接。具體代碼示例如下:<br> ```php register_shutdown_function('handleFatal'); function handleFatal() { $error = error_get_last(); if (isset($error['type'])) { switch ($error['type']) { case E_ERROR : case E_PARSE : case E_DEPRECATED: case E_CORE_ERROR : case E_COMPILE_ERROR : $message = $error['message']; $file = $error['file']; $line = $error['line']; $log = "$message ($file:$line)\nStack trace:\n"; $trace = debug_backtrace(); foreach ($trace as $i => $t) { if (!isset($t['file'])) { $t['file'] = 'unknown'; } if (!isset($t['line'])) { $t['line'] = 0; } if (!isset($t['function'])) { $t['function'] = 'unknown'; } $log .= "#$i {$t['file']}({$t['line']}): "; if (isset($t['object']) && is_object($t['object'])) { $log .= get_class($t['object']) . '->'; } $log .= "{$t['function']}()\n"; } if (isset($_SERVER['REQUEST_URI'])) { $log .= '[QUERY] ' . $_SERVER['REQUEST_URI']; } error_log($log); $serv->send($this->currentFd, $log); } } } ``` ## **10.SSL隧道加密TCP-Server** 1.7.4后swoole增加了對SSL隧道加密的支持,在swoole_server中可以啟用SSL證書加密。使用僅需增加[swoole_server_set](https://github.com/LinkedDestiny/swoole-doc/blob/master/doc/03.swoole_server%E5%87%BD%E6%95%B0%E5%88%97%E8%A1%A8.md#swoole_serverset)的配置即可,并將listener端口的類型,增加[SWOOLE_SSL](https://github.com/LinkedDestiny/swoole-doc/blob/master/doc/03.swoole_server%E5%87%BD%E6%95%B0%E5%88%97%E8%A1%A8.md#swoole_serveraddlistener)標志。<br> ```php $serv = new swoole_server("0.0.0.0", 443, SWOOLE_PROCESS, SWOOLE_SOCK_TCP | SWOOLE_SSL); // 加密端口 $key_dir = dirname(dirname(__DIR__)).'/tests/ssl'; $serv->addlistener('0.0.0.0', 80, SWOOLE_SOCK_TCP); // 非加密端口 $serv->set(array( 'worker_num' => 4, 'ssl_cert_file' => $key_dir.'/ssl.crt', 'ssl_key_file' => $key_dir.'/ssl.key', )); ``` 配置項說明[點此查看](https://github.com/LinkedDestiny/swoole-doc/blob/master/doc/01.swoole_server%E9%85%8D%E7%BD%AE%E9%80%89%E9%A1%B9.md#23ssl_cert_file%E5%92%8Cssl_key_file).<br>
                  <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>

                              哎呀哎呀视频在线观看