PHP開發(fā)中需要請求其它HTTP(S)服務(wù)接口時,很多人都會直接使用內(nèi)置的curl工具。其中curl_multi可以將之前單個的curl請求添加到一個批處理中去并行執(zhí)行,在時間開銷上實(shí)現(xiàn)max(接口1, 接口2, 接口3...)的效果,能夠降低我們的業(yè)務(wù)需要多服務(wù)數(shù)據(jù)聚合時對使用者產(chǎn)生的等待感。
那么本文能夠帶來什么呢?
- 時間優(yōu)化不止于
max(接口1, 接口2, 接口3...),可達(dá)max(業(yè)務(wù)代碼, 接口1, 接口2, 接口3...),讓請求后的等待期也能用來執(zhí)行業(yè)務(wù)代碼。 - 對
curl curl_multi的友好使用封裝,以對象的封裝來簡化代碼中各種curl_*函數(shù)的記憶和凌亂。
環(huán)境
-
Win10 x64、PHP8.0.0 TS x64
前言
-
curl_multi創(chuàng)建一個批處理,將多個curl句柄加入其中,然后執(zhí)行這個批處理 -
curl_multi_exec()執(zhí)行批處理中需要操作的句柄。- 如
發(fā)送請求/接收處理響應(yīng),等待響應(yīng)時則無需操作
- 如
-
curl_multi_select()阻塞等待,直到有待處理的句柄/超時。- 如某個句柄接收到了響應(yīng)。
- 此函數(shù)可以避免等待期的死循環(huán)空轉(zhuǎn)exec情況。線程應(yīng)該是掛起狀態(tài),由底層觸發(fā)喚醒。
分析
- 優(yōu)化核心在于
curl_multi_exec()和curl_multi_select() - 通過調(diào)試發(fā)現(xiàn)執(zhí)行
curl_multi_exec()第一次即為發(fā)送HTTP請求報文,推測exec的執(zhí)行粒度為HTTP請求/響應(yīng)報文的處理。 - 所以我們可以先發(fā)送請求,然后執(zhí)行自己的業(yè)務(wù)邏輯,最后需要時再獲取執(zhí)行結(jié)果。這樣就可以復(fù)用等待響應(yīng)的時間。
- 因?yàn)?code>重定向/
HTTPS都會涉及到多次HTTP報文交互,封裝中盡量為其提供了可選優(yōu)化參數(shù)。
測試(下方有結(jié)果圖)
- 封裝&測試代碼倉庫 https://gitee.com/VwenX/curl-mut
- 本地使用
node啟了一個http服務(wù)器(代碼見下圖,網(wǎng)上隨便找的改一下用) - 步驟
- 目標(biāo)
http服務(wù)中設(shè)定了接到請求后等待300ms后才進(jìn)行響應(yīng),并在響應(yīng)中輸出實(shí)際等待時長 - PHP作為客戶端請求3個接口,同時模擬執(zhí)行業(yè)務(wù)1秒
- 最終我們可以看到3個接口的耗時都在310ms以上。
- 如果按照常規(guī)調(diào)用,整體耗時該在
max(a, b, c)+業(yè)務(wù)=1317ms以上。但我們此番處理之后的整體耗時僅為1017ms,3個310+ms的請求幾乎沒有占用什么時間開銷!
- 目標(biāo)
測試結(jié)果圖

curlMut測試結(jié)果.png