คลังเก็บป้ายกำกับ: SERVICE_ORIENTED_ARCHITECTURE

ทำความรู้จักกับ Microservices สถาปัตยกรรมระบบที่ทั้งนักพัฒนา และผู้ดูแลระบบควรรู้จัก

ช่วงสองสามปีที่ผ่านมา หลายๆคนคงได้ยินคำว่า Microservices มาไม่มากก็น้อย

ในวงการไอทีต่างประเทศ สถาปัตยกรรมแบบ Microservices ได้ถูกนำมาใช้งานในบริษัทใหญ่ๆ (Amazon, Netflix ) มาเป็นเวลาหลายปีแล้ว  ช่วง 2-3 ปีที่ผ่านมา แนวคิดของสถาปัตยกรรมแบบนี้เริ่มตื่นตัว และถูกนำไปใช้อย่างแพร่หลายมากขึ้น บ้างก็ประสบความสำเร็จเป็นอย่างดี บ้างก็ประสบปัญหา ได้รับบาดแผลกันมาพอสมควร

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

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

 

ตัวอย่างและนิยามของ Microservices

สมมติว่าเราต้องการพัฒนาระบบ E-banking ของธนาคาร เราสามารถแตกระบบออกเป็นส่วนย่อยๆได้ ดังนี้

  • Authentication – สำหรับล็อคอินเข้าสู่ระบบ
  • Account Balance – สำหรับตรวจสอบยอดเงินของผู้ใช้
  • Payment – สำหรับโอน/จ่ายเงิน
  • SMS Verification- สำหรับใช้ยืนยันผู้ใช้ผ่านทาง SMS
  • ฯลฯ (ในที่นี้ยกตัวอย่างแบบไม่ซับซ้อน ระบบธนาคารจริงมีรายละเอียดเยอะกว่านี้มากๆครับ )

ในการพัฒนา เราสามารถเขียนระบบของทั้งหมดรวมกันเป็นชิ้นเดียว (ถ้าเป็น Java ก็อยู่ใน JAR หรือ WAR file เดียวกัน) แล้วนำไปวางบนเว็บเซอร์เวอร์ที่เดียว โดยเราเรียกสถาปัตยกรรมแบบนี้ว่า Monolith

แต่ถ้าเป็นสถาปัตยกรรม Microservices เราจะแยกพัฒนาแต่ละเซอร์วิซออกจากกันโดยชัดเจน โดยกำหนด API ไว้ให้เรียกใช้ แต่ละเซอร์วิซสามารถทำงานได้อย่างเป็นอิสระ มีฐานข้อมูลเป็นของตัวเอง และหากจำเป็นต้องใช้ข้อมูลที่อยู่ในเซอร์วิซอื่น ก็สามารถเรียกใช้ผ่าน API

vs monolith

เมื่อลูกค้าต้องการเช็คยอดเงิน จะสามารถติดต่อไปยัง Account Balance Service  เพื่อดึงข้อมูลออกมา  หากต้องการโอนเงิน ก็จะมีการติดต่อไปยัง Payment Service ซึ่งจะเรียก API ของ SMS Verification service อีกทอดนึง เพื่อทำการส่ง SMS สำหรับยืนยันการโอน

ถึงจุดนี้ เราน่าจะเห็นภาพคร่าวๆแล้วว่า Microservices คืออะไร บางคนอาจจะเริ่มคิดในใจว่า “เฮ้ย นี่มันก็คือ SOA (Service-oriented Architecture) ดีๆนี่เอง”  ซึ่งเป็นความคิดที่ถูกต้องครับ Microservices เป็นรูปแบบหนึ่งของ SOA  ซึ่งมีลักษณะพิเศษเพิ่มอีกหลายอย่าง

เพื่อให้ชัดเจนยิ่งขึ้นว่าลักษณะพิเศษเหล่านี้คืออะไร เราจะมาลองดูสถาปัตยกรรมแบบอื่นๆที่ ไม่ใช่ Microservices กันครับ

 

