關於Curl在Swoole協程中的解決方案詳析

2022-09-28 00:36:19 字數 3596 閱讀 3558

前言

眾所周知,在 swoole 應用中,是不推薦使用 cgccvssurl 的,因為 curl 會阻塞程序。

本文會用實際的**和資料,用最直觀的方式,讓你明白為什麼。

最後還會給出 curl 在 swoole 中的解決方案,如果不想看分析可以直接拉到最後。

例程對比

宇潤看文章不喜歡那些虛的,所以自己寫也比較實在,直接來跑一下**,用資料看為什麼不推薦在 swoole 使用 curl。

為了偷懶,我直接用了 yurunhttp 的 curl 和 swoole handler,來替代那些又臭又長的 curl **。

yurunhttp::setdefaulthandler(\yurun\util\yurunhttp\handler\curl::class); // 切換為 curl handler

$channel = new \swoole\coroutine\channel;

for($i = 0; $i < request_count; ++$i)

);} for($i = 0; $i < request_count; ++$i)

$channel->close();

echo 'curl time: ', (microtime(true) - $time) . 's', php_eol, php_eol;

});執行

首次執行需要執行 composer update 安裝依賴

執行 php server.php,啟動服務端

執行 php test.php,啟動客戶端

執行結果

結果分析

上面的**在服務端延遲 1 秒後返回結果,模擬實際業務的耗時。

通過客戶端的耗時可以看出,curl 3 次請求總共耗時 3 秒多,而協程客戶端僅耗時 1 秒多。

因為前一次請求中,curl 等待返回內容的時間是幹不了其他事情的。而協程客戶端等待返回內容期間,是掛起當前協程,轉而再去執行其它協程中的**。

解決方案

使用 swoole 內建的協程客戶端實現,適合有一定基礎的開發者使用。

文件:guzzle-swoole

我們在專案中,可能很少直接寫 curl,但是用到的很多第三方類庫(如某某雲們的 sdk)會有用到。

這些第三方類庫通常使用的是 guzzle 作為 http 客戶端,而 guzzle 底層也是使用 curl 實現。

宇潤專為此種場景研發了 guzzle-swoole 包,引入後可以讓這些 sdk 輕鬆支援協程,而不用修改一行**。

使用方法

執行命令直接安裝依賴:composer require yurunsoft/guzzle-swoole ~1.1

全域性設定處理器:

手動指定 swoole 處理器:

yurunhttp 是開源的php http類庫,支援鏈式操作,簡單易用。

支援所有常見的get、post、put、delete、update等請求方式,支援瀏覽器級別 cookies 管理、上傳**、設定和讀取header、cookie、請求引數、失敗重試、限速、**、證書等。

3.0 版完美支援curl、swoole 協程;3.2 版支援 swoo websocket 客戶端。

使用方法

執行命令直接安裝依賴:composer require yurunsoft/yurun-http ~3.2

// 設定預設請求處理器為 swoole

// swoole 處理器必須在協程中呼叫

go('test');

function test()

截止發稿時,swoole 4.4 新增的 hook curl 依然是實驗性功能。雖然宇潤曾為該功能貢獻過一部分**,但是由於需要相容的工作量非常大,有太多 option 不被支援,我個人是暫時不推薦使用 hook curl 的。

總結本文標題: 關於curl在swoole協程中的解決方案詳析

本文位址:

swoole使用協程

協程 協程可以理解為純使用者態的執行緒,其通過協作而不是搶占來進行切換。相對於程序或者執行緒,協程所有的操作都可以在使用者態完成,建立和切換的消耗更低。swoole可以為每乙個請求建立對應的協程,根據io的狀態來合理的排程協程,這會帶來了以下優勢 開發者可以無感知的用同步的 編寫方式達到非同步io的...

swoole之協程channel元素個數

channel用於程序內跨協程通訊,按照角色分為生產協程和消費協程。生產協程,在channel已滿時,會被掛起 消費協程,在channel為空是,也會被掛起。chan new swoole coroutine channel 50 function t4 swoole coroutine chann...

關於協程 nodejs和golang協程的不同

nodejs和golang都是支援協程的,從表現上來看,nodejs對於協程的支援在於async await,golang對協程的支援在於goroutine。關於協程的話題,簡單來說,可以看作是非搶占式的輕量級執行緒。一句話概括,上面提到了 可以看作是非搶占式的輕量級執行緒 在多執行緒中,把一段 放...