พื้นหลัง
ฉันมีบอทที่ไม่ลงรอยกันเป็นเวลานาน (3 ปีขึ้นไป) เขียนไว้ discord.py
ซึ่งทำงานบน GCP เสมอ โซน us-east4-a บอทวิ่งเข้ามา k8s
ใช้ discord.py 1.7.2 และ python 3.9
ปัญหา
ในหนึ่งหรือสองเดือนที่ผ่านมา ฉันเริ่มเห็นการหยุดชะงักของการเชื่อมต่อจำนวนมากขึ้น [ข้อผิดพลาด 104] การเชื่อมต่อถูกรีเซ็ตโดยเพียร์ การรีเซ็ตไม่ได้เชื่อมโยงโดยตรงกับจำนวนกิจกรรมบนบอท เกิดขึ้นเป็นระยะๆ ตลอดทั้งวันในการผลิต (โดยเฉลี่ยทุกๆ สองสามนาที)
การรีเซ็ตเหล่านี้ทำให้เกิดความล้มเหลวแบบสุ่มกับ HTTP API ที่ไม่ลงรอยกัน และส่งผลให้มีการตัดการเชื่อมต่อในระดับสูงบน WebSocket การตัดการเชื่อมต่อชิ้นส่วนเหล่านี้จำนวนมากสามารถดำเนินการต่อได้ แต่หลายครั้ง (ประมาณ 200 ครั้งต่อวัน) จบลงด้วยการเรียก IDENTIFY เช่น การเชื่อมต่อใหม่
ตัวอย่าง
นี่คือตัวอย่างการตัดการเชื่อมต่อ:
Traceback (การโทรครั้งล่าสุดล่าสุด):
ไฟล์ "/opt/venv/lib/python3.9/site-packages/discord/shard.py", บรรทัด 187 ในการเชื่อมต่อใหม่
self.ws = รอคอย asyncio.wait_for(coro, หมดเวลา=60.0)
ไฟล์ "/usr/local/lib/python3.9/asyncio/tasks.py", บรรทัด 481 ใน wait_for
ส่งคืน fut.result()
ไฟล์ "/opt/venv/lib/python3.9/site-packages/discord/gateway.py", บรรทัด 305 ใน from_client
เกตเวย์ = เกตเวย์หรือรอลูกค้า http.get_gateway()
ไฟล์ "/opt/venv/lib/python3.9/site-packages/discord/http.py", บรรทัด 967 ใน get_gateway
ข้อมูล = รอ self.request (เส้นทาง ('GET', '/ เกตเวย์'))
ไฟล์ "/opt/venv/lib/python3.9/site-packages/discord/http.py", บรรทัด 192 ตามคำขอ
async กับ self.__session.request (เมธอด, url, **kwargs) เป็น r:
ไฟล์ "/opt/venv/lib/python3.9/site-packages/aiohttp/client.py", บรรทัด 1117 ใน __aenter__
self._resp = รอ self._coro
ไฟล์ "/opt/venv/lib/python3.9/site-packages/aiohttp/client.py", บรรทัด 544 ใน _request
รอ resp.start (คอน)
ไฟล์ "/opt/venv/lib/python3.9/site-packages/aiohttp/client_reqrep.py" บรรทัด 890 ในการเริ่มต้น
ข้อความ payload = wait self._protocol.read() # ประเภท: เพิกเฉย
ไฟล์ "/opt/venv/lib/python3.9/site-packages/aiohttp/streams.py", บรรทัด 604 ในการอ่าน
รอตัวเอง._waiter
aiohttp.client_exceptions.ClientOSError: [Errno 104] การเชื่อมต่อถูกรีเซ็ตโดยเพียร์
การทดลองเพื่อแยกปัญหา
ฉันทำการทดลองเพื่อแยกสาเหตุของปัญหา ฉันปรับใช้คอนเทนเนอร์กับบอตของฉันกับ VM (ไม่ใช่ k8s
) และแยกมันออกเพื่อให้สื่อสารกับความไม่ลงรอยกันเท่านั้น (ไม่มีฐานข้อมูลภายนอก) และส่งคำสั่งโดยอัตโนมัติเพื่อจำลองพฤติกรรมของผู้ใช้และโหลด (ฉันส่งประมาณ 60 คำสั่งต่อนาทีในเซิร์ฟเวอร์เดียวกัน -- ภายใต้ภาระการผลิตของฉัน) ฉันรันสิ่งนี้เป็นเวลา 20 นาทีหรือจนกว่าฉันจะสังเกตเห็นว่ามีการรีเซ็ตการเชื่อมต่อหรือไม่ และฉันเห็นสิ่งต่อไปนี้:
- ใน
เรา-ตะวันออก4-ก
ฉันสามารถทำซ้ำการรีเซ็ตการเชื่อมต่อเป็นระยะได้
- ใน
เรา-ตะวันออก4-ข
ฉันสามารถทำซ้ำการรีเซ็ตการเชื่อมต่อเป็นระยะได้
- ใน
เรา-ตะวันออก4-ค
ฉันสามารถทำซ้ำการรีเซ็ตการเชื่อมต่อเป็นระยะได้
- ใน
เรา-central1-ก
, ฉัน ไม่สามารถทำซ้ำการรีเซ็ตการเชื่อมต่อใดๆ (แม้จะผ่านไปแล้ว 3 ชั่วโมง -- ไม่มีการถอดชิ้นส่วนใดๆ เลย)
- ใน
เรา-ตะวันออก1-ข
, ฉัน ไม่สามารถทำซ้ำการรีเซ็ตการเชื่อมต่อใดๆ.
- บนแล็ปท็อปของฉัน (อินเทอร์เน็ตที่อยู่อาศัยบนชายฝั่งตะวันออก) ฉันเป็น ไม่สามารถทำซ้ำการรีเซ็ตการเชื่อมต่อใดๆ.
การทดลองทั้งหมดใช้คอนเทนเนอร์เดียวกัน ประเภทเครื่องเดียวกัน และขั้นตอนการทดสอบเดียวกัน
ฉันทำการทดลองซ้ำใน เรา-ตะวันออก4-ก
ด้วยเครื่องหลายประเภทสูงสุด 8 vCPU และทั้งระดับเครือข่ายพรีเมียมและมาตรฐาน และฉันยังคงเห็นการรีเซ็ต ฉันยังลองใช้ VM อื่นในโครงการอื่น แต่ปัญหาการเชื่อมต่อยังคงมีอยู่เสมอ เรา-ตะวันออก4
.
ฉันเปิดกรณีการสนับสนุนด้วย GCP เนื่องจากดูเหมือนว่าจะเป็นปัญหาเฉพาะภูมิภาค
มีการทดลองเพิ่มเติมใดบ้างที่ฉันสามารถทำได้เพื่อพยายามจำกัดสาเหตุของสิ่งนี้ให้แคบลง มีปัญหาการกำหนดค่า GCP ทั่วไปที่อาจส่งผลให้เกิดปัญหานี้หรือไม่
ฉันไม่ย้ายไปภูมิภาคอื่น ฉันรู้สึกราวกับว่าฉันไม่มีทางเลือก