HTTPX PoolTimeout ไม่ใช่การหมดเวลาเชื่อมต่อพร็อกซี
แยกให้ออกว่ารอในพูล HTTPX และคืนทรัพยากรของคำตอบสตรีม ก่อนเปลี่ยนพร็อกซีที่อาจยังไม่เคยได้รับคำขอถัดไป
PoolTimeout หมายถึง HTTPX ดึงการเชื่อมต่อจากพูลไม่ได้ภายในเวลารอที่ตั้งไว้ ไม่ใช่หลักฐานว่าการเชื่อมต่อ TCP ใหม่ไปพร็อกซีหมดเวลา คำขอที่สองอาจยังรออยู่ภายในโปรเซสของคุณ
ทำให้เกิดซ้ำได้ง่ายเมื่อไคลเอนต์อนุญาตเพียงหนึ่งการเชื่อมต่อและคำตอบสตรีมแรกถูกเปิดค้างไว้ การเริ่มคำขอใหม่ไม่ได้คืนการเชื่อมต่อนั้นเอง
ทำให้ชัดว่าใครรับผิดชอบคำตอบสตรีม
import httpx
limits = httpx.Limits(
max_connections=1,
max_keepalive_connections=1,
)
timeout = httpx.Timeout(
connect=5, read=10, write=10, pool=1
)
with httpx.Client(
proxy="http://203.0.113.10:8080",
trust_env=False,
limits=limits,
timeout=timeout,
) as client:
with client.stream("GET", "https://example.com/") as response:
print(response.status_code)
for chunk in response.iter_bytes():
print(len(chunk))
next_response = client.get("https://example.com/")
print(next_response.status_code)
แทนที่ที่อยู่พร็อกซีตัวอย่างในเอกสารก่อนรัน คำขอถัดไปเริ่มหลังออกจากบริบทของสตรีม การออกนั้นปิดคำตอบแม้โค้ดหยุดลูปหรือเกิดข้อยกเว้น
เมื่อสตรีมแบบจัดการเอง เช่น client.send(request, stream=True) โค้ดของคุณรับผิดชอบการปิดในท้ายที่สุด สำหรับ AsyncClient ต้องรอการเก็บกวาดเองที่สอดคล้องกันด้วย response.aclose() การปิดคำตอบที่ยังไม่ได้อ่านคืนความจุ แต่บางครั้งต้องทิ้งการเชื่อมต่อด้านล่างแทนนำกลับมาใช้ซ้ำ
อ่านชื่อข้อยกเว้น
ConnectTimeout เกี่ยวกับการสร้างการเชื่อมต่อ ReadTimeout เกี่ยวกับการรอข้อมูลคำตอบ PoolTimeout เกี่ยวกับการได้ช่องการเชื่อมต่อ การบันทึกแค่ «พร็อกซีหมดเวลา» ทำให้เสียความต่างที่ใช้เลือกวิธีแก้
ตรวจคำตอบที่เปิดอยู่ งานพร้อมกัน และขีดจำกัดการเชื่อมต่อก่อนเปลี่ยน IP จุดเชื่อมต่อ พูลที่ใหญ่ขึ้นอาจเหมาะกับภาระงานพร้อมกันที่สมเหตุสมผล แต่ไม่แก้คำตอบที่ไม่เคยปิด เพียงให้แอปมีความจุมากขึ้นให้ครอบครอง
เก็บไคลเอนต์ไว้ใช้ซ้ำตลอดภาระงาน การสร้างไคลเอนต์ใหม่เพื่อให้แต่ละคำขอดูเหมือนทำงานได้อาจซ่อนปัญหาวงจรชีวิต และเสียการนำการเชื่อมต่อกลับมาใช้ซ้ำ