數據源程序庫可行性替換研究
1118
2025-03-31
Swoole v4.6.0 版本發布了,同樣也是 2021 年的首個版本更新。
作為一個 y 版本發布,此次更新也包含了不兼容的修改以及許多的新功能,下面就來看一看都有哪些改動?
向下不兼容改動
從 v4.6.0 版本開始將不再支持 PHP7.1
PHP 官方對于 PHP7.1 的支持也早已在 2019 年底結束。
將 Event::rshutdown() 標記為已棄用,請改用 Coroutine\run
在之前的版本中,如果在index.php中直接使用go創建協程
go(function () { var_dump(Co\System::gethostbyname('www.baidu.com')); });
這樣是正常的,但是在此版本中,就會收到廢棄警告
PHP Deprecated: Swoole\Event::rshutdown(): Event::wait() in shutdown function is deprecated in Unknown on line 0
推薦使用Coroutine\run來代替這種方式:
Swoole\Coroutine\run(function () { var_dump(Co\System::gethostbyname('www.baidu.com')); }); Swoole\Coroutine\run(function () { go(function () { var_dump(Co\System::gethostbyname('www.baidu.com')); }); go(function () { var_dump(Co\System::gethostbyname('www.zhihu.com')); }); });
默認啟用 Coroutine hook
使用了上面所說的Coroutine\run之后,也會迎來一個新的變更:默認啟用 Coroutine hook,即自動設置SWOOLE_HOOK_ALL
use Swoole\Runtime; Swoole\Coroutine\run(function () { $flags = Runtime::getHookFlags(); assert($flags === SWOOLE_HOOK_ALL); var_dump($flags); });
當然也可以自行設置所需要的 flag
use Swoole\Runtime; Runtime::setHookFlags(SWOOLE_HOOK_TCP); Swoole\Coroutine\run(function () { $flags = Runtime::getHookFlags(); assert($flags === SWOOLE_HOOK_TCP); var_dump($flags); });
使用協程時禁用不安全功能,包括 pcntl_fork/pcntl_wait/pcntl_waitpid/pcntl_sigtimedwait
Swoole\Coroutine\run(function () { $pid = pcntl_fork(); var_dump($pid); });
在此版本使用上面的示例代碼,你將會得到一個 Warning 錯誤
PHP Warning: pcntl_fork() has been disabled for security reasons
移除了 session_id 的最大限制,不再重復
將 Server 的 session_id 從 int24 改為了 int64 ,這樣可以持續自增,永不重復。
之前的int24時,session_id大約可以到 1600 萬就可能會出現重復的問題。
新增 API & 增強
原生 curl 協程客戶端 (SWOOLE_HOOK_NATIVE_CURL)
在這個版本中最大的變化莫過于支持了原生 curl 協程客戶端,有什么用呢?
用過 SWOOLE_HOOK_CURL 的小伙伴應該知道,有一些不支持的選項,同時還會因為部分 SDK 的不兼容導致一些錯誤,例如:
PHP Notice: Object of class Swoole\Curl\Handler could not be converted to int PHP Warning: curl_multi_add_handle() expects parameter 2 to be resource, object given
原因是 hook 后的 curl 不再是一個 resource 類型,而是 object 類型。
出現這種問題也建議聯系 SDK 方修改代碼,因為在 PHP8 中 curl 不再是 resource 類型,而是 object 類型
以及經常使用的阿里云 OSS SDK 也是不支持SWOOLE_HOOK_CURL的,會遇到一些奇奇怪怪的
那么從 v4.6.0 版本開始就可以使用 SWOOLE_HOOK_NATIVE_CURL 代替 SWOOLE_HOOK_CURL,來解決以上提到的問題
使用SWOOLE_HOOK_NATIVE_CURL需要在編譯 Swoole 擴展時增加 –enable-swoole-curl 編譯參數,開啟該選項后將自動設置 SWOOLE_HOOK_NATIVE_CURL,關閉 SWOOLE_HOOK_CURL,同時 SWOOLE_HOOK_ALL 也會包含 SWOOLE_HOOK_NATIVE_CURL
pecl 的 v4.6.0 版本暫時沒有增加這個選項,請使用手動編譯開啟,下個版本中會增加。
編譯成功后使用--ri查看信息,就可以看到curl-native
$ php --ri swoole | grep curl curl-native => enabled
從下面的例子就可以看出兩者的不同
Swoole\Runtime::setHookFlags(SWOOLE_HOOK_CURL); Swoole\Coroutine\run(function () { $curl = curl_init(); var_dump(get_class($curl), (int) $curl); //PHP Notice: Object of class Swoole\Curl\Handler could not be converted to int //string(19) "Swoole\Curl\Handler" //int(1) });
Swoole\Coroutine\run(function () { $curl = curl_init(); var_dump($curl, (int) $curl); //resource(4) of type (Swoole-Coroutine-cURL Handle) //int(4) });
SWOOLE_HOOK_SOCKETS
增加了對 ext-sockets 的協程化支持
const N = 8; $GLOBALS['time'] = []; $s = microtime(true); Swoole\Runtime::setHookFlags(SWOOLE_HOOK_SOCKETS); Swoole\Coroutine\run(function () { $n = N; while($n--) { go(function() { $s = microtime(true); $domain = 'www.baidu.com'; $sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); socket_connect($sock, $domain, 80); socket_write($sock, "GET / HTTP/1.0\r\nHost: $domain\r\nConnection: close\r\nKeep-Alive: off\r\n\r\n"); $html = ''; while(true) { $data = socket_read($sock, 8192); if ($data == '') { break; } $html .= $data; } socket_close($sock); $GLOBALS['time'][] = microtime(true) - $s; }); } }); echo "Done\n"; var_dump(microtime(true) - $s, array_sum($GLOBALS['time']) / 3);
支持 Server 事件回調函數傳遞對象風格的參數
默認不啟用。通過設置 event_object 參數進行啟用,以下事件回調將使用對象風格
onConnect
onReceive
onClose
onPacket
onPipeMessage
onWorkerError
onTask
onFinish
以 onConnect 為例,具體內容可參考文檔 回調對象
$server->on('Connect', function (Swoole\Server $server, int $fd, int $reactorId) { var_dump($fd); }); $server->set([ 'event_object' => true, ]); $server->on('Connect', function (Swoole\Server $serv, Swoole\Server\Event $object) { var_dump($object); });
支持重復 header
支持重復設置相同 $key 的 HTTP 頭,并且 $value 支持多種類型,如 array、object、int、float,底層會進行 toString 轉換,并且會移除末尾的空格以及換行
$http = new Swoole\Http\Server('0.0.0.0', 9501); $http->on('request', function ($request, $response) { $response->header('Test-Value', [ "a\r\n", 'd5678', "e \n ", null, 5678, 3.1415926, ]); $response->header('Foo', new SplFileInfo('bar')); }); $http->start();
$ curl -I http://127.0.0.1:9501 HTTP/1.1 200 OK Test-Value: a Test-Value: d5678 Test-Value: e Test-Value: 5678 Test-Value: 3.1415926 Foo: bar Server: swoole-http-server Connection: keep-alive Content-Type: text/html Date: Wed, 06 Jan 2021 05:16:17 GMT Content-Length: 39
協程死鎖檢測
默認開啟,可以通過在 Coroutine::set 中設置 enable_deadlock_check 進行關閉
在 EventLoop 終止后,如果存在協程死鎖,底層會輸出相關堆棧信息:
=================================================================== [FATAL ERROR]: all coroutines (count: 1) are asleep - deadlock! =================================================================== [Coroutine-2] -------------------------------------------------------------------- #0 Swoole\Coroutine::printBackTrace() called at [@swoole-src/library/core/Coroutine/functions.php:74] #1 Swoole\Coroutine\deadlock_check() #2 curl_getinfo() called at [/mnt/c/code/php/hyperf-skeleton/vendor/aliyuncs/oss-sdk-php/src/OSS/Http/RequestCore.php:492]
更新日志
下面是完整的更新日志
向下不兼容改動
移除了session id的最大限制,不再重復 (#3879) (@matyhtf)
使用協程時禁用不安全功能,包括pcntl_fork/pcntl_wait/pcntl_waitpid/pcntl_sigtimedwait (#3880) (@matyhtf)
默認啟用 coroutine hook (#3903) (@matyhtf)
移除
不再支持 PHP7.1 (4a963df) (9de8d9e) (@matyhtf)
廢棄
將 Event::rshutdown() 標記為已棄用,請改用 Coroutine\run (#3881) (@matyhtf)
新增 API
支持 setPriority/getPriority (#3876) (@matyhtf)
支持 native-curl hook (#3863) (@matyhtf) (@huanghantao)
支持 Server 事件回調函數傳遞對象風格的參數,默認不傳遞對象風格的參數 (#3888) (@matyhtf)
支持 hook sockets 擴展 (#3898) (@matyhtf)
支持重復 header (#3905) (@matyhtf)
支持 SSL sni (#3908) (@matyhtf)
支持 hook stdio (#3924) (@matyhtf)
支持 stream_socket 的 capture_peer_cert 選項 (#3930) (@matyhtf)
添加 Http\Request::create/parse/isCompleted (#3938) (@matyhtf)
添加 Http\Response::isWritable (db56827) (@matyhtf)
增強
Server 的所有時間精度都從 int 修改為 double (#3882) (@matyhtf)
在 swoole_client_select 函數里面檢查 poll 函數的 EINTR 情況 (#3909) (@shiguangqi)
添加協程死鎖檢測 (#3911) (@matyhtf)
支持使用 SWOOLE_BASE 模式在另一個進程中關閉連接 (#3916) (@matyhtf)
優化 Server master 進程與 worker 進程通信的性能,減少內存拷貝 (#3910) (@huanghantao) (@matyhtf)
修復
當 Coroutine\Channel 被關閉時,pop 出里面所有的數據 (960431d) (@matyhtf)
修復使用 JIT 時的內存錯誤 (#3907) (@twose)
修復 port->set() dtls 編譯錯誤 (#3947) (@Yurunsoft)
修復 connection_list 錯誤 (#3948) (@sy-records)
修復 ssl verify (#3954) (@matyhtf)
修復 Table 遞增和遞減時不能清除所有列問題 (#3956) (@matyhtf) (@sy-records)
修復使用 LibreSSL 2.7.5 編譯失敗 (#3962) (@matyhtf)
修復未定義的常量 CURLOPT_HEADEROPT 和 CURLOPT_PROXYHEADER (swoole/library#77) (@sy-records)
內核
默認情況下忽略 SIGPIPE 信號 (9647678) (@matyhtf)
支持同時運行 PHP 協程和 C 協程 (c94bfd8) (@matyhtf)
添加 get_elapsed 測試 (#3961) (@luolaifa000)
添加 get_init_msec 測試 (#3964) (@luffluo)
PHP Swoole
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。