PHP開發(fā)中需要請(qǐng)求其它HTTP(S)服務(wù)接口
時(shí)盆赤,很多人都會(huì)直接使用內(nèi)置的curl
工具。其中curl_multi
可以將之前單個(gè)的curl請(qǐng)求
添加到一個(gè)批處理中去并行執(zhí)行悲柱,在時(shí)間開銷上實(shí)現(xiàn)max(接口1, 接口2, 接口3...)
的效果,能夠降低我們的業(yè)務(wù)需要多服務(wù)數(shù)據(jù)聚合時(shí)對(duì)使用者產(chǎn)生的等待感。
那么本文能夠帶來什么呢刺彩?
- 時(shí)間優(yōu)化不止于
max(接口1, 接口2, 接口3...)
,可達(dá)max(業(yè)務(wù)代碼, 接口1, 接口2, 接口3...)
枝恋,讓請(qǐng)求后的等待期也能用來執(zhí)行業(yè)務(wù)代碼创倔。 - 對(duì)
curl curl_multi
的友好使用封裝,以對(duì)象的封裝來簡(jiǎn)化代碼中各種curl_*
函數(shù)的記憶和凌亂鼓择。
環(huán)境
-
Win10 x64
三幻、PHP8.0.0 TS x64
前言
-
curl_multi
創(chuàng)建一個(gè)批處理,將多個(gè)curl
句柄加入其中呐能,然后執(zhí)行這個(gè)批處理 -
curl_multi_exec()
執(zhí)行批處理中需要操作的句柄念搬。- 如
發(fā)送請(qǐng)求
/接收處理響應(yīng)
,等待響應(yīng)時(shí)則無需操作
- 如
-
curl_multi_select()
阻塞等待摆出,直到有待處理的句柄
/超時(shí)
朗徊。- 如某個(gè)句柄接收到了響應(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請(qǐng)求報(bào)文象踊,推測(cè)exec的執(zhí)行粒度為HTTP請(qǐng)求/響應(yīng)報(bào)文的處理温亲。 - 所以我們可以先發(fā)送請(qǐng)求,然后執(zhí)行自己的業(yè)務(wù)邏輯杯矩,最后需要時(shí)再獲取執(zhí)行結(jié)果栈虚。這樣就可以復(fù)用等待響應(yīng)的時(shí)間。
- 因?yàn)?code>重定向/
HTTPS
都會(huì)涉及到多次HTTP報(bào)文
交互史隆,封裝中盡量為其提供了可選優(yōu)化參數(shù)魂务。
測(cè)試(下方有結(jié)果圖)
- 封裝&測(cè)試代碼倉(cāng)庫(kù) https://gitee.com/VwenX/curl-mut
- 本地使用
node
啟了一個(gè)http
服務(wù)器(代碼見下圖,網(wǎng)上隨便找的改一下用) - 步驟
- 目標(biāo)
http服務(wù)
中設(shè)定了接到請(qǐng)求后等待300ms
后才進(jìn)行響應(yīng),并在響應(yīng)中輸出實(shí)際等待時(shí)長(zhǎng) - PHP作為客戶端請(qǐng)求3個(gè)接口粘姜,同時(shí)模擬執(zhí)行業(yè)務(wù)1秒
- 最終我們可以看到3個(gè)接口的耗時(shí)都在310ms以上鬓照。
- 如果按照常規(guī)調(diào)用,整體耗時(shí)該在
max(a, b, c)+業(yè)務(wù)=
1317ms以上孤紧。但我們此番處理之后的整體耗時(shí)僅為1017ms豺裆,3個(gè)310+ms的請(qǐng)求幾乎沒有占用什么時(shí)間開銷!
- 目標(biāo)