จุดเด่นของ Microservices เมื่อเปรียบเทียบกับสถาปัตยกรรมแบบอื่นๆ

ส่วนที่แล้ว ผมได้เปรียบเทียบความแตกต่างของ Microservices กับสถาปัตยกรรมแบบรวมทุกอย่างไว้เป็นเนื้อเดียว (Monolith) ในทางปฏิบัติ น้อยครั้งมาก ที่เราจะเห็นแอพพลิเคชั่นสมัยใหม่ถูกพัฒนาแบบทุกอย่างเป็นเนื้อเดียวกัน

 

Thee-tier architecture

เว็บแอพพลิเคชั่นส่วนใหญ่มักจะใช้สถาปัตยกรรมแบบ Three-tier โดยการแบ่ง Presentation (User interface), application logic, และ Database แยกออกจากกัน ตัวอย่างเช่น User interface ถูกเขียนด้วยจาวาสคริปต์และใช้งานบนเว็บบราวเซอร์ โดย application logic จะถูกซ่อนไว้บนเว็บเซอร์เวอร์ซึ่งติดต่อกับฐานข้อมูลในอีกเซอร์เวอร์แยกไปอีก

การใช้สถาปัตยกรรมแบบ Three-tier สามารถนำมารวมเข้ากับ Microservices ได้ โดยการแบ่งส่วนแต่ละ Tier ออกไปอยู่ในเซอร์วิซต่างๆแยกกัน ตามรูปข้างล่าง

vs threetier

ประเด็นสำคัญคือ การแบ่งชิ้นส่วน (Component) ของ Microservices นั้นแบ่งตามความต้องการของผู้ใช้งาน (Requirement หรือ Business capability) แทนที่จะแบ่งกันตามหน้า (Technical responsibility) เหมือนในกรณีของ Three-tier  โดยแต่ละเซอร์วิซจะมีอิสระต่อกันมาก

ดังนั้น ข้างในแต่ละเซอร์วิซ ก็จะสามารถนำมาแบ่งออกเป็น tier ย่อยลงไปได้อีก

อีกประเด็นที่สำคัญคือ การแบ่งตามเซอร์วิซ จะมีผลกระทบต่อการทำงานของทีมด้วย สมมติว่าเรามีทีมพัฒนา 20 คน  ครึ่งหนึ่ง (ทีมเหลือง) ต้องพัฒนา Payment service ส่วนอีกครึ่งหนึ่ง (ทีมเทา) ต้องพัฒนา Account Balance Service

หากเราเลือกทำตามรูปแบบทางซ้าย ทั้งสองทีมจะต้องเลือกใช้เทคโนโลยีเดียวกัน และ Release แอพพลิเคชั่นใหม่พร้อมกัน หากมีชิ้นส่วนไหนทำงานผิดพลาด ทั้งระบบอาจหยุดทำงานหมดได้

กรณีทางด้านขวา ทีมเหลืองอาจเลือกที่จะใช้ Java 7 ในการพัฒนา ส่วนทีมเทาอาจเลือกใช้ Python เขียน เนื่องจากเซอร์วิซทั้งสองตัวทำงานอยู่คนละ Process (หรืออาจจะอยู่คนละเครื่องเลย) ทั้งสองทีมมีอิสระอย่างเต็มที่ในการเลือกใช้เทคโนโลยีที่เหมาะสมกับทีม

นอกจากนี้ ทั้งสองทีมไม่มีความจำเป็นที่จะต้อง Release แอพพลิเคชั่นเวอร์ชั่นใหม่พร้อมกัน แต่ละทีมแค่ต้องรักษา Backward compatibility ของเซอร์วิซ ที่คนอื่นเรียกใช้ให้ทำงานได้เหมือนเดิมก็พอ  หากเซอร์วิซตัวหนึ่งเกิดพังขึ้นมา ตัวอื่น (ที่ไม่ได้ใช้งานเซอร์วิซนี้) ก็ยังสามารถทำงานได้อย่างปกติ

