ในระบบงานมักจะมีการติดต่อสื่อสารระหว่างระบบหรือ service
ผ่านระบบ network ที่ขึ้นชื่อว่า พร้อมพัง ได้เสมอ
ดังนั้นในการออกแบบ พัฒนา และ ทดสอบระบบ
ต้องทำให้มั่นใจว่าการติดต่อสื่อสารจะต้องทำงานตามที่เราต้องการเสมอ
ทั้งการทำงานให้เสร็จ
ทั้งการทำงานอย่างไรเมื่อเกิดปัญหาขึ้นมา
เพื่อให้ระบบงานมีความน่าเชื่อถือมากยิ่งขึ้น

โดยรูปแบบยอดนิยมของการจัดการ ​​มีดังนี้​

  • Timeout
  • Retry
  • Circuit braker
  • Bulkhead

แบบที่ 1 Timeout

เป็นรูปแบบที่ถูกใช้งานมากที่สุด
เพราะว่า service หรือ ระบบปลายทาง อาจจะเกิดปัญหาขึ้นมา
ส่งผลให้ตอบกลับได้ช้ากว่าปกติ
ดังนั้นเพื่อป้องกันการทำงานที่นาน หรือใช้ resource มากจนเกินไป
จึงทำการกำหนด timeout ของการใช้งานไว้
เมื่อถึง timeout ก็จะตัดการเชื่อมต่อ หรือ คืน resource ให้ระบบกลับไป

ยกตัวอย่างการใช้งาน Database connection pool
หรืออาจจะเป็น network connection

ดังนั้นทางผู้เรียกใช้งานจะได้ระบบผลกลับมาว่า Connection timeout
จากนั้นก็ต้องจัดการว่าจะทำอย่างไรต่อไป

คำถามที่น่าสนใจคือ
ระบบปลายทางยังมีปัญหาแล้ว request อื่น ๆ ยังจะเรียกอีกหรือ ?

แบบที่ 2 Retry

เป็นอีกรูปแบบที่ถูกใช้งาน เพื่อแก้ไขปัญหาที่เกิดจากความผิดพลาด
อาจจะไม่เรียกว่าเป็นการแก้ไขปัญหา
แต่เป็นวิธีการที่จะทำต่อ หลังจากการทำงานมีปัญหา

ยกตัวอย่างเช่น เกิด timeout หรือ ระบบล่ม ขึ้นมา
ดังนั้นทางฝั่งคนเรียกใช้ ก็ต้องจัดการต่อไป
การ retry คือการทำซ้ำไปเรื่อย ๆ ตามจำนวนครั้ง และ interval ที่กำหนด
ทำไปจนกว่าจะทำงานสำเร็จ !!
มักจะเจอบ่อยกับงานที่เป็น batch job
หรือเป็นพวกระบบ messaging นั่นเอง

คำถามที่น่าสนใจคือ
ระบบปลายทางยังมีปัญหายังจะ retry อีกหรือ ?
หรื retry กันตอนไหน ?

แบบที่ 3 Circuit breaker

เป็นอีกวิธีที่ได้รับความนิยมในปัจจุบัน
แต่หลาย ๆ คนไม่รู้จัก ไม่เข้าใจส่งผลให้ไม่ได้ใช้งานกัน

โดยใช้หลักการเหมือนการตัดไฟเมื่อเกิดการช๊อตขึ้นมา
ถ้าเทียบกับระบบคือ
ผู้เรียกใช้งานจะไม่เรียก service หรือ ระบบปลายทาง
เมื่อมีปัญหาตามรูปแบบที่ตกลงร่วมกันไว้ยกตัวอย่างเช่น

  • มีจำนวน concurrent user มากกว่า 1,000 คนในช่วง 1 นาที
  • มีจำนวนความผิดพลาด เช่น timeout มากกว่า 3 ครั้งในช่วง 1 นาที หรือ 10% ของ request ในช่วงเวลาหนึ่ง ๆ เป็นต้น

โดยทางผู้เรียกใช้งานจะรู้ทันทีว่าปลายทางมีปัญหา
ทำให้สามารถจัดการได้ว่า
เมื่อมี request เข้ามาหลังจากนี้จะจัดการอย่างไร
วิธีการที่ได้รับความนิยมคือ fail fast
นั่นคือ ส่งผลการทำงานที่ fail กลับไปทันที
ไม่ต้องส่ง request ไปยังปลายทาง
เป็นการลดภาระไปในตัว
พร้อมทั้งช่วยให้ service ปลายทาง สามารถ recovery กลับมาได้ง่ายขึ้น
หรืออาจจะใช้วิธีการอื่น ๆ นอกเหนือจาก fail fast เช่น

  • ส่งค่าล่าสุดที่เก็บไว้จาก database หรือ caching
  • ไปเรียก service อื่น ๆ ที่วางแผนไว้แล้ว

แบบที่ 4 Bulkhead

เป็นหลักการที่ใช้สำหรับป้องกันปัญหาที่เกิดจากระบบหนึ่งทำงานผิดพลาด
แล้วอาจจะส่งผลให้ทั้งระบบพังได้
จึงมักจะทำแผนสำรองไว้
ยกตัวอย่างเช่น Active-stand by หรือเป็น Muti-data center เป็นต้น
เมื่อเกิดปัญหาขึ้นมาที่หนึ่ง แล้วจะทำการเปลี่ยนไปใช้อีกที่โดยอัตโนมัติ
อย่าลือซ้อมบ่อย ๆ ละ !!

ยังมีแนวทางอื่น ๆ ช่วยจัดการปัญหาที่เกิดขึ้นอีก

ยกตัวอย่างเช่น Feature toggle
ทำการเปิดหรือปิด feature ของระบบได้ทันที
เพื่อลดความผิดพลาดและปัญหาอื่น ๆ ที่จะตามมา

หรือจะเป็นพวก

  • Rate limit
  • Redundancy
  • Caching
  • Boundary validation
  • Rollback

วิธีการต่าง ๆ ไม่ได้ทำให้ความผิดพลาดหายไป
แต่เป็นการลดผลที่เกิดจากความผิดพลาด
ไม่ให้มันกระทบไปทั้งระบบ
ไม่ให้กระทบกับผู้ใช้งานโดยรวม

ความผิดพลาดเกิดขึ้นได้
แต่เราต้องเรียนรู้ที่จะปรับปรุงและจัดการมันเช่นกัน

Reference websites

https://levelup.gitconnected.com/10-robustness-and-resiliency-design-patterns-to-learn-today-c03776f73936