PHPCurl的毫秒超時的乙個」Bug」

2021-06-20 17:13:25 字數 1033 閱讀 3018

最近我們的服務在公升級php使用的libcurl, 期望新版本的libcurl支援毫秒級的超時, 從而可以更加精細的控制後端的介面超時, 從而提高整體響應時間.

但是, 我們卻發現, 在我們的centos伺服器上, 當你設定了小於1000ms的超時以後, curl不會發起任何請求, 而直接返回超時錯誤(timeout reached 28).

原來, 這裡面有乙個坑, curl預設的, 在linux系統上, 如果使用了系統標準的dns解析, 則會使用sigalarm來提供控制網域名稱解析超時的功能, 但是sigalarm不支援小於1s的超時, 於是在libcurl 7.28.1的**中(注意中文注釋行):

intcurl_resolv_timeout

(struct

connectdata

*conn,

可見, 當你的超時時間小於1000ms的時候, name解析會直接返回curlresolv_timeout, 最後會導致curle_operation_timedout, 然後就error, timeout reached了…

這….太坑爹了吧? 難道說, 我們就不能使用毫秒超時麼? 那你提供這功能幹啥?

還是看**, 還是剛才那段**, 注意這個(中文注釋行):

看起來, 只要set.no_signal 這個東西為1, 就可以繞過了… 那這個玩意是啥呢?

這就簡單了, grep一下**, 發現:

哈哈, 原來是這貨:

加上這個opt以後, 一切終於正常了!

後記:這樣一來, 就會有乙個隱患, 那就是dns解析將不受超時限制了, 這在於公司內部來說, 一般沒什麼問題, 但是萬一dns伺服器hang住了, 那就可能會造成應用超時.

那麼還有其他辦法麼?

有, 那就是mike提醒的, 我們可以讓libcurl使用c-ares(c library for asynchronous dns requests)來做名字解析. 具體的可以在config curl的時候:

這樣就可以不用設定nosignal了

ps, 為什麼冠以」bug」, 我只是好奇, 他們為什麼不用setitimer?

乙個超時功能的設計

有乙個產品需求,需要執行某個動作之後,需要生成乙個超時的任務,在超時時間到了之後執行後續的動作,後續動作的執行大約耗時1秒鐘。任務允許在未到超時間刪除,超時時間不超過30天。要求在現有的產品架構上實現此功能。存在問題 方案二既然方案一存在持久化的問題,那麼只要解決這個問題即可,比如儲存在乙個公共的儲...

curl毫秒超時使用的坑

公升級後的libcurl已經支援了公釐級別的超時。但是使用的時候還有乙個坑需要注意跨過去 libcurl如果檢查到設定的timeout 1s 那麼會直接發出乙個訊號說 已經超時了 如果要使用毫秒超時 那麼還需要關閉這個signal功能,即設定中需要多乙個 curl setopt ch,curlopt...

乙個60秒超時導致除錯失敗的BUG

clr無法從com 上下文轉換為com上下文,這種狀態已持續60秒。異常資訊 clr無法從com 上下文0x645e18 轉換為com上下文0x645f88,這種狀態已持續60秒。擁有目標上下文 單元的執行緒很有可能執行的是非幫浦式等待或者在不傳送 windows 訊息的情況下處理乙個執行時間非常長...