นี่เป็นกรณีของทีมพัฒนาขนาด 20 คน  ลองนึกภาพบริษัทใหญ่ที่มีทีมพัฒนาเป็นหลักพันคนดูสิครับ ถ้าไม่มีการแบ่งออกเป็นเซอร์วิซย่อยๆ จะ Release ทีนี่วุ่นวายแค่ไหน

 

Centrally Integrated database

ตัวเปรียบเทียบถัดไปคือแนวคิดของการจัดเก็บข้อมูล โดยแอพพลิเคชั่นบางประเภท (เช่น ERP- Enterprise Resource Planning) จะเน้นให้มีการจัดเก็บข้อมูลของทุกอย่างในฐานข้อมูลเดียวกัน เพื่อให้มีความสอดคล้อง (Consistent) และลดความซ้ำซ้อน (Duplication) ของข้อมูล

vs centraldb

ในแนวคิดของ Microservices  แต่ละชิ้นส่วนของแอพพลิเคชั่น (เซอร์วิซ) จะเป็นอิสระต่อกัน ดังนั้น แต่ละเซอร์วิซสามารถมีฐานข้อมูลแยกออกไปเป็นอิสระของตัวเอง การออกแบบ Microservices จึงต้องระวังเรื่องความสอดคล้องและความซ้ำซ้อนของข้อมูลให้ดี

อีกประเด็นหนึ่งที่สำคัญคือ แต่ละเซอร์วิซจะไม่สามารถเข้าถึง Database ของชิ้นส่วนอื่นๆได้ โดยจะต้องดึงข้อมูลผ่านทาง API ที่ตกลงกันไว้เท่านั้น

จากรูปด้านบน เราอาจจะต้องการแสดงรายงานยอดเงินในบัญชีย้อนหลังสามสิบวัน โดยแต่ละวันมีการโอนเงินเข้าออกเท่าไรบ้าง ซึ่งจะต้องดึงข้อมูลจากทั้ง 2 เซอร์วิซมารวมเข้าด้วยกัน  คำถามคือ เราจะเชื่อมข้อมูลด้วยอย่างไร?  ถ้าใช้หมายเลขบัญชีควรจะเป็นความรับผิดชอบของเซอร์วิซไหนในการเชื่อมข้อมูล  ส่วนนี้เป็นความยากของการออกแบบ Microservices เพราะถ้าออกแบบผิดแล้ว การจะย้ายโค้ดข้ามเซอร์วิซในภายหลังจะทำได้ยากมาก

 

Enterprise Service Bus

อีกตัวอย่างหนึ่งที่สามารถแสดงข้อแตกต่างของ Microservices กับ SOA แบบอื่นได้ดี คือสถาปัตยกรรมที่ใช้ Enterprise Service Bus

vs esb

Enterprise Service Bus เป็นสถาปัตยกรรมแบบหนึ่งของ SOA  โดยตัว Bus จะหน้าที่หลายอย่างดังนี้ [2]

  1. ส่งข้อมูลหรือข้อความต่างๆระหว่าง Service
  2. จัดการ Deployment ของ Service เวอร์ชั่นต่างๆ
  3. จัดการ Service ที่หลาย Service ต้องเรียกใช้ร่วมกัน (event handling, , data mapping and transformation, security, exception handling)
  4. Service orchestration

ในทางตรงกันข้าม Microservices เลือกที่จะตัด Enterprise Service Bus ออก และหันไปใช้ “Dumb pipes” [1] ในการส่งข้อมูลแทน

Dumb pipes อาจจะเป็นเพียง HTTP connection หรือ Light-weight messaging  ใจความหลักคือ Dumb pipes จะทำหน้าที่ส่งข้อมูล ส่วนหน้าที่อื่นๆที่เคยถูกทำโดย Enterprise Service Bus จะถูกโอนไปให้ตัวเซอร์วิซเป็นผู้ตัดสินใจเอง

