บันทึกการอ่านเรื่องของปรับปรุง architecture ของระบบ Twitch
ซึ่งทำการปรังปรุงระบบ Monolith มายัง Microservice
โดยมีขั้นตอนการปรับปรุงที่น่าสนใจ
ทำการเขียนใน blog 2 ตัวคือ
อธิบายการเดินทางของระบบตั้งแต่เริ่มต้น
มาจนถึงมีการใช้งานที่สูงมาก ๆ
จนก่อให้เกิดปัญหาคอขวดต่าง ๆ ของระบบ
พร้อมทั้งแนวทางการแก้ไขปัญหา
เริ่มต้นทาง Monolith ทุกอย่างรวมกันที่เดียว
ง่ายต่อการพัฒนา ส่งมอบ
แน่นอนว่า เร็ว และ ดีต่อทีมที่มีขนาดเล็กในช่วงเริ่มต้น (Startup)
ทั้ง Web, database , file system
พัฒนาด้วย Ruby On Rails (RoR)
แต่เมื่อระบบใหญ่ขึ้น คนใช้งานมากขึ้น
จำเป็นที่จะต้องแยกส่วนการทำงานออกจากกันมาขึ้น
ด้วยเหตุผลดังนี้
- ทำงานร่วมกันมาเกินไป (Coordination)
- Resilience
- Scalability
โดยที่ Twitch นั้นมีปัญหาคอขวดของการ scale เป็นหลัก !!
เช่น
- ระบบ chat
- ระบบ VDO
- ระบบ Search
ดังนั้นจึงเริ่มมีแนวคิดที่จะพยายามแยกส่วนต่าง ๆ ออกมา
จากเดิมที่พัฒนาด้วย Ruby On Rails อย่างเดียว
เริ่มทำงานแบบ background ด้วย Sidekiq
แต่พบว่ายังอยู่ใน codebase เดิมซึ่งใหญ่ จึงพยายามแยกออกมา
ความพยายามแรกคือ พัฒนาส่วนใหม่ด้วย NodeJS
แต่ก็เจอปัญหาตอนการ scale
ในบทความบอกคร่าว ๆ ว่าเป็น ปัญหาที่ core ของ NodeJS
ซึ่งตอนนั้น NodeJS ยังใหม่มาก ๆ
จึงไม่ได้นำมาใช้งาน
ความพยายามที่สองคือ Python + Tonado
โดยได้พัฒนาระบบ chat ตัวใหม่ขึ้นมา
จากนั้นได้เริ่มนำภาษา Go มาลองสร้างเครื่องมือในระบบงาน
เช่นระบบ pubsub ที่เขียน code ไม่กี่ร้อยบรรทัด
เพื่อใช้ในการแลกเปลี่ยนข้อมูลในระบบ
หรือการ mock service เพื่อช่วยตรวจสอบ bug ในระบบ
ซึ่งเป็นการทดลองใช้ Go
เป็นจุดเริ่มต้นของการนำภาษา Go มาใช้งาน
และใช้เป็นภาษาหลักของระบบต่อมานั่นเอง
ในส่วนของ Frontend ก็เปลี่ยนแปลงเช่นกัน
จาก jQuery -> Ember.js มาจนถึง React.js
ขั้นตอนการย้ายระบบเก่ามาใหม่
จะเป็นการทำงานแบบขนานกันไป
โดยจะมี proxy มากั้น request เพื่อแยกไประบบเก่าและใหม่
ทำให้สามารถ redirect traffic ได้ง่ายขึ้น
ซึ่งใช้ NGINX ดังรูป
การเปลี่ยนแปลงครั้งนี้ จะกระทบเยอะมาก ๆ
ทั้งเรื่องของโครงสร้างของบริษัท
ทั้งเรื่องการเขียน code ใน repository เยอะ ๆ
เพื่อทำการส่งมอบ feature เดียวกัน
จะ deploy อย่างไร
การ provisioning infrastructure บน Cloud provider
ด้วยภาษา Go
การเรียกกันข้าม service ผ่านระบบ network
ซึ่งก่อนนี้จะเป็นแบบเรียก functiom/method
ทำให้เกิดปัญหาใหม่ ๆ ขึ้นมา เช่น
- Error handling
- Monitoring
- Circuit breaker
- Rate limit
- Request tracing
- API versioning
- Service-to-service security
- Authorization
- Integration test
ซึ่งหลาย ๆ อย่างมักจะทำการ copy-and-paste กันในแต่ละ service
ดังนั้นทีมจึงทำการสร้าง Twirp framework มาใช้งาน
สำหรับ service-to-service communication
ในตอนนี้จะใช้ภาษาโปรแกรมเยอะ
แยกตามไปแต่ละส่วนงาน
เช่น Go, TypeScript, Python, C++, Java/Kotlin และ ObjectiveC/Swift
และแต่ละทีมก็มี account สำหรับ Cloud provider แยกกัน
ส่งผลให้แต่ละส่วนงานมีความเป็นอิสระมากขึ้น
แต่ละทีมสามารถเข้ามา contribute ได้เลย
และเมื่อทีมแข็งแรงขึ้น จะเริ่มเกิด standard ต่าง ๆ ขึ้นมา
เกิด framework ต่าง ๆ ขึ้นมา
เกิด tool ต่าง ๆ ขึ้นมา
เพื่อช่วยให้การพัฒนา deployment และ operation มีประสิทธิภาพที่ดีขึ้น