เรามีปัญหาเกี่ยวกับเครือข่ายที่ดูเหมือนจะซับซ้อน ซึ่งฉันได้ต่อสู้มาระยะหนึ่งแล้วและสงสัยว่ามีใครคิดอย่างไร
เรามีเซิร์ฟเวอร์จำนวนหนึ่งนั่งอยู่ใน AWS London และเซิร์ฟเวอร์อีกชุดหนึ่งนั่งอยู่ใน CoLos ในลอนดอนและแฟรงก์เฟิร์ต
เราเชื่อมต่อจาก AWS กับ CoLos เหล่านี้โดยใช้ AWS DirectConnect
เซิร์ฟเวอร์ AWS ส่วนใหญ่เชื่อมต่อกับเซิร์ฟเวอร์ CoLo โดยใช้ PGSQL โดยเซิร์ฟเวอร์ CoLo จะโฮสต์ฐานข้อมูล แบบสอบถามจะดำเนินการกลับไปกลับมาตลอดทั้งวัน
เซิร์ฟเวอร์ CoLo ยังส่งข้อมูลจำนวนมากกลับไปยัง AWS ในรูปแบบของ Rsync และ Elastic เราไม่เคยเห็นปัญหาใด ๆ กับ Rsync หรือ Logstash ที่พุชไปยัง Elastic
โดยทั่วไปแล้วทุกอย่างทำงานได้ดี ยกเว้นการสืบค้น PGSQL ประเภทใดประเภทหนึ่งค้างระหว่าง AWS และ CoLo
ผ่านไฟล์ PCAP เราเห็นสิ่งต่อไปนี้:
- สำหรับเซสชันส่วนใหญ่ เซิร์ฟเวอร์ (CoLo) ส่งข้อมูล 1460 ไบต์ และไคลเอ็นต์ (AWS) ACK ข้อมูลนั้น สิ่งนี้ดำเนินการไปมาโดยไม่มีปัญหา
- จากนั้นเราจะเห็นเซิร์ฟเวอร์ส่งระหว่าง 5-20 ส่วนที่ไม่ถึงไคลเอนต์การลดลงนี้อาจอยู่ที่ใดก็ได้เนื่องจากเส้นทางเครือข่ายต้องผ่านผู้ให้บริการ 2-3 รายและ DirectConnect
- จากนั้นไคลเอ็นต์จะเริ่มการตอบกลับจนถึงเซ็กเมนต์สุดท้ายที่ได้รับอย่างถูกต้อง
- เมื่อถึงเวลาที่เซิร์ฟเวอร์ได้รับ ACK ซึ่งบ่งชี้ว่าแพ็กเก็ตสูญหาย เซิร์ฟเวอร์ได้ส่งอีก 10-20 เซ็กเมนต์
- ในที่สุด เซิร์ฟเวอร์จะเริ่มส่งเซ็กเมนต์ที่พลาดครั้งแรกอีกครั้ง ซึ่งได้รับและ ACKed ทันที
- จากนั้นเซิร์ฟเวอร์จะส่งเซกเมนต์ "ปัจจุบัน" สองเซ็กเมนต์กลับไปกลับมา แต่ไคลเอ็นต์ ACKs อีกครั้งที่บอกว่ายังไม่ถูกจับ
- ณ จุดนี้ เซิร์ฟเวอร์จะเริ่มการย้อนกลับแบบเอ็กซ์โปเนนเชียลระหว่างการส่งเซ็กเมนต์ "ปัจจุบัน" และเซ็กเมนต์เก่าจนกว่าจะถึงช่องว่าง 120 วินาที
- ทำซ้ำขั้นตอนดังนี้:
- เซิร์ฟเวอร์ส่งส่วนที่ขาดหายไปล่าสุด
- ลูกค้าตอบรับส่วนนี้ทันที
- เซิร์ฟเวอร์ส่งสองส่วน "ปัจจุบัน" ติดต่อกันอย่างรวดเร็ว
- ไคลเอนต์ ACKs เหล่านี้ด้วย ACK เดียวกันกับขั้นตอนที่ 2
- เซิร์ฟเวอร์ถอยออกอย่างทวีคูณและกลับไปที่ขั้นตอนที่ 1 (ช่องว่างเพิ่มขึ้นจนกว่าจะถึง 120 วินาที)
- ในที่สุดหลังจากผ่านไปนานพอ (บางครั้งอาจถึงหนึ่งชั่วโมง) เซิร์ฟเวอร์จะสามารถส่งเซ็กเมนต์ที่หายไปทั้งหมดอีกครั้งและดำเนินการต่อได้ตามปกติ
ควรสังเกตสิ่งต่อไปนี้:
- ไม่ได้อยู่ที่จุดใดในการจับภาพคือชุดขนาด Zero Window ในความเป็นจริงระหว่างการกู้คืนไคลเอนต์จะเพิ่มหน้าต่างประมาณ 6 ไบต์ทุกๆ ACK
- การรัน netstat ไม่แสดงการรับหรือส่งการเข้าคิวระหว่างเหตุการณ์
- การเรียกใช้คำสั่ง "ss" ดูเหมือนว่าจะแสดงการเปิดใช้งานอัลโกการหลีกเลี่ยงความแออัดของลูกบาศก์
เห็นได้ชัดว่าการสูญเสียแพ็กเก็ตใดๆ นั้นไม่เหมาะ แต่คำถามของฉันคือแน่นอนว่านี่ไม่ใช่พฤติกรรมที่ถูกต้อง ใน 10-20 ส่วนที่สูญหายนั้นใช้เวลาถึงชั่วโมงในการกู้คืน
สิ่งนี้ดูเหมือนปัญหาของเรามาก: https://engineering.skroutz.gr/blog/uncovering-a-24-year-old-bug-in-the-linux-kernel/ ฉันอาจพูดคุยกับโฮสต์เซิร์ฟเวอร์ CoLo ของเราและดูเกี่ยวกับการอัปเกรดเคอร์เนล