【轉】使用CURL檢測Client側發起的HTTP請求各階段時間

  • 2019 年 10 月 4 日
  • 筆記

參考原文地址: https://blog.51cto.com/h2ofly/1957171

生產環境下,經常會有需要調用第三方的介面。如果沒有很好地監控系統(SA負責網路層的監控、研發人員負責自己的業務層的監控實現),則出問題時候大大增加了排查難度,影響到服務的SLA。

第一、HTTP請求的過程介紹

1、DNS解析域名

2、請求從Clinet路由至Server,Clinet與Server建立TCP連接

3、如果使用了HTTPS,還涉及SSL連接的建立

4、server開始準備數據 (開始邏輯計算、調後端介面、查資料庫快取等)

5、server開始傳遞數據 (數據準備完成,開始給client傳數據)

6、數據傳輸完畢

7、整個過程可能還涉及多次重定向

第二、關於CURL的介紹

CURL是利用URL語法在命令行方式下工作的開源數據傳輸工具。

支援:DICT, FILE, FTP, FTPS, Gopher, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, POP3, POP3S, RTMP, RTSP, SCP, SFTP, SMB, SMBS, SMTP, SMTPS, Telnet and TFTP. curl supports SSL certificates, HTTP POST, HTTP PUT, FTP uploading, HTTP form based upload, proxies, HTTP/2, cookies, user+password authentication (Basic, Plain, Digest, CRAM-MD5, NTLM, Negotiate and Kerberos), file transfer resume, proxy tunneling 等

最新版的curl穩定版為7.55.1(截止20170817)

源程式碼:https://github.com/curl/curl

第三:用CURL檢測Clinet側發起的HTTP請求各階段時間,簡要說明

1、TCP建立連接的耗時:CONNECT-NAMELOOKUP

2、建立TCP連接到server返回client第一個位元組的時間:

STARTTRANSFER-CONNECT

3、SERVER處理數據的時間:

可以用STARTTRANSFER – PRETRANSFER計算得到

4、CLIENT接收數據的耗時(開始接收至接收完成):

TOTAL-STARTTRANSFER

第五、詳細說明

NAMELOOKUP:從開始計算,域名解析完成的耗時

CURLINFO_NAMELOOKUP_TIME. The time it took from the start until the name resolving was completed.

CONNECT:從開始計算,TCP建立完成的耗時

CURLINFO_CONNECT_TIME. The time it took from the start until the connect to the remote host (or proxy) was completed.

APPCONNECT:從開始計算,應用層(SSL,在TCP之上的應用層)連接/握手完成的耗時

CURLINFO_APPCONNECT_TIME. The time it took from the start until the SSL connect/handshake with the remote host was completed. (Added in in 7.19.0)

PRETRANSFER:從開始計算,準備開始傳輸數據的耗時

CURLINFO_PRETRANSFER_TIME. The time it took from the start until the file transfer is just about to begin. This includes all pre-transfer commands and negotiations that are specific to the particular protocol(s) involved.

STARTTRANSFER:從開始計算,開始傳輸數據的耗時(libcurl接收到第一個位元組)

CURLINFO_STARTTRANSFER_TIME. The time it took from the start until the first byte is received by libcurl.

TOTAL:總的耗時

CURLINFO_TOTAL_TIME. Total time of the previous request.

REDIRECT:整個過程重定向的耗時,如果整個過程沒有重定向,這個時間為0

CURLINFO_REDIRECT_TIME. The time it took for all redirection steps include name lookup, connect, pretransfer and transfer before final transaction was started. So, this is zero if no redirection took place.

另:python也有一個pycurl模組,大家可以嘗試。

參考:

https://curl.haxx.se/libcurl/c/curl_easy_getinfo.html

下面是我學習了上文部落格,自己做的一個測試:

curl -o /dev/null -s -w time_namelookup:"t"%{time_namelookup}"n"time_connect:"tt"%{time_connect}"n"time_appconnect:"t"%{time_appconnect}"n"time_pretransfer:"t"%{time_pretransfer}"n"time_starttransfer:"t"%{time_starttransfer}"n"time_total:"tt"%{time_total}"n"time_redirect:"tt"%{time_redirect}"n"  https://blog.51cto.com/lee90

time_namelookup:0.000

time_connect:0.032

time_appconnect:0.000

time_pretransfer:0.032

time_starttransfer:0.780

time_total:0.844

time_redirect:0.000

註:這裡的單位為秒

根據上面的這些數值,可以算出請求https://blog.51cto.com/lee90如下結論:

dns解析耗時: 0.000s  (一般0.000的話,說明之前不久請求過這個域名,本地已經有快取了)

建立連接耗時: 0.032s

傳輸耗時:0.780-0.032=0.748s (因為傳輸的博文內容比較多,因此可以時間挺長的)

下面是我測試curl自己的部落格的截圖:

下圖是我通過blackbox_exporter+grafana展示的截圖嗎,可以和上面的curl結果對比下:

此外,還可以使用pycurl+graphite+statsd來採集這些資訊,但是不如prometheus好用,生產上我們還是推薦用prometheus來做這件事情。