如何測試代理請求取消,避免遺留幽靈流量

關閉瀏覽器分頁、中止 API 請求或取消蒐集任務,並不能自動證明所有層級的工作都停止了。用戶端可能放棄讀取回應,但代理仍在轉送位元組,目標端仍在產生大型回應,重試佇列又建立替代請求,或連線池一直占用並行直到逾時。
這些隱藏行為會浪費代理流量、占用並行、干擾計費並造成重複蒐集。本指南為已獲授權的 HTTP、HTTPS CONNECT、SOCKS 與瀏覽器代理工作流程建立可控的取消測試。
先定義「已取消」的完整含義
有效的取消契約需要涵蓋每一層:
| 層級 | 預期結果 |
|---|---|
| 應用程式 | 任務以明確的取消狀態結束,不能記為成功 |
| 重試控制器 | 除非策略明確允許,否則不建立替代嘗試 |
| 用戶端傳輸 | 回應本文停止,串流或通訊端得到釋放 |
| 代理路線 | 通道或請求不再占用活動容量 |
| 受控目標 | 產生或傳輸停止,或單獨標記已經完成 |
| 計量 | 已傳輸位元組與請求數量可以解釋和核對 |
不要只把「呼叫方很快返回」定義為成功。使用者看到的操作已經結束,背景流量仍可能繼續。
建立安全測試端點
使用你控制的目標端,並提供四種確定性端點:
- 按固定間隔輸出編號資料塊的慢速回應;
- 延遲首位元組的回應;
- 以低速讀取的有界上傳接收器;
- 用於取消後健康檢查的小型正常回應。
每個請求使用合成測試識別碼。目標端只記錄識別碼、時間戳、收發位元組數、連線狀態與結束原因。測試中不要包含代理憑證、Cookie、個人資料或真實客戶 URL。
對直接連線與每種已授權代理路線執行同一組測試。直接連線只作為診斷對照,不能成為生產備援。
涵蓋不同取消時間點
取消行為會隨時間點變化,至少測試:
- DNS 或代理連線建立完成前;
- 代理驗證或 CONNECT 協商期間;
- 收到回應標頭後、本文開始前;
- 串流下載中途;
- 有界上傳中途;
- 在用戶端並行佇列等待期間;
- 剛出現看似可重試錯誤時;
- 應用程式關閉過程中。
每次只改變一個條件,否則逾時、伺服器關閉與使用者取消會混在同一條證據裡。
在兩端蒐集證據
用戶端記錄:
test_id
route_class
cancel_requested_monotonic_ms
client_returned_monotonic_ms
bytes_sent_before_cancel
bytes_received_before_cancel
retry_count_after_cancel
active_connections_before_after
queued_requests_before_after
final_reason_code
受控目標端記錄第一個請求位元組、第一個回應位元組、最後觀察到的位元組、斷線或完成時間以及總位元組數。使用測試識別碼對應兩端事件。持續時間使用單調時鐘,跨系統關聯才使用同步 UTC。
除非確有必要、已獲授權並妥善保護,否則不要預設擷取封包。多數驗收測試可以使用應用程式、代理與測試端點計數器完成,避免蒐集無關內容。
測試下載取消
透過代理啟動慢速分塊回應。收到固定數量的資料塊後,使用執行環境支援的取消機制在應用層取消。除非測試程序結束情境,否則不要直接終止整個程序。
逐項確認:
- 用戶端報告取消,而不是把部分本文標記為成功;
- 解析器不會把不完整回應寫入資料集;
- 受控目標端在約定清理視窗內觀察到資料流結束;
- 代理活動請求或連線占用回到基線;
- 自動重試不會換一個出口 IP 重新開始;
- 已知正常路線上的小型後續請求可以成功。
可結合代理回應完整性測試,防止部分本文被誤認為完整結果。
測試上傳取消
上傳帶來另一類風險:用戶端得知最終結果前,目標端可能已經接收部分甚至全部請求。應使用可丟棄的合成物件,並讓目標端提供實際接收位元組數。
在不同上傳百分比取消。用戶端必須返回取消或結果不確定,不能假設操作已經回復。凡是存在副作用的操作,重試前應使用冪等鍵或目標端提供的狀態查詢。
不能因為代理連線關閉,就自動重複付款、表單提交或帳號變更。傳輸結果不確定不等於業務操作失敗。
驗證重試確實被抑制
許多重試程式庫會把取消誤分類為逾時、連線重設或普通網路錯誤,於是在使用者要求停止後立即建立新請求。
為任務攜帶明確的取消原因。重試層必須先判斷取消,再判斷狀態碼或例外類型。斷言明確使用者取消或排程取消後,重試次數維持為零。如果關閉策略允許稍後恢復,應建立帶新決策記錄的新任務,而不是悄悄延續舊任務。
可以使用代理 429 與重試處理指南,區分允許的瞬時恢復、取消、限速與永久失敗。
檢查連線池行為
取消不一定要關閉整條連線。HTTP/2 和 HTTP/3 可以取消一個串流,同時保留其他健康串流。HTTP/1.1 用戶端在無法安全排空本文時,可能必須關閉或丟棄連線。必須測試生產實際使用的執行環境與協定。
每次取消後測量:
- 活動與閒置連線數量;
- 並行槽位重新可用的時間;
- 連線是否返回池中;
- 後續回應的框架邊界是否正確;
- 其他進行中串流是否受到影響;
- 重複循環後的檔案描述元與記憶體變化。
不適合重用的連線必須退出池。重用仍殘留未讀回應位元組的通訊端,可能把舊位元組附到新請求上,造成下一條結果損壞。
預先定義驗收門檻
測試前確定門檻。範例契約可以要求:
- 應用程式在 250 毫秒內確認取消;
- 取消時間戳之後不出現新重試;
- 串流測試端點在 2 秒內觀察到斷線;
- 活動並行在 3 秒內回到基線;
- 寫入資料集的部分記錄為零;
- 日誌中的憑證與本文洩漏為零;
- 後續對照請求成功;
- 在服務說明的統計延遲內核對代理位元組計數。
具體數值要符合執行環境、地區和代理產品。目標是明確可重複的契約,而不是一味追求極小數字。
疑難排解矩陣
| 現象 | 優先調查方向 |
|---|---|
| 用戶端返回後目標仍在傳送 | 傳輸中止傳播與本文排空行為 |
| 取消後建立新請求 | 重試分類與任務狀態傳播 |
| 並行長時間被占用 | 連線池釋放、通道關閉與閘道計量 |
| 下一回應混入異常位元組 | 不安全的 HTTP/1.1 連線重用 |
| 上傳可能已經完成 | 冪等機制與目標狀態核對 |
| 只有一個市場清理失敗 | 地區閘道、協定或網路中間層 |
| 直接連線能清理而代理不能 | 代理通道行為,而非僅應用取消 |
上線檢查清單
- 每個任務都有穩定的合成請求識別碼。
- 取消與逾時、失敗、成功明確區分。
- 重試邏輯先判斷取消狀態。
- 部分下載絕不會作為完整資料入庫。
- 有副作用的上傳使用冪等或狀態核對。
- 連線池計數會回到基線。
- 不安全連線從重用池移除。
- 必須使用代理時禁止直接連線備援。
- 日誌排除憑證、Cookie 和原始本文。
- 服務商計量與用戶端、測試端證據互相核對。
- 按需要涵蓋 IPv4、IPv6、HTTP 代理和 SOCKS 模式。
- Global、北美、歐洲與 APAC 的結果分別審查。
常見問題
取消時應該關閉整條代理連線嗎?
不一定。多路複用協定可以只取消一個串流而不影響其他串流。驗收要求是已取消工作停止、資源釋放且相鄰請求不被破壞。
逾時和取消相同嗎?
不同。逾時是等待過久後的策略決定,取消是使用者、排程器或關閉流程發出的明確停止信號。兩者可能產生相似傳輸錯誤,但重試策略不同。
換一個代理能解決取消卡住嗎?
不能。輪替可能製造重複工作並掩蓋清理缺陷。應先修復取消傳播與資源計量。
已取消流量如何計費?
以服務商公開的計量定義為準。已經傳輸的位元組仍可能計費。應核對用戶端、代理與受控目標計數,而不是假設取消會抹去用量。
合規說明
取消測試只能針對你擁有或已獲授權的目標與代理帳號。使用合成內容、保守流量、明確清理視窗與最小化日誌。不得透過取消和輪替請求規避限速、存取控制或發布者決定。