แล้วแบบไหนดีกว่า? คำตอบก็แล้วแต่มุมมองและสถานการณ์ ฝั่งที่สนับสนุน Microservices จะสนับสนุนตัวเองว่า Business logic และการจัดการต่างๆควรจะเป็นหน้าที่ของฝั่งเซอร์วิซ ไม่ใช่เอามาปนกันอยู่ใน Bus  ในขณะที่ฝั่งที่สนับสนุน Bus ก็จะบอกว่าการให้อิสระมากเกินไปกับฝั่งเซอร์วิซ จะทำให้ควบคุมจากส่วนกลางทำได้ยาก Interface ของแต่ละเซอร์วิซไม่สอดคล้องกัน และมี Logic ที่ซ้ำซ้อนระหว่างเซอร์วิซมากกว่า

โดยส่วนตัว ผู้เขียนชื่นชอบ Microservices มากกว่าเพราะเหตุผลในด้านการจัดการ  เนื่องจากทีมพัฒนาที่ดูแล Bus กับตัว Service มักจะเป็นคนละทีมกัน ทีมที่ดูแล Bus มักจะเป็นทีมที่มีงานมากที่สุด (เพราะต้องรองรับทุกๆ Service) พอใกล้เวลา Release ก็จะเกิดปัญหาคอขวดที่ทีมนี้เนื่องจากงานล้นมือ  และจบด้วยปัญหาการเมืองที่มาไล่จับแพะกันว่าทำไมถึง Release ไม่ทัน

 

สรุปข้อดีข้อเสียของ Microservices

ถึงจุดนี้ ผู้อ่านคงเห็นภาพของ Microservices ชัดเจนมากขึ้น ผมข้อสรุปข้อดีข้อเสียไว้ดังนี้ครับ

  • ข้อดี

    • Technology Independent – แต่ละเซอร์วิซมีอิสระในการเลือกใช้เทคโนโลยีที่ต่างกัน
    • Availability – หากเซอร์วิซหนึ่งพัง เซอร์วิซอื่นๆที่เหลือยังสามารถทำงานต่อได้โดยไม่พังทั้งระบบ
    • Release and deployment – การจัดการเซอร์วิซเล็กๆหลายตัวทำได้ง่ายกว่า
    • Scalability – การทำขยายเซอร์เวอร์เพื่อรองรับผู้ใช้งานที่มากขึ้น (เช่น เพิ่มจำนวนเซอร์เวอร์) สามารถทำได้ในเฉพาะเซอร์วิซที่ถูกใช้งานเยอะๆ  แทนที่จะต้องทำกับทั้งแอพพลิเคชั่น
  • ข้อเสีย

    • Boundary definition between services – หากการแบ่งเซอร์วิซทำไว้ตอนแรกไม่ดี การแก้ไขในภายหลังจะยากมาก เพราะ  Service อาจถูกเรียกใช้แล้ว การรักษา Backward compatibility จะทำให้การ Refactor โค้ดระหว่างเซอร์วิซยากมากๆ
    • Latency – การใช้ส่งข้อมูลระหว่างเซอร์วิซนั้นช้ากว่าการส่งข้อมูลภายใน process เดียวกัน (ในกรณี Monolith)
    • Consistency – ความสอดคล้องกันของข้อมูลจะรักษายากกว่ากรณี Integrated Database
    • Infrastructure automation– การทำ Microservices ให้ได้ดี จำเป็นต้องมีการจัดการ Infrastructure ที่ดีมาก เพราะการ deploy เซอร์วิซจำนวนมากนั้นจะทำ Manual ยากมาก ส่วนใหญ่ต้องใช้การทำ Automation เกือบ 100%

แหล่งอ้างอิง:

from:https://www.techtalkthai.com/introduction-to-microservices-architecture/