Topology (โครงสร้าง Topology)

Event-driven architecture ใช้การสื่อสารแบบอะซิงโครนัสในรูปแบบ fire-and-forget ซึ่งแต่ละ service จะ trigger event และ service อื่นๆ จะตอบสนองต่อ event เหล่านั้น ส่วนประกอบหลักทั้งสี่ของ topology นี้ได้แก่ initiating event , event broker , event processor (มักเรียกสั้นๆ ว่า service ) และ derived event .

initiating event คือ event ที่เริ่มต้น event flow ทั้งหมด อาจเป็น event ง่ายๆ เช่น การเสนอราคาประมูลออนไลน์ หรือ event ที่ซับซ้อนกว่านั้น เช่น การอัปเดตระบบสวัสดิการสุขภาพเมื่อพนักงานแต่งงาน initiating event จะถูกส่งไปยัง event channel ใน event broker เพื่อรอประมวลผล event processor หนึ่งตัวจะรับ initiating event จาก event broker และเริ่มประมวลผล event นั้น

event processor ที่รับ initiating event มาจะทำงานเฉพาะที่เกี่ยวข้องกับการประมวลผล event นั้น (เช่น การเสนอราคาประมูลสินค้า) จากนั้นจะประกาศสิ่งที่มันทำไปให้ระบบส่วนที่เหลือทราบแบบอะซิงโครนัส ด้วยการ trigger สิ่งที่เรียกว่า derived event ไปยัง event broker event processor ตัวอื่นๆ จะตอบสนองต่อ derived event นี้ ประมวลผลเฉพาะส่วนของตนตาม event นั้น แล้วประกาศสิ่งที่ตัวเองทำผ่าน derived event ใหม่อีกต่อหนึ่ง กระบวนการนี้จะดำเนินต่อไปเรื่อยๆ จนกว่า event processor ทุกตัวจะว่างและ derived event ทั้งหมดถูกประมวลผลเสร็จสิ้น Figure 15-2 แสดงให้เห็นขั้นตอนการประมวลผล event นี้

Event-driven architecture topology

Figure 15-2. Basic topology of an event-driven architecture (Topology พื้นฐานของ Event-Driven Architecture)

ส่วนประกอบ event broker มักจะเป็นแบบ federated (หมายถึงมี instance แบบ clustered ตาม domain หลายชุด) แต่ละ federated broker จะมี event channel ทั้งหมด (เช่น queue และ topic) ที่ใช้ใน event flow (workflow ทั้งหมดสำหรับการประมวลผล event) ของ domain นั้นๆ เนื่องจากสไตล์สถาปัตยกรรมนี้มีลักษณะ decoupled อะซิงโครนัส และเป็นการ broadcast แบบ fire-and-forget broker topology จึงใช้ topic, topic exchange (ในกรณีของ Advanced Message Queuing Protocol (AMQP) ) หรือ stream ด้วยโมเดลการส่งข้อความแบบ publish-and-subscribe

เพื่อแสดงให้เห็นภาพรวมว่า EDA ทำงานอย่างไร ลองพิจารณา workflow ของระบบรับคำสั่งซื้อสินค้าปลีก (retail-order entry system) ทั่วไป ดังภาพประกอบใน Figure 15-3 ที่ลูกค้าสามารถสั่งซื้อสินค้าได้ (เช่น หนังสือเล่มนี้) ในตัวอย่างนี้ event processor Order Placement จะรับ initiating event ( place order ) เพิ่มคำสั่งซื้อลงในตารางฐานข้อมูล และส่ง order ID กลับไปให้ลูกค้า จากนั้นจะประกาศให้ระบบส่วนที่เหลือทราบว่าได้สร้างคำสั่งซื้อแล้วผ่าน derived event order placed สังเกตว่ามี event processor สามตัวที่สนใจ derived event นี้ ได้แก่ event processor Notification , event processor Payment และ event processor Inventory ซึ่งทั้งหมดจะทำงานของตัวเองพร้อมกัน

Event-driven architecture example

Figure 15-3. Example of the event-driven architecture topology (ตัวอย่าง Topology ของ Event-Driven Architecture)

event processor Notification รับ derived event order placed และส่งอีเมลแจ้งรายละเอียดคำสั่งซื้อให้ลูกค้า เนื่องจาก event processor Notification ได้ทำงานเสร็จแล้ว จึงสร้าง derived event email sent ขึ้นมา อย่างไรก็ตาม สังเกตได้จาก Figure 15-3 ว่าไม่มี event processor ตัวอื่นฟัง derived event นี้เลย นี่เป็นเรื่องปกติใน EDA และแสดงให้เห็นถึง architectural extensibility ของสไตล์นี้ นั่นคือความสามารถที่ event processor ในอนาคตจะตอบสนองต่อ derived event ได้โดยไม่ต้องแก้ไขระบบที่มีอยู่เดิม (ดู “Triggering Extensible Events” )

event processor Inventory ก็ฟัง derived event order placed เช่นกัน และปรับปรุงสต็อกสินค้าของหนังสือเล่มนั้น จากนั้นจะประกาศการกระทำนี้ด้วยการ trigger derived event inventory updated ซึ่งจะไปกระตุ้นการตอบสนองจาก event processor Warehouse ต่ออีกที processor นี้จะตอบสนองและจัดการสต็อกที่สอดคล้องกันระหว่างคลังสินค้าต่างๆ พร้อมสั่งซื้อสินค้าเพิ่มหากสต็อกเหลือน้อยเกินไป เมื่อสต็อกถูกเติมเต็มแล้ว event processor Warehouse จะ trigger derived event stock replenished ซึ่ง event processor Inventory จะตอบสนองด้วยการปรับปรุงสต็อกปัจจุบัน

ในกรณีนี้ event processor Inventory จะไม่ trigger event inventory adjusted ที่สอดคล้องกันอีก เพราะถ้าทำเช่นนั้นจะนำไปสู่สิ่งที่เรียกว่า poison event ซึ่งก็คือ event ที่วนลูปไปเรื่อยๆ ไม่มีที่สิ้นสุด

Warning (คำเตือน)

poison event เกิดขึ้นเมื่อ derived event ถูก trigger และตอบสนองต่อกันไปมาเป็นลูปต่อเนื่องระหว่าง service ต่างๆ สิ่งนี้เกิดขึ้นได้บ่อยเมื่อใช้ event-driven architecture ดังนั้นควรระวังไม่ให้เกิดขึ้น

event processor Payment ก็ตอบสนองต่อ derived event order placed เช่นกัน โดยตอบสนองด้วยการเรียกเก็บเงินจากบัตรเครดิตของลูกค้า Figure 15-3 แสดงให้เห็นว่ามี derived event ที่เป็นไปได้สองแบบที่จะถูกสร้างขึ้นจากการกระทำของ event processor Payment แบบหนึ่งคือแจ้งระบบส่วนที่เหลือว่าการชำระเงินสำเร็จ ( payment applied ) และอีกแบบคือแจ้งว่าการชำระเงินถูกปฏิเสธ ( payment denied ) event processor Notification สนใจ derived event payment denied เพราะถ้าเกิดเหตุการณ์นี้ขึ้น มันต้องส่งอีเมลแจ้งลูกค้าว่าต้องอัปเดตข้อมูลบัตรเครดิตหรือเลือกวิธีชำระเงินอื่น

event processor Order Fulfillment ฟัง derived event payment applied และทำหน้าที่อัตโนมัติต่างๆ ในขั้นตอนการหยิบและแพ็กสินค้า เช่น บอกพนักงานว่าจะหาสินค้าได้ที่ไหนและต้องใช้กล่องขนาดใดสำหรับคำสั่งซื้อนั้น เมื่อเสร็จแล้ว มันจะ trigger derived event order fulfilled เพื่อแจ้งระบบส่วนที่เหลือว่าได้ดำเนินการคำสั่งซื้อเสร็จแล้ว ทั้ง event processor Notification และ Shipping จะฟัง derived event นี้ โดย event processor Notification จะแจ้งลูกค้าพร้อมกันว่าคำสั่งซื้อพร้อมสำหรับจัดส่งแล้ว ส่วน event processor Shipping จะเลือกวิธีจัดส่ง จัดส่งคำสั่งซื้อ และส่ง derived event order shipped ออกไป event processor Notification จะฟัง derived event order shipped นี้ด้วยและแจ้งลูกค้าว่าคำสั่งซื้อกำลังจัดส่งอยู่

event processor ทั้งหมดนี้ decoupled สูงและเป็นอิสระจากกัน วิธีหนึ่งที่จะเข้าใจ workflow การประมวลผลแบบอะซิงโครนัสนี้คือคิดเหมือนกับการวิ่งผลัด ในการวิ่งผลัด นักวิ่งจะถือไม้ (ท่อนไม้) แล้ววิ่งไปในระยะทางหนึ่ง (เช่น 1.5 กิโลเมตร) จากนั้นส่งไม้ต่อให้นักวิ่งคนถัดไป ซึ่งจะทำแบบเดียวกันไปเรื่อยๆ จนกว่านักวิ่งคนสุดท้ายจะข้ามเส้นชัย เมื่อนักวิ่งส่งไม้ต่อแล้ว นักวิ่งคนนั้นก็หมดหน้าที่ในการแข่งขันและไปทำอย่างอื่นได้ event processor ก็เช่นกัน เมื่อ event processor ส่งต่อ event ไปแล้ว มันจะไม่เกี่ยวข้องกับการประมวลผล event นั้นอีกต่อไป และพร้อมที่จะตอบสนองต่อ initiating event หรือ derived event อื่นๆ ต่อไป นอกจากนี้ event processor แต่ละตัวยังสามารถ scale ได้อย่างอิสระเพื่อรองรับสภาวะโหลดที่เปลี่ยนแปลงหรือการค้างของงาน