
จากการไปแบ่งปันความรู้เรื่องการออกแบบระบบพื้นฐานนั้น
หนึ่งในเรื่องที่น่าสนใจคือ การออกแบบเพื่อรองรับความผิดพลาดต่าง ๆ
ที่อาจจะเกิดขึ้นได้ในระบบของเรา หรือ design for failure นั่นเอง
ว่ามีแนวทางอย่างไรบ้าง
เพื่อทำให้ระบบมีความน่าเชื่อถือมากยิ่งขึ้น
จึงได้ทำการพูดคุย และ แนะนำแนวทางต่าง ๆ ที่น่าสนใจไว้ดังนี้
แนวทางต่าง ๆ นั้น ต้องเข้าใจถึง requirement ด้วยว่าเป็นอย่างไร
มีข้อจำกัดอย่างไร
และเกี่ยวข้องกับ user experience ที่เปลี่ยนไปด้วย
ก่อนอื่นต้องเข้าใจก่อนว่า ในทุก ๆ ส่วนของระบบงานมันพร้อมพังเสมอ
ดังนั้น เราต้องระบุจุดเสี่ยงต่าง ๆ ออกมาก่อน
จากนั้นทำการออกแบบเพื่อรับมือปัญหาต่าง ๆ เหล่านั้น
ถ้าส่วนหนึ่งพัง หรือ มีปัญหา จะไม่ส่งผลต่อส่วนอื่น ๆ เช่น
feature ที่ 1 มีปัญหา น่าจะไม่ส่งผลกระทบต่อ feature อื่น ๆ ที่ไม่เกี่ยวข้องกัน
หรือสามารถทำการ auto recovery กลับมาเป็นปกติได้เอง
เพื่อลดผลกระทบที่เกิดจากข้อผิดพลาดต่าง ๆ ให้น้อยที่สุด
ซึ่งจะส่งผลดีต่อ business นั่นเอง
ตัวอย่างของแนวทางในการแก้ไข หรือ ป้องกัน
- Timeout and retry น่าจะใช้กันบ่อยสุด ๆ เพื่อไม่ให้กิน resource นานเกินไป คงไม่ใส่ timeout กันน่นมาก ๆ เช่น 10 วินาทีขึ้นไปนะ
- Redundancy และ replication น่าจะใช้บ่อยเช่นกัน เพื่อลดความเสี่ยงต่าง ๆ ลงไป มีมากกว่า 1 น่าจะดีกว่า และ มีความน่าเชื่อถือสูง แต่แลกมาด้วยค่าใช้จ่ายที่สูงขึ้น
- Batching หรือ scheduler job เป็นแนวทางที่ใช้กันมายาวนาน ทำให้แต่ละระบบแยกกันชัดเจน แต่ไม่สามารถทำงานแบบ realtime ได้
- Circuite breaker เป็นอีกแนวทางหนึ่งของการตัดก่อนตายเตือนก่อนวายวอด ทำการตรวจสอบจากฝั่งผู้ใช้งานเสมอว่า ปลายทางที่เราใช้งานนั้นมีปัญหาหรือเกิดปัญหาตามที่กำหนดไว้หรือไม่ เพื่อให้ฝั่งของ client จัดการได้ง่ายขึ้น เช่นถ้าในการเรียก 100 ครั้งล่าสุดนั้น ปลายทางมีปัญหาทั้ง 100 ครั้ง แล้วในครั้งที่ 101 จะเรียกหรือไม่ ?
- Bulkhead คือการออกแบบเพื่อแต่ละส่วนต่าง ๆ ในระบบงาน หรือ despendency ต่าง ๆ ออกจากกัน เมื่อเกิดปัญหาในส่วนหนึ่ง ๆ แล้วไม่กระทบในวงกว้าง หรือ cascadeed-failure นั่นเอง
- Asynchronous communication การติดต่อสื่อสารระหว่างส่วนต่าง ๆ ของระบบงาน ถ้าทำงานแบบ sync ได้แล้วไม่มีคอขวดน่าจะดีและง่ายต่อการพัฒนา แต่ถ้ามีปัญหาขึ้นมาแล้ว หนึ่งในแนวทางคือ เปลี่ยนมาใช้ Asynchronous เพื่อลดการผูกมัดระหว่างส่วนงาน รวมทั้งลดเรื่องความกดกันหรือ load งานลงไป ซึ่งมีเทคนิดต่าง ๆ มากมาย เช่น event-based, queue, topic เป็นต้น รวมทั้งขากลับของ response ก็อาจจะเป็น async-request and response หรือ web hook ก็ได้
- ยังมีแนวทางอื่น ๆ อีกมากมายที่นำมาใช้งาน เช่น api gateway, auto-scale, auto-recovery, rate limit และ caching เป็นต้น
แต่ทั้งหมดนี้จำเป็นต้องมีระบบ observability ที่ดี
ทั้ง log, metric, trace, alert system
ที่ช่วยให้ระบบจุดเกิดเหตุของปัญหาได้อย่างทันท่วงที
ไม่ต้องมาเสียเวลา debug หรือ หาจุดผิดพลาด
ดังนั้นลองดูว่าแนวทางเหล่านี้ มีแนวทางไหนบ้างที่เหมาะสมกับปัญหาของเราบ้าง ?
Reference Websites