PHP開發中需要請求其它HTTP(S)服務介面
時,很多人都會直接使用內建的curl
工具。其中curl_multi
可以將之前單個的curl請求
新增到一個批處理中去並行執行,在時間開銷上實現max(介面1, 介面2, 介面3...)
的效果,能夠降低我們的業務需要多服務資料聚合時對使用者產生的等待感。
那麼本文能夠帶來什麼呢?
- 時間優化不止於
max(介面1, 介面2, 介面3...)
,可達max(業務程式碼, 介面1, 介面2, 介面3...)
,讓請求後的等待期也能用來執行業務程式碼。 - 對
curl curl_multi
的友好使用封裝,以物件的封裝來簡化程式碼中各種curl_*
函式的記憶和凌亂。
環境
Win10 x64
、PHP8.0.0 TS x64
前言
curl_multi
建立一個批處理,將多個curl
控制程式碼加入其中,然後執行這個批處理curl_multi_exec()
執行批處理中需要操作的控制程式碼。- 如
傳送請求
/接收處理響應
,等待響應時則無需操作
- 如
curl_multi_select()
阻塞等待,直到有待處理的控制程式碼
/超時
。- 如某個控制程式碼接收到了響應。
- 此函式可以避免等待期的死迴圈空轉exec情況。執行緒應該是掛起狀態,由底層觸發喚醒。
分析
- 優化核心在於
curl_multi_exec()
和curl_multi_select()
- 通過除錯發現執行
curl_multi_exec()
第一次即為傳送HTTP請求報文,推測exec的執行粒度為HTTP請求/響應報文的處理。 - 所以我們可以先傳送請求,然後執行自己的業務邏輯,最後需要時再獲取執行結果。這樣就可以複用等待響應的時間。
- 因為
重定向
/HTTPS
都會涉及到多次HTTP報文
互動,封裝中儘量為其提供了可選優化引數。
測試(下方有結果圖)
- 封裝&測試程式碼倉庫 gitee.com/VwenX/curl-mut
- 本地使用
node
啟了一個http
伺服器(程式碼見下圖,網上隨便找的改一下用) - 步驟
- 目標
http服務
中設定了接到請求後等待300ms
後才進行響應,並在響應中輸出實際等待時長 - PHP作為客戶端請求3個介面,同時模擬執行業務1秒
- 最終我們可以看到3個介面的耗時都在310ms以上。
- 如果按照常規呼叫,整體耗時該在
max(a, b, c)+業務=
1317ms以上。但我們此番處理之後的整體耗時僅為1017ms,3個310+ms的請求幾乎沒有佔用什麼時間開銷!
- 目標
測試結果圖
本作品採用《CC 協議》,轉載必須註明作者和本文連結