Microservices คืออะไร?
Microservices คือแนวคิดในการออกแบบระบบรูปแแบบหนึ่ง ซึ่งมาจากคำว่า Micro และ services
- Micro คือ service ต่างๆที่นำมาใช้งานใน ระบบต้องมีขนาดเล็ก(ยิ่งเล็ก ยิ่งดี)
- Services นำ Services หลายๆตัวมาทำงานร่วมกัน(โดยส่วนใหญ่จะคุยกันผ่าน REST API และ gRPC) ใน microservices จะไม่ทำทุกอย่างอยู่ใน application ตัวเดียว
ดังนั้น Microservices จะเติม s ด้วยเสมอเพราะเป็นการนำเอา services หลายๆตัว(ที่มีขนาดเล็ก) มาทำงานร่วมกัน
ที่มาของ Microservices
Microservices เกิดจากการสะสมองค์ความรู้จากการทำ Distributed System ดังนั้น Design Patterns ต่างๆ ที่นำมาใช้ใน Microservices นั้นจึงไม่ใช่ของใหม่แต่ได้ถูกประยุกต์ใช้อย่างแพร่หลายมาอย่างยาวนาน
และอีกต้นกำเนิดของ Microservices คือ Service Oriented Architecture(SOA) เป็นแนวคิดที่ได้รับการยอมรับในวงกว้าง แต่เนื่องจากการออกแบบระบบให้เป็น SOA นั้นจำเป็นต้องใช้เครื่องมือที่นำมาเชื่อม Services ต่างๆเข้าหากันเรียกว่า Enterrprise Service Bus(ESB) ซึ่งมีราคาค่อนข้างสูง เราจึงเห็น Implementation เฉพาะในองค์กรที่มีขนาดใหญ่ๆเท่านั้น และในแนวคิดของ SOA นี่เองที่ทำให้เราเริ่มแยก Services ต่างๆออกไปเป็น Web Services (ช่วงนั้นจะยังนิยมใช้ SOAP Service เป็นหลัก) หลังจากนั้นก็เริ่มมีการใช้งาน RESTful services กันมากขึ้นจึงทำให้เริ่มมีการพูดถึง lightweight SOA และได้พัฒนาแนวคิดมาเรื่อยๆจนกลายเป็น Microservices ในปัจจุบัน
Monolithic vs Microservices
Monolith หรือ Monolithic คือการออกแบบระบบในแบบเดิม ที่เราจะนำทุก services ไปไว้ใน Project เดียวกันทั้งหมด
การเป็น Monolith นั้นทำให้เราปรับเปลี่ยนระบบได้ยาก(ทุกครั้งที่เกิดการเปลี่ยนแปลงจะต้อง Build ระบบใหม่ทั้งก้อน) และยังเจอปัญหาในการ scale อีกด้วย(ถ้่าต้องการรองรับ load มาขึ้นก็ต้องนำ Application นี้ไป deploy ใหม่ทั้งก้อน)
ทำไมต้องเป็น Microservices
แนวโน้มของการพัฒนาซอฟแวร์นั้นจะมีการเพิ่ม requirements และความซับซ้อนมากขึ้นเรื่อยๆในทุกๆปี ดังนั้นเมื่อเวลาผ่านไปความต้องการของ user ก็จะมีมากขึ้นและก็จะยิ่งซับซ้อนมากขึ้นดังนั้นการที่เราพัฒนาระบบขั้นมาเป็นแบบ Monoliths นั้นจะทำให้เกิดข้อจำกัดต่างๆดังนี้
- ระบบยิ่งมีขนาดใหญ่ ยิ่งมีจำนวน developer มากขึ้น เมื่อคนเยอะขึ้นการสื่อสารก็ทำได้ยากขึ้นตามไปด้วย
- ปริมาณของ data นั้นจะมีมากขึ้นเรื่อยๆ ยิ่ง data มีปริมาณมาก ความเสี่ยงก็จะมากขึ้นตามไปด้วย(Centralize Database)
- ยิ่งระบบมีขนาดใหญ่ขึ้นการแก้ไข(maintain)ก็ทำได้ยากขึ้น
- ยิ่งระบบใหญ่ขึ้นก็ต้องมี module มากขึ้น และเมื่อมี module มากขึ้นการสื่อสารระหว่าง module ก็จะมากขึ้นตามไปด้วย นั่นทำให้ระบบเกิด high coupling(ถอดออกได้ยาก)
- ยิ่งระบบใหญ่ขึ้น technical debt ก็จะมากขึ้นตามไปด้วย
technical dept คือ การที่เราแก้ปัญหาโดยไม่ได้แก้ที่ต้นเหตุ ดังนั้นปัญหาจริงๆจะยังคงอยู่และเมื่อปัญหาที่เราได้หมกไว้นี้กลับมาเกิดขึ้นใหม่ก็จะทำให้ใช้ต้นทุนทั้งเวลาและจำนวนคนที่เข้ามาแก้ไขปัญกานี้มากขึ้น
ซึ่งนี่ก็เป็นสาเหตุว่าทำไมเราจึงควรเปลี่ยนมาเป็น Microservices Architecture เพื่อที่จะลดปัญหาที่ว่ามาทั้งหมดนี้ เพราะเมื่อ source code มีขนาดเล็กลง ปัญหาก็จะน้อยลงตามไปด้วย
การออกแบบ Microservices(Microservices Architecture)
Microservices Architecture คือการออกแบบระบบให้สอดคล้องกับแนวคิดของ Microservices และเนื่องจาก Microservices นั้นไม่ได้มีเฉพาะข้อดีเท่านั้นแต่ยังนำมาซึ่งความซับซ้อน ความยากในการออกแบบ พัฒนาและดูแลให้ services นั้นทำงานได้อย่างราบรื่น
ดังนั้นเราจึงควรออกแบบระบบให้ได้ประโยชน์จากการเป็น Microservices มากที่สุด ในต้นทุนที่คุ้มค่ามากที่สุด หรือแม้กระทั่งพิจารณาว่าระบบที่เรากำลังออกแบบนั้นได้ประโยชน์จากการเป็น Microservices ที่คุ้มค่าหรือไม่ ถ้าไม่คุ้มค่าเราอาจต้องเลือกที่จะให้ระบบเรายังคงเป็น Monolith ต่อไป
เราควรออกแบบ Microservices โดยคำนึงถึง Value ที่ได้จากการเป็น Microservices เสมอ
การออกแบบ Microservices ควรจะต้องเข้าใจแนวคิดเหล่านี้
- Domain Driven Design(DDD) เป็นแนวคิดที่ใช้ในการแบ่งแยก Service (Bounded Context)
- Event Driven Design(EDD) วิธีคิดใน Microservices เราจะเริ่มต้นที่ Event เสมอและคิดต่อว่าหลังจากนั้นจะมี Work flow ยังไงต่อไป
- Contract Driven Design(CDD) ใช้ในการ ออกแบบ API โดยเริ่มจากการสร้าง Contract หรือ Document ขึ้นมาก่อน ก่อนจะนำ Contract นั้นไปสร้างเป็น API ขึ้นจริงๆ คล้ายๆกับ Test Driven Design(TDD) ที่เขียน Test ก่อนเขียน Code
Microservices ที่ดีต้องมีสิ่งนี้
- High Cohesion แต่ละ service ต้องทำหน้าที่เพียงอย่างเดียวเท่านั้น(Single Responsibility)
- Autonomous ระบบต้องสามารถเปลี่ยนแปลงและ Deploy ได้โดยที่ไม่ต้องขึ้นอยู่กับ service อื่นๆ
- Business Domain Centric เราต้องออกแบบให้ระบบนั้นสอดคล้องกับการทำงานในธุรกิจจริง ทั้งการตั้งชื่อตัวแปรและ service ต่างๆต้องนำมาจาก business function หรือ business action ที่มีอยู่ในการทำงานจริง
- Resilience เราต้องออกแบบให้ระบบนั้นมีความแข็งแรง รวมทั้งยังสามารถตอบสนองต่อข้อผิดพลาดได้ดี(Continuity)
- Observable เราต้องมี Centrailize Logging และ Centralize Monitopring เนื่องจากระบบนั้นกระจายออกเป็น services ย่อยๆ เราจึงต้องนำ Log ของแต่ละ service มารวมกัน เพื่อที่จะได้แก้ปัญหาต่างได้ง่ายขึ้น
- Automation การดูแล Microservices นั้นเราไม่สามารถจัดการด้วยขึ้นตอนการทำงานด้วยคนได้ เราจึงต้องพยายามทำให้การทดสอบ(Testing) และการ Deploy เป็นไปโดยอัตโนมัติ
ในปัจจุบันเรายังเริ่มมีการพูดถึง Microservices ที่สามารถตอบสนองต่อข้อผิดพลาดต่างๆได้ เรียกว่า Reactive Microservices
Downstream and Upstream service
ศัพท์ที่เราใช้เรียก service อยู่บ่อยๆคือ downstream service และ upstream service เนื่องจาก microservices นั้นมีการเรีียก service ต่อเนื่องกันไปเรื่อยๆ เพื่อความเข้าใจว่าเรากำลังพูดถึง service ด้่นหน้าและด้านหลังเราจะเรียกว่า
- Downstream service หมายถึง service ที่อยู่หน้าบ้าน(จะใกล้กับ user)
- Upstream service หมายถึง service ที่อยู่ด้่านหลังจะใกล้กับ database มากๆ
จากรูป Trip management จะเป็น downstream service ส่วน Passenger management จะเป็น upstream service
เทคโนโลยีที่ใช้ใน Microservices มีอะไรบ้าง?
- RESTful API รูปแบบของการให้บริการ(Web Service)ที่ได้รับความนิยมสูงสุด ข้อดีคือการรับส่งข้อมูลด้วย REST API จะเกิด dependency น้อยมาก
- gRPC เป็นอีกรูปแบบหนึ่งของการแลกเปลี่ยนข้อมูล จะแตกต่างจาก REST API ตรงที่มันจะมีการกำหนดรูปแบบของข้อมูลที่จะคุยกันจึงทำให้เราได้ความถูกต้อง(Integrity)ของข้อมูล
- Container การใช้ container จะเป็นเครื่องมือช่วยให้เราสามารถ deploy แต่ละ service ได้ง่ายขึ้น
- API Gateway ใน microservices มีจำนวน services ที่เยอะมากๆดังนั้นต้องมี Single point of contract คือมีจุดที่เราสสามารถเข้าใช้บริการได้จากที่ๆเดียว นั่นคือ API Gateway นั่นเอง อ่านเรื่อง api-gateway ต่อได้ที่นี่
- Authentication and Authorization Server เนื่องจากเราไม่สามารถกระจาย username และ password ไปไว้ใน services แต่ละตัวได้้เราจึงต้องมี server ที่ใช้สำหรับการ authentication และ authorization โดยเฉพาะซึ่งส่วนใหญ่เราจะใช้ oAuth2 server และ Open ID Connect(OIDC)
- Service Registry และ Service Discovery การที่มี services หลายๆ services ยิ่งมากการ monitor ว่า service แต่ละตัวยังคงทำงานได้อยู่รึเปล่า เป็นสิ่งที่จำเป็นมาก
- Logging และ Monitoring Server การจัดการ Log และการ Monitor services นั้นจำเป็นต้องเป็น Centrallize คือมี server ที่ดูแลเรื่องนี้โดยเฉพาะ เพราะเมื่อนำ service ใหม่ๆเข้ามาในระบบเราจะได้เก็บ Log และ Monitor service นั้นได้เลยทันที
- Message Broker การรับส่งข้อมูลใน Microservices เราจะเน้นการรับส่งแบบ Asunchronous ดังนั้นจึงนิยมนำ Message Broker เข้ามาเป็นตัวกลางในการรับส่งข้อมูล
- Caching ในทุกๆระบบจำเป็นต้องมี master data หรือข้อมูลหลักที่ใช้ร่วมกันบ่อยๆ ดังนั้น Caching Server จึงเป็นส่วนหนึ่งมีสำคัญในการ share data ที่ใช้บ่อยๆ และนอกจากนี้ Cache ยังสามารถเพิ่ม performance และ continuity ให้กับระบบได้อีกด้วย
การจะทำ Microservices นั้นต้องอาศัย skill และ Knowledge ที่เยอะพอสมควร แต่ทุกๆเทคโนโลยีที่พูดถึงนี้ก็ยังจำเป็นต้องใช้ใน Monolithic ด้วยเหมือนกัน เพียงแต่การเป็น Microservices นั้นเทคโนโลยีต่างๆที่กล่าวมานี้มีความจำเป็นมากกว่า Monolithic มากๆ
ข้อดีของ Microservices
- ระบบจะมี High Availability(จะล่มยากขึ้น)
- การทำการ Scale up(เพิ่ม server) หรือ Scale down(ลด server) ได้ตามการใช้งาน
- สามารถ update หรือสร้าง service ใหม่ขึ้นมาทดแทนของเก่าได้ง่าย
- สามารถเลือก Database ได้เหมาะกับงานมากขึ้น
- ไม่ต้องยึดติดกับภาษาหรือเทคโนโลยีใดๆ
สิ่งที่มักจะเป็นความต้องการพื้นฐานของระบบที่จะเป็น Microservices เลยคือ High Availability และ Scalability
ข้อเสียของ Microservices
- ต้องมีการพัฒนา skill หรือทักษะหลายอย่างให้กับทีมงาน
- ต้องพัฒนาการทำ Infrastructure as Code(IaC) และ Automated Deployment
- จำเป็นต้องมีการทำ Automated Testing
- กระบวนการ Test จะเปลี่ยนไป โดยจะเน้นที่การทำ Integration Test มากขึ้น
- ไม่มีเครื่องมือที่สามารถนำมาใช้แล้วจะกลายเป็น Microservices ได้เลย
- การจัดการเรื่องความสอดคล้องของข้อมูล(Data Consistency) เป็นเรื่องยาก
- จะเกิด Communication Cost หรือเวลาที่ใช้ในการรับส่งข้อมูลข้าม service มากขึ้น
Communication Cost(Network Latency) กับ Data Consistency ถือว่าเป็นต้นทุนใน Microservices ที่สามารถแลกกับ High Availability และ Scalability ได้
จาก Monolith สู่ Microservices
การจะเป็น Microservices ได้นั้นมีกระบวนการอยู่ 2 วิธีนั่นคือ
- Green Field Approach จะเป็นการสร้าง Microservices โดยเริ่มต้นจากศูนย์เลย โดยที่มีคำแนะนำจากผู้่เชี่ยวชาญว่าเราควรจะออกแบบระบบให้เป็น Monolithic ก่อนแล้วจึงค่อยนำมาออกแบบให้เป็น microservices
- Brown Field Approach เป็นการปรับเปลี่ยนระบบแบบ Monolithic ให้เป็น Microservices โดยจะต้องค่อยๆย้่าย service ที่มีความสำคัญมากและมีความเสี่ยงน้อยออกมาก่อน โดยในทุกๆขั้นตอนจำเป็นจะต้องสามารถ roll back กลับได่้เสมอ
Microservices นั้นไม่จำเป็นต้องสร้างขึ้นจากศูนย์เสมอไป
Microservices Design Patterns
Design Patterns คือ การรวบรวมวิธีการแก้ปัญหาที่ได้ผล(Best Practices) เพื่อเป็นกรณีศึกษาให้กับผู้ที่ต้องมา Implement ทีหลังจะได้ไม่เสียเวลาในการแก้ไขปัญหา Microservices เองก็มีปัญหาที่ต้องเจออยู่เยอะมากๆ จึงจำเป็นต้องรวบรวมองค์ความรู้ทั้งจากการทำ Distributed System และวิธีการแก้ไขปัญหาที่หลายๆองค์กรเลือกใช้งาน เพื่อให้เราจะได้ไม่ต้องเสียเวลาในการหาวิธีการแก้ปัญหาเหล่านั้น โดยที่ Microservices design patterns หรือ microservices architecture patterns หลักๆที่เราต้องรู้จักไว้มีดังนี้
- Circuit Breaker เพื่อให้ระบบสามารถจัดการกับข้อผิดพลาดที่เกิดขึ้นได้ ต้องใช้ Pattern นี้ ระบบจะไม่ส่งข้อความไปหา service ที่ไม่ available(ถามจาก Service Registry ได้)
- SAGA ใช้ในการจัดการ Distributed Transaction(Transaction เดียวกัน แต่ต้องใช้หลาย service ในการทำ Transaction นี้)
- CQRS การแยก Service ออกมาเป็น 2 ส่วนโดยจะแยกการทำงานของการอ่านและการเขียนออกจากกัน ซึ่งอย่างน้อยต้องมี service สำหรับการ Query(Read Only) อย่างเดียว 1 ตัวและอีก 1 ตัวสำหรับการ insert, update หรือ delete
- Event Sourcing เป็นการเก็บการเปลี่ยนแปลงต่างๆที่เกิดขึ้นกับ service นั้นๆไว้ในฐานข้อมูล เมื่อใครอยากจะรับรู้การเปลี่ยนแปลงที่เกิดขึ้นนี้ก็จะมา subscribe หรือ query ข้อมูลในฐานข้อมูลนี้
Microservices Design Patterns เป็นสิ่งที่เข้าใจยาก แต่ยิ่งคุณเข้าใจ Design Patterns เหล่านี้มากขึ้นเท่าไหร่ปัญหาในการทำ Microservices นั้นยิ่งลดลง
อย่าลืมหลักการที่อยู่เบื้องหลัง Microservices
การเป็น Microservices นั้นมีหลักการที่ต้องยึดถือไว้ตลอดเวลาเลยนั่นคือการเป็น Agile และ DevOps ยกตัวอย่างเช่น Domain Driven Design ต้องอาศัยคนที่มีความเข้าในใน Business อยู่ในทีมด้วย(Agile Principles) เพื่อที่จะช่วยนำทางให้การทำงานของระบบนั้น สอดคล้องและตอบโจทย์ธุรกิจจริงๆ
Agile Principles และ DevOps Principles เป็นหลักการที่ทุกคนในทีมต้องยึดถือไว้ตลอดเวลา
ตัวอย่าง Microservices (Microservices examples)
- Sock shop เป็นตัวอย่างที่มาจากค่าย Weavework(ผู้พัฒนา WeaveNet ใน Kubernetes และแนวคิด GitOps ที่มีคนพูดถึงเป็นจำนวนมาก)
- eShop on Container เป็นตัวอย่างจากค่าย Microsoft เป็น project ทืี่แนะนำให้ศึกษาสำหรับ dotnet developer ทุกท่าน
- Eventuate example ตัวอย่างประกอบหนังสือ Microservices Patterns ที่ถือได้ว่าเป็นตำราต้นฉบับสำหรับผู้ที่ต้องการเข้าใจ Microservices อย่างถ่องแท้