ทำความเข้าใจ Round-robin DNS
(blog.hyperknot.com)- ผู้ดูแล OpenFreeMap นำ VPS ในหลายภูมิภาคมาผูกเป็น A record หลายรายการของซับโดเมนเดียวกันเพื่อทำ Round-robin DNS และทดลองว่าเบราว์เซอร์กับ Cloudflare เลือกเซิร์ฟเวอร์จริงอย่างไร
- แม้จะคาดหวังการกระจายโหลดและการหลบเลี่ยงความขัดข้องได้โดยไม่ต้องมี load balancer แยกต่างหาก แต่ผลลัพธ์จริงขึ้นอยู่กับวิธีจัดเรียงที่อยู่และการ retry ของไคลเอนต์อย่างมาก
- จากการทดสอบด้วย VPS 3 เครื่องในสหรัฐฯ ยุโรป และสิงคโปร์ พบว่า Chrome และ Firefox มีแนวโน้มจะเลือกเซิร์ฟเวอร์แบบสุ่มตอนเริ่มต้นแล้วคงอยู่กับเซิร์ฟเวอร์นั้น ส่วน Safari และ curl จะค่อย ๆ รวมไปที่ เซิร์ฟเวอร์ EU ที่อยู่ใกล้หลังจากส่งคำขอซ้ำหลายครั้ง
- หากบางเซิร์ฟเวอร์ออฟไลน์ เบราว์เซอร์และ curl จะสลับไปยังเซิร์ฟเวอร์สำรองอย่างรวดเร็ว แต่คำขอที่ผ่านพร็อกซี Cloudflare อาจยังใช้ origin ที่กำหนดไว้ตาม IP ของไคลเอนต์ต่อไป จนเกิด ข้อผิดพลาด 521 ได้
- หาก Cloudflare เลือก origin ที่ออฟไลน์หรือเซิร์ฟเวอร์ latency ต่ำได้ไม่ถูกต้อง การกระจายโหลดด้วย Round-robin DNS อาจพาผู้ใช้ไปยังเซิร์ฟเวอร์ที่ช้าโดยไม่เกี่ยวกับตำแหน่งของผู้ใช้
แนวคิดพื้นฐานของ Round-robin DNS
- เว็บไซต์ที่ใช้ VPS โดยทั่วไปจะเพิ่ม A record หนึ่งรายการในผู้ให้บริการ DNS เพื่อส่งทราฟฟิกไปยัง IP เฉพาะ
- Round-robin DNS คือวิธีระบุ IP ของเซิร์ฟเวอร์หลายตัวให้กับซับโดเมนเดียวกัน
- ตัวอย่างคือการตั้งค่า A record หลายรายการให้กับ
rr-direct.hyperknot.comและrr-cf.hyperknot.com
- ตัวอย่างคือการตั้งค่า A record หลายรายการให้กับ
- ในการตั้งค่านี้ สามารถคาดหวังพฤติกรรมการแบ่งโหลดไปยังหลายเซิร์ฟเวอร์ และหลีกเลี่ยงเซิร์ฟเวอร์ที่ออฟไลน์ได้
- ตั้งค่าได้กับผู้ให้บริการ DNS ส่วนใหญ่โดยไม่ต้องมี load balancer แยกต่างหาก จึงเป็นแนวทางที่เรียบง่ายและแทบไม่มีค่าใช้จ่าย
- ฟีเจอร์ load balancing ของบริการอย่าง Cloudflare อาจมีภาระค่าใช้จ่ายสูงขึ้นได้
ไคลเอนต์อาจเลือกเซิร์ฟเวอร์ตามเกณฑ์ใด
- มาตรฐานที่เกี่ยวข้องมี RFC 8305 Happy Eyeballs และ RFC 6724
- ส่วนการจัดเรียงที่อยู่ของ RFC 8305 อธิบายว่า หากไคลเอนต์ที่มีสถานะมีบันทึกเวลา round-trip time (RTT) ที่คาดไว้ของแต่ละเส้นทางที่อยู่ ก็ควรเพิ่มกฎการเลือกที่อยู่ปลายทางที่ให้ความสำคัญกับที่อยู่ที่มี RTT ต่ำกว่า
- ผู้ทดลองเข้าใจสิ่งนี้เป็นพฤติกรรมดังต่อไปนี้
- ตรวจสอบว่าเซิร์ฟเวอร์ออนไลน์หรือออฟไลน์
- จัดเรียงเซิร์ฟเวอร์ที่ออนไลน์ตาม เวลา ping
การตั้งค่าการทดลอง
- สร้าง VPS ใน 3 ภูมิภาคทั่วโลก
- สหรัฐฯ
- ยุโรป
- สิงคโปร์
- ตั้งค่า A record ที่ผ่านพร็อกซี 3 รายการและ A record ที่ไม่ผ่านพร็อกซี 3 รายการบน Cloudflare
- แต่ละเซิร์ฟเวอร์ให้โครงสร้าง response เดียวกันด้วย nginx
- คำขอทุก path ถูก rewrite เป็น
color.png /serverส่งคืน/etc/hostnameเป็นtext/plain
- คำขอทุก path ถูก rewrite เป็น
color.pngเป็นไฟล์ PNG ขนาด 1px และมีสีต่างกันตามเซิร์ฟเวอร์- US: เขียว
- EU: น้ำเงิน
- SG: แดง
- แยก hostname เป็น
test-eu,test-us,test-sg - เนื่องจากตำแหน่งทดสอบอยู่ในยุโรป พฤติกรรมที่คาดหวังคือการเลือก เซิร์ฟเวอร์ EU ที่อยู่ใกล้ที่สุด
- หน้า HTML สำหรับทดสอบ เติมรูปภาพแบบสุ่มลงในกริด 10x10 เพื่อแสดงผลการเลือกเซิร์ฟเวอร์เป็นภาพ
พฤติกรรมของแต่ละไคลเอนต์เมื่อทุกเซิร์ฟเวอร์ออนไลน์
- Chrome มีแนวโน้มเลือกหนึ่งในหลายตำแหน่งแบบค่อนข้างสุ่ม แล้วคงอยู่กับเซิร์ฟเวอร์ที่เลือกไปแล้ว
- จะประเมินการเลือกใหม่หลังผ่านไปหลายชั่วโมง
- ในการทดสอบ บางครั้งถูกตรึงอยู่กับเซิร์ฟเวอร์สิงคโปร์ที่ช้าที่สุดเป็นเวลาหลายชั่วโมง
- เมื่อไม่ใช้ HTTP/2 บางครั้งจะเลือกแบบสุ่มระหว่างสองเซิร์ฟเวอร์และสร้างแพตเทิร์นขึ้นมา
- Firefox ก็ทำงานคล้ายกับ Chrome
- เลือกตำแหน่งแบบสุ่มตอนเริ่มต้น
- หากรีสตาร์ทเบราว์เซอร์ อาจเลือกตำแหน่งสุ่มอื่นได้
- Safari เลือกเซิร์ฟเวอร์ที่ใกล้ที่สุดได้ถูกต้องเสมอ
- แม้เซิร์ฟเวอร์จะออฟไลน์ชั่วคราวแล้วกลับมา หาก refresh ไม่กี่ครั้งก็จะพบเซิร์ฟเวอร์ EU อีกครั้ง
- curl ก็ปรับกลับไปยังเซิร์ฟเวอร์ที่อยู่ใกล้ได้
- การรันครั้งแรกอาจยังไม่ใช่ แต่ถ้ารันคำสั่งสองครั้ง จะย้ายไปยังเซิร์ฟเวอร์ที่ใกล้ที่สุดเสมอ
- ในตัวอย่าง คำขอแรกเป็น
test-usและคำขอถัดไปเปลี่ยนเป็นtest-eu
พฤติกรรมเมื่อผ่านพร็อกซี Cloudflare
- Cloudflare เลือกตำแหน่งแบบสุ่มตาม IP ของไคลเอนต์ แล้วใช้ตำแหน่งเดิมต่อไป
- พฤติกรรมที่สังเกตได้คล้ายกับ
client_ip_hash modulo server_num - จาก IP ที่บ้าน ไม่ว่าจะปรับอย่างไร Cloudflare ก็เชื่อมไปยังเซิร์ฟเวอร์สหรัฐฯ
- ผลลัพธ์ของ
curl https://rr-cf.hyperknot.com/serverออกมาเป็นtest-us
- ผลลัพธ์ของ
- เมื่อใช้ mobile hotspot จะเชื่อมไปยังเซิร์ฟเวอร์ EU เสมอ
- เมื่อรันคำสั่ง curl เดียวกันจาก VPS หลายเครื่อง แต่ละ VPS จะเชื่อมต่อไปยังตำแหน่งสุ่มทั่วโลก แต่ใช้เซิร์ฟเวอร์เดิมเสมอ
- ผลลัพธ์ตัวอย่างคือ
test-sg
- ผลลัพธ์ตัวอย่างคือ
ความแตกต่างเมื่อบางเซิร์ฟเวอร์ออฟไลน์
- หยุด nginx บนเซิร์ฟเวอร์สหรัฐฯ ด้วย
service nginx stopแล้วตรวจสอบพฤติกรรม - Chrome, Firefox, Safari และ curl ทั้งหมดตรวจจับเซิร์ฟเวอร์ที่ออฟไลน์และเลือกเซิร์ฟเวอร์อื่น
- แม้ปิดเซิร์ฟเวอร์ระหว่างโหลด การเชื่อมต่อสำรอง ก็ทำงานรวดเร็วมากจนปรับได้ภายในไม่ถึง 1 วินาที
- Cloudflare ตรวจจับเซิร์ฟเวอร์ที่ออฟไลน์ไม่ได้
- สำหรับ IP ของไคลเอนต์ จะเข้าถึงเซิร์ฟเวอร์ที่กำหนดไว้ครั้งแรกต่อไปโดยไม่สนใจว่าออนไลน์หรือไม่
- หากเซิร์ฟเวอร์นั้นออฟไลน์ ผู้ใช้จะได้รับข้อผิดพลาด
- ผลลัพธ์ curl คือ
error code: 521
ข้อสงสัยและข้อจำกัดเกี่ยวกับ Cloudflare
- มองว่าพฤติกรรมที่ Cloudflare ตรวจจับ origin ที่ออฟไลน์ไม่ได้ มีความเป็นไปได้สูงว่าเป็น บั๊ก ของเครือข่าย
- อ้างอิงจาก zero downtime failover ในเอกสารของ Cloudflare จึงเห็นว่าควรทำงานเหมือนเบราว์เซอร์และ curl
- อย่างน้อยที่สุด เซิร์ฟเวอร์ที่ออฟไลน์ควรถูกตรวจจับได้
- หากเลือกเซิร์ฟเวอร์ที่มี latency ต่ำที่สุดได้เหมือน Safari จะยิ่งดีกว่า
- ด้วยพฤติกรรมปัจจุบัน หากมีเซิร์ฟเวอร์สหรัฐฯ 1 เครื่องและเซิร์ฟเวอร์นิวซีแลนด์ 1 เครื่อง ผู้ใช้ในสหรัฐฯ 50% อาจได้รับ response จากเซิร์ฟเวอร์นิวซีแลนด์
- ผู้ใช้ Safari อาจช้าลงเมื่อใช้ Cloudflare เมื่อเทียบกับตอนไม่ใช้ Cloudflare
- ใน การอภิปรายบน HN ที่เกี่ยวข้อง CEO และ CTO ของ Cloudflare ได้ตอบกลับ
- ผู้ทดลองยังถามด้วยว่ามีแพลตฟอร์ม serverless ที่รองรับ HTTPS และ Round-robin DNS โดยไม่ต้องเสียค่า VPS 3 เครื่องทั่วโลกหรือไม่ เพื่อให้การทดลองทำงานต่อไปได้
1 ความคิดเห็น
ความคิดเห็นบน Hacker News
อืม ผมได้ขอให้ ทีม DNS ที่มีสิทธิ์กำหนดระเบียน อธิบายแล้วว่าที่นี่เกิดอะไรขึ้น
ถ้าได้คำตอบที่แน่ชัดจะมาแจ้งใน HN ครับ ผมไม่ได้ดูโค้ดมาหลายปีแล้ว และระหว่างนั้นก็มีคนจำนวนมากแก้ไขต่อเนื่องมา :-)
เดาว่าน่าจะเกี่ยวกับพฤติกรรมที่พยายามรักษา ความชอบระหว่าง IP ของไคลเอนต์กับเซิร์ฟเวอร์แบ็กเอนด์ ตามที่ผู้เขียนกล่าวถึงในบล็อก คำถามหลักคือ “ถ้าเซิร์ฟเวอร์แบ็กเอนด์ล่ม ควรทำลายความชอบนั้นไหม” ถ้ารู้เพิ่มเติมจะมาตอบต่อในคอมเมนต์ของผม
หนึ่งในวิธีแก้ยุคแรกของปัญหานี้คือ ระเบียน DNS แบบ SRV คล้ายกับระเบียน MX แต่ตั้งใจให้ใช้ได้กับบริการทุกชนิด ไม่ใช่แค่อีเมล
ในระเบียน MX และ SRV สามารถระบุรายการเซิร์ฟเวอร์ที่ไคลเอนต์ควรลองและลำดับความสำคัญได้ และ SRV ยังมีพารามิเตอร์
weightสำหรับ load balancing ด้วย แต่ SRV ถูกกำหนดให้ใช้เฉพาะเมื่อมาตรฐานของโปรโตคอลนั้นระบุการใช้ SRV ไว้เท่านั้น เพื่อหลีกเลี่ยงการต่อสู้ทางการเมืองที่ในทางปฏิบัติต้องไปแทรกแซงโปรโตคอลมาตรฐานทั้งหมดให้ไคลเอนต์ทุกตัวตรวจ SRV ผลคือในเชิงเทคนิค ไคลเอนต์ HTTP จึงใช้ SRV ไม่ได้ ต่อมาเมื่อสร้าง HTTP/2 และมาตรฐาน HTTP รุ่นถัด ๆ มา ก็ยังไม่สามารถระบุ SRV ไว้ในโปรโตคอล HTTP ใหม่ได้ เพราะเหตุผลที่ไม่เหมาะสมจาก Google และรายอื่น ๆ SRV แทบจะตายไปแล้วสำหรับการพัฒนาใหม่ ๆ และดูเหมือนใช้กันเฉพาะในมาตรฐานเก่าบางตัวเท่านั้นทางแก้ load balancing แบบใหม่ดูเหมือนจะเป็น ระเบียน DNS แบบ HTTPS และ SVCB เท่าที่เข้าใจ คือถูกทำให้เป็นมาตรฐานโดยคนที่ต้องการใส่พารามิเตอร์เพิ่มเติมใน DNS เพื่อเริ่ม TLS 1.3 handshake ให้เร็วขึ้นและลดจำนวนรอบไปกลับ ประเภทระเบียน SVCB เหมือน HTTPS แต่เป็นรูปแบบทั่วไปแบบ SRV ใน HTTPS และ SVCB มีพารามิเตอร์ลำดับความสำคัญแบบเดียวกับ SRV และ MX แต่ไม่มีพารามิเตอร์
weightของ SRV มาตรฐานเผยแพร่แล้ว และดูเหมือนเบราว์เซอร์บางตัวรองรับแล้ว แต่ยังไม่ใช่ทุกเจ้าที่เปิดใช้ ต้องรอดูว่าในอนาคตอันใกล้เบราว์เซอร์จะทำจริงอย่างไรไม่ต้องใช้ทริก CNAME flattening ที่อาจก่อปัญหา routing ใน CDN ที่ใช้ GeoDNS ร่วมกับ anycast หรือใช้แทน anycast ถ้าคุณเคยเห็นแพลตฟอร์มบางแห่งแนะนำให้ใช้ซับโดเมน
wwwแทน apex domain นี่คือเหตุผล และเป็นหนึ่งในเหตุผลที่ Akamai ผลักดันการทำมาตรฐานระเบียน HTTPS เพราะ Akamai ใช้ GeoDNSการไม่มีระเบียนแบบนี้เจ็บเป็นพิเศษ เพราะผู้คนมักอยากโฮสต์เว็บไซต์ไว้ที่ domain apex อย่างไรก็ตาม ถ้าพึ่งพา DNSSEC ไม่ได้ การใช้ระเบียนสไตล์ MX อย่างปลอดภัยก็อาจยุ่งยาก
DNS load balancing มี edge case ที่สกปรกมากจริง ๆ ผมเคยรับมือสถานการณ์ที่ไคลเอนต์ Go HTTP/2 ใช้ round-robin DNS แล้วเกิดปัญหา
ไคลเอนต์ Go HTTP/2 จะใช้เซิร์ฟเวอร์ตัวแรกที่เชื่อมต่อได้ซ้ำไปเรื่อย ๆ และไม่ resolve DNS ใหม่ ทำให้แม้เพิ่มเซิร์ฟเวอร์ใหม่เข้า pool ไคลเอนต์ก็อาจไม่พบเซิร์ฟเวอร์ใหม่
กรณีที่เลวร้ายเป็นพิเศษคือเมื่อแบ็กเอนด์ทั้งหมดล่ม แล้วแบ็กเอนด์ตัวแรกตัวเดียวกลับมาออนไลน์ ไคลเอนต์ทั้งหมดจะยึดติดกับเซิร์ฟเวอร์นั้นและไม่ย้ายไปไหน แม้เซิร์ฟเวอร์อื่น ๆ จะกลับมาแล้ว ก็แทบไม่มีไคลเอนต์ที่เชื่อมต่อใหม่ เพราะเชื่อมกับเซิร์ฟเวอร์แรกไปแล้ว
ใน
grpc-goก็เกิดปัญหาคล้ายกัน ตัว resolver DNS ของ gRPC จะ resolve ใหม่เฉพาะเมื่อการเชื่อมต่อกับแบ็กเอนด์ขาด ดังนั้นไคลเอนต์ gRPC อาจไปรวมติดอยู่ที่โฮสต์เดียวแล้วค้างอยู่แบบนั้น มีข้อเสนอให้ตั้งค่าMAX_CONNECTION_AGEฝั่งเซิร์ฟเวอร์ เพื่อให้ตัดไคลเอนต์เป็นระยะหลังผ่านไประยะหนึ่ง และบังคับให้ไคลเอนต์ resolve DNS ใหม่อยากให้มีวิธีมาตรฐานที่ดีกว่าสำหรับ service discovery สุดท้ายสิ่งที่ทำได้ดีที่สุดดูเหมือนจะเป็นการทำ load balancer แบบต่อคำขอโดยอิง virtual IP แล้วให้ load balancer ทำ health check แต่สิ่งนี้ก็เป็นแค่การผลักปัญหาไปให้ระบบที่ implement virtual IP เท่านั้น ดูเหมือนจะตั้งสมมติฐานว่าระบบ routing ค่อนข้างคงที่กว่าแบ็กเอนด์ และประโยชน์ก็เกิดจากตรงนั้น
สงสัยเหมือนกันว่าบน bare metal เขาทำกันอย่างไร รู้ว่า AWS/GCP ฯลฯ มี internal load balancer แต่ก็อยากรู้ว่าเคล็ดลับในการ implement คืออะไร ถ้ามีบล็อกโพสต์หรือ whitepaper ที่เกี่ยวข้องแนะนำก็ยินดี
มีข้อความว่า “ถ้าเซิร์ฟเวอร์ตัวหนึ่งออฟไลน์จะเกิดอะไรขึ้น? สมมติว่าเราหยุดเซิร์ฟเวอร์ในสหรัฐฯ:
service nginx stop” แต่ไม่ควรทดสอบแบบนี้ไคลเอนต์จะเห็นว่า connection refused แล้วข้ามไป IP ถัดไป แต่ในความเป็นจริง เซิร์ฟเวอร์อาจไม่ตอบสนองเลย หรืออาจรับการเชื่อมต่อไว้แล้วเงียบก็ได้
ตอนนั้นก็ต้องพึ่งพา timeout ของไคลเอนต์ และ round-robin DNS ที่ตั้งใจเพิ่มความน่าเชื่อถือก็จะดูไม่น่าสนใจลงมากในทันที
การหยุดบริการเป็นงานที่วางแผนไว้ และในกรณีนั้นก็สามารถจัดการได้ด้วยการอัปเดต DNS ก่อน
SIG_STOPหรือDROPของip/nftablesเป็นการทดสอบที่สมจริงกว่ามากประเด็นหลักที่ยุ่งยากคือ “อย่างที่เห็น ไคลเอนต์ทุกตัวตรวจจับสิ่งนี้ได้ถูกต้องและเลือกเซิร์ฟเวอร์สำรอง” ความน่าเชื่อถือถูกตัดสินที่ฝั่งไคลเอนต์
ตัวอย่างเช่น ครั้งหนึ่ง
systemd-resolvedเคยทำงานโดยคืนค่า IP address ที่ต่ำที่สุดเสมอ โดยอ้างว่าทำให้ถูกต้องทางเทคนิคมากที่สุด เหตุผลคือ DNS round robin ไม่ได้ถูกนิยามไว้อย่างชัดเจน ดังนั้นการคืนค่า IP ต่ำที่สุดเสมอก็ไม่ได้ผิด หลังจากเกิดความวุ่นวายจึงมีการเปลี่ยนแปลง แต่เท่าที่รู้ Debian 11 เคยติดอยู่กับพฤติกรรมนั้น หรือเป็นแบบนั้นอยู่นานนอกจากนี้ ยังเจอแอปพลิเคชันจำนวนมากที่พฤติกรรมการ retry แย่มากหรือไม่มีเลย ทำงานประมาณว่า “มี connection refused หนึ่งครั้ง งั้นยกเลิกทั้งหมด ออกไป และไม่ต้องลองอีก” แบบนั้นคำขอทั้งหมด 20–30% ก็หายวับไป
ถ้าไม่มีตัวเลือกอื่น นี่ก็เป็นวิธีแก้ที่พอยอมรับได้ อย่างที่บทความบอก หากมี HTTP client คุณภาพดีแบบเบราว์เซอร์ที่ตั้งค่าให้ retry ได้หลายครั้ง DNS round robin ก็ใช้ได้ดีสำหรับการค้นหา load balancer จริงที่มี health check เป็นต้น และสามารถให้ success rate 100% ได้
แต่ DNS round robin ไม่ใช่ load balancer และ load balancer ก็ทำได้ดีกว่า
ที่ที่เคยทำงานมาก่อนมีเซิร์ฟเวอร์ DNS ภายในที่มีเรคคอร์ดหลายร้อยล้านรายการและ TTL 60 วินาที ใช้กับระบบ routing ภายในแบบปรับแต่งเองเพื่อเชื่อมต่อ connection ขาเข้าของลูกค้าไปยัง resource ที่ถูกต้องภายในเครือข่าย ซึ่งยอดเยี่ยมจริง ๆ การเปลี่ยน routing ทำได้ง่ายพอ ๆ กับการอัปเดต DDNS และใช้
NOTIFYเพื่อผลักการเปลี่ยนแปลงไปยังเซิร์ฟเวอร์ลูกทั้งหมด ทำให้ค่า delay เฉลี่ยจนสะท้อนผลครบทั้งระบบต่ำกว่า 60 วินาที สิ่งนี้ทำให้สร้างเครื่องมือที่ซับซ้อนขึ้นได้ง่าย และยังทำ control panel ที่กดปุ่มครั้งเดียวก็ถอดออกจากบริการได้ตั้งแต่เซิร์ฟเวอร์เดี่ยวไปจนถึงทั้ง data centerระบบนั้นก็มีจุดหยาบ ๆ อยู่แน่นอน แต่เมื่อเทียบกับระบบประเภทนั้นแล้ว มันเร็ว ตรวจสอบภายในได้ง่าย และค่อนข้างทนทานมาก
failover ก็เช่นกัน หาก region หนึ่งล่ม คุณอยากให้ทราฟฟิกกระจายไปยัง region อื่นอย่างสม่ำเสมอ หรืออยากให้ไหลไปรวมที่ region เพื่อนบ้านที่ใกล้ที่สุดถัดไป? ถ้าพฤติกรรมนั้นสำคัญ คุณควรรักษาอำนาจควบคุม traffic management ไว้ ไม่ใช่ยกให้คนอื่น
ทุกวันนี้ ก่อนจะไปถึงจุดที่ “ไม่มีตัวเลือกอื่น” ยังมีวิธีแก้อื่น ๆ ให้เลือกอีกมาก
หากจะจับผิดอย่างระมัดระวังเกี่ยวกับ การตรวจจับออฟไลน์อัตโนมัติของ DNS จากประโยคที่ว่า “สามารถแบ่งโหลดไปยังหลายเซิร์ฟเวอร์ และตรวจจับได้อัตโนมัติว่าเซิร์ฟเวอร์ใดออฟไลน์เพื่อเลือกเซิร์ฟเวอร์ที่ออนไลน์อยู่” นั้น round robin DNS ในสภาพพื้นฐานเหมาะใช้แค่สำหรับ load balancing เท่านั้น
หากไม่ใส่ logic ฉลาด ๆ ไว้ในไคลเอนต์ ก็ไม่มีอะไรเกิดขึ้นโดยอัตโนมัติในแง่การตรวจจับสถานะ availability บทนำของบทความพูดถึงจุดนี้อยู่บ้าง แต่ต้องอ่านหลายรอบกว่าจะเข้าใจความหมาย พูดอย่างเป็นธรรม อาจเป็นปัญหาความเข้าใจของผมเองก็ได้ พออ่านส่วนที่เหลือของบทความแล้ว ทั้งหมดก็เป็นเรื่องของ logic ฉลาด ๆ นั้นจริง ๆ
ถ้าเรคคอร์ดเซิร์ฟเวอร์ 1/N ที่เบราว์เซอร์เลือกใช้งานไม่ได้ ก็จะไม่มีการกู้คืนอัตโนมัติหรือ retry ในระดับ protocol
แถม “เรื่องสนุกที่เกี่ยวข้อง”: อย่าลืมพฤติกรรม DNS TTL [1] และ
.equals()[2] ของ Java[1] https://stackoverflow.com/questions/1256556/how-to-make-java...
[2] https://news.ycombinator.com/item?id=21765788 (5 ปีก่อน, 168 ความคิดเห็น)
มีไคลเอนต์ที่ไม่สนใจ TTL อยู่บ้าง แต่ค่อนข้างหายาก
หากเซิร์ฟเวอร์ล่ม ที่อยู่ IP ที่กระจายและถูกแคชไว้ทั่วโลกจะยังคงเหลืออยู่ และเราไม่สามารถป้องกันไม่ให้ผู้คนเข้าถึงที่อยู่นั้นได้
https://www.cloudflare.com/learning/dns/glossary/round-robin...
การกระจายโหลดย่อมมีต้นทุน และยังมีปัญหาที่ load balancer ทำให้การเชื่อมต่อเสียแบบละเอียดอ่อนหรือชัดเจนด้วย เคยมีผู้ให้บริการบางรายที่ความพร้อมใช้งานของ load balancer แย่กว่าโฮสต์ของเราเองด้วยซ้ำ
หากควบคุมไคลเอนต์ได้ วิธีเรียกใช้ DNS API ของแพลตฟอร์มเพื่อรับรายการ IP แล้วสลับลำดับและวนใช้อย่างเหมาะสมก็สมเหตุสมผล หากสามารถใส่ IP ที่จัดสรรไว้อย่างเสถียรสักสองสามรายการไว้ในไบนารีของไคลเอนต์เพื่อเตรียมไว้กรณี DNS เสียได้ก็ยิ่งดี แต่โดยปกติ DNS ไม่ได้เสีย และเหมาะสำหรับใช้เปลี่ยนแปลงการปฏิบัติการโดยไม่ต้องเผยแพร่การตั้งค่าใหม่หรือไบนารีใหม่ทุกครั้งที่อัปเดตคลัสเตอร์
หากไคลเอนต์เป็นเบราว์เซอร์ พฤติกรรมเริ่มต้นถือว่าใช้ได้พอสมควร โดยปกติจะใช้ IP ตามลำดับ จึงอาจเป็นปัญหาได้ [1] แต่นอกเหนือจากนั้น พฤติกรรมการลองใหม่ค่อนข้างดี หากถูกปฏิเสธการเชื่อมต่อก็จะลอง IP อื่นทันที และหากหมดเวลาก็จะลอง IP อื่นอย่างน้อยสองสามรายการ แม้จะไม่สมบูรณ์แบบ ดังนั้นสำหรับเบราว์เซอร์ผมคงใช้ load balancer และถ้าเป็นไปได้อย่างน้อยก็คงใช้กับการโหลดหน้าแรก ส่วนสำหรับ WebSocket เป็นต้น อาจใช้ DNS round robin ร่วมกับลอจิกไคลเอนต์ JS ที่ฉลาดในระดับหนึ่งได้ ถึงอย่างนั้น การใช้ DNS round robin กับทั้งไซต์ก็ยังเป็นไปได้
หากไคลเอนต์ไม่ใช่เบราว์เซอร์และผมก็ควบคุมไม่ได้ ก็ได้แต่หวังว่าจะโชคดี
ยอมรับ 100% ว่าบางครั้งเราต้องตั้งสมมติฐานว่ามีใครสักคนสร้างตัวแก้ชื่อ DNS แบบแคชโดยตีความฟิลด์ TTL เป็นจำนวนวัน ไม่ใช่วินาที ไคลเอนต์ที่อยู่หลังตัวแก้ชื่อแบบนั้นจะมีปัญหาเมื่ออัปเดต DNS แต่ถ้า load balancer อยู่หลังชื่อ DNS และถึงเวลาที่ต้องเปลี่ยนที่อยู่นั้น คุณก็จะเจอปัญหานั้นอยู่ดี และตอนนั้นก็จะไม่มีประสบการณ์ด้วย
[1] RFC ฉบับหนึ่งเสนอว่า OS API ควรจัดเรียงคำตอบตามการจับคู่ prefix หาก prefix ของ IP เป็นลำดับชั้นและเป็นตัวแทนสำหรับการเลือกเซิร์ฟเวอร์ที่มีระยะทางเครือข่ายใกล้ที่สุด ก็อาจฟังขึ้น แต่ในโลกจริง
/24ที่อยู่ติดกันในเชิงตัวเลขมักไม่ได้อยู่ใกล้กันในเครือข่าย หากที่อยู่เซิร์ฟเวอร์กระจัดกระจายมาก คุณอาจเห็นทราฟฟิกจาก IP ไคลเอนต์บางส่วนไหลไปหา IP เซิร์ฟเวอร์ที่คล้ายกันในเชิงตัวเลขแน่นอนว่าย่อมมีบางคนที่ตั้งค่า DNS ภายในเครื่องผิดหรือใช้ไคลเอนต์ที่ไม่ดี ต้องยอมรับความขัดข้องสำหรับคนที่มีการตั้งค่าพัง ๆ หรือไม่ก็ต้องจัดสรร IP ใหม่ไปยังเซิร์ฟเวอร์อื่นในดาต้าเซ็นเตอร์เดียวกัน
สวัสดีครับ ผมเป็น CTO ของ Cloudflare เราได้ปล่อยการเปลี่ยนแปลงไปยังบัญชีฟรีทั้งหมดของ Cloudflare เพื่อให้มีพฤติกรรมเหมือนกับบัญชีแบบชำระเงินแล้ว
ปัญหาที่กล่าวถึงตรงนี้ได้รับการแก้ไขแล้ว และ Zero Downtime Failover ควรทำงานได้กับบัญชีทุกประเภท ลองทดสอบอีกครั้งได้ไหมครับ?
ขอบคุณที่เขียนสรุปไว้เป็นบทความ ดีใจที่เราสามารถเปลี่ยนพฤติกรรมนี้ให้ทุกคนได้
ผมจะอัปเดตบทความให้สอดคล้องกัน ขอบคุณที่ทำให้ใช้ได้กับบัญชีฟรีด้วย เป็นผลลัพธ์ที่ยอดเยี่ยม
เวอร์ชันรีมิกซ์ด้านมืดของสิ่งนี้คือ fast flux hosting และเป็นวิธีที่ผู้ให้บริการ bulletproof hosting จำนวนมากใช้
https://unit42.paloaltonetworks.com/fast-flux-101/
อาจควรกล่าวว่า การสลับระบบเมื่อเกิดเหตุขัดข้องแบบไม่หยุดให้บริการ เป็นฟีเจอร์สำหรับ Pro ขึ้นไป
ผมจำได้ว่าเมื่อก่อน ตอนที่เอกสารการป้องกัน origin server ยังแยกตามระดับแพ็กเกจ ก็มีการระบุไว้แบบนั้น ดังนั้นพฤติกรรมหรือการลองใหม่จึงอาจดูแตกต่างกัน