สิ่งหนึ่งที่มักได้ยินบ่อย ๆ ในการพัฒนา software คือ
เรื่องของ Event-based Architecture
ยิ่งมีการพูดถึงมาก ๆ ในแนวคิดของ microservices
ตามจริงก็พูดกันเยอะมาก ๆ จาก Domain-Driven Design
ในเรื่อง Strategic design (Integration pattern)

อ่านเจอบทความเรื่อง Best Practices for Event-Driven Microservice
ซึ่งอธิบายได้อย่างน่าสนใจ ประกอบไปด้วย

  • Event-based Architecture คืออะไร ?
  • ทำไมถึงต้องใช้ด้วย ?
  • Event-based Architecture มีข้อดีและแน่นอนว่ามีข้อเสียอะไรที่ต้องรับมือ ?

จึงทำการสรุปไว้นิดหน่อย

Event-based Architecture คืออะไร ?

ผมคิดว่าเรื่องของ event หรือเหตุการณ์ต่าง ๆ มันเป็นเรื่องธรรมชาติอยู่แล้ว
แน่นอนว่า แต่ละ event ที่เกิดขึ้นมา
ย่อมเกิดผลกระทบหรือ side effect
โดยอาจจะเกิดผลกระทบในหลาย ๆ ส่วนงานก็เป็นไปได้ที่ให้ความสนใจต่อ event นั้น ๆ
ที่สำคัญแต่ละ event ที่เกิดขึ้นมา ต้องมีคนกระทำหรือคนที่สั่ง (Command)

โดยผู้สร้าง event จะเรียกว่า Producer
ส่วนผู้สนใจใน event ต่าง ๆ จะเรียกว่า Consumer
และ event ต่าง ๆ เหล่านี้จำเป็นต้องมีที่จัดเก็บ เราจะเรียกว่า Event store

เมื่อนำแนวคิดนี้มาใช้ใน Microservices แล้ว

สามารถออกแบบได้ดังตัวอย่าง
ของการสมัครสมาชิก (Register service)
จะมีขั้นตอนการทำงานและ services ต่าง ๆ ดังนี้

  • ขั้นตอนที่ 1 ผู้ใช้งานทำการสมัครสมาชิกผ่านหน้า website
  • ขั้นตอนที่ 2 Register service ทำการสร้างข้อมูล user ลง database
  • ขั้นตอนที่ 3 Register service ทำการสร้าง event ชื่อว่า Registered event ขึ้นมาใน Event store
  • ขั้นตอนที่ 4 Notification service ทำการ consume Registered event เพื่อทำการส่ง notification ไปหา user
  • ขั้นตอนที่ 5 Report service ทำการ consume Registered event เพื่อทำการบันทึกข้อมูลของ user เพื่อใช้ในการสร้าง report ต่อไป

โดยที่ event ที่สร้างขึ้นมานั้นคือ Registered event
จะถูกสร้างและจัดเก็บได้หลากหลายรูปแบบ
ยกตัวอย่างเช่น
จัดเก็บลง queue ซึ่งจะการันตีว่า event ต่าง ๆ
จะถูกส่งไปยัง consumer ที่กำหนดอย่างแน่นอน
หรืออาจจะสร้างในรูปแบบ pub/sub ก็ได้

ข้อดีของ Event-based Architecture ประกอบไปด้วย

1. ทำงานแบบ Asynchronous

ทำให้แต่ละ request ไม่จำเป็นต้องรอให้การทำงานทุกอย่างเสร็จ
จึงจะได้ response กลับมา
ทำให้ไม่ block การทำงาน
นั่นคือ resource ต่าง ๆ ไม่โดย block หรือ lock ไว้
ส่งผลให้รองรับ request ได้มากขึ้น

2. Loosely coupling หรือแต่ละส่วนงานผูกมัดกันแบบหลวม ๆ

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

3. ง่ายต่อการ scale ระบบ

แต่ละ service แยกกันชัดเจนจากข้อที่ 2
มีการทำงานที่เฉพาะเจาะจง
ทำให้ง่ายต่อการ tracking ปัญหา รวมทั้งง่ายต่อการ scale อีกด้วย

4. ง่ายต่อการ recovery ระบบ

ในกรณีที่ consumer มีปัญหาขึ้นมา
ระบบในรูปแบบนี้ สามารถนำ event ที่จัดเก็บใน event store มา replay ใหม่ได้
ซึ่งช่วยตอบโจทย์เรื่องของข้อมูลสูญหายได้อีกด้วย

มีข้อดีก็ย่อมมีข้อเสีย โลกสวยไม่ได้นะ !!

ข้อแรกคือ แยกการทำงานดีเกินไป (Over engineer)

ให้เกิด service ต่าง ๆ แยกกันเยอะมาก
แน่นอนบางครั้งเล็กจนเกินไป
ทำให้การทำงานหนึ่ง ๆ เกิดความซับซ้อนจนเกินไปตั้งแต่เริ่มต้น
ซึ่งบ่อยครั้งเราไม่ได้ต้องการอย่างนั้นเลย

ข้อสองคือ การจัดการข้อมูลและ transaction

เนื่องจากทำงานแบบ asynchronous 
ทำให้แต่ละส่วนงานไม่ได้สนใจเรื่องความถูกต้องของข้อมูลระหว่างกัน
จะสนใจเฉพาะการทำงานของตัวเองเท่านั้น
ซึ่งอาจก่อให้ข้อมูลเกิดซ้ำซ้อนขึ้นมา
ซึ่งอาจก่อนให้เกิดปัญหาเรื่อง transaction ข้ามระบบงาน
นั่นคือปัญหาเรื่องความถูกต้องของข้อมูล (Data consistency)
จะทำการจัดการอย่างไร ?

แน่นอนว่าไม่สนับสนุน ACID แน่ ๆ
ดังนั้นข้อมูลจะอยู่ในรูปแบบ Eventualy consistency
ซึ่งยากต่อการ tracking และ debug !!

ดังนั้นใครก็ตามที่เริ่มนำเอา Event-based Architecture มาใช้งาน

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

Reference Websites