แนวทางการพัฒนา Event-Driven Architectures ด้วย Azure Event Grid ครับ

เรียนรู้แนวทางของ Event-Driven Architecture และตัวอย่างการพัฒนาด้วย Azure Event Grid (Custom Topic, Web Hooks)

Ponggun
T. T. Software Solution
8 min readMay 26, 2021

--

Azure Event Grid with Custom Topic and Web Hooks

Request-Response Driven

Request-Response Driven เป็นระบบที่ควบคุมมีการทำงานระหว่างบริการ (Service) ต่างๆ โดยมีการ Request จาก Client เข้ามายัง Server หลังจากนั้น ระบบจะทำการประมวลผลเป็นลำดับขั้นตอนระหว่าง Service จาก 1 ไป 2 ไป 3 จนกระทั่งได้ Response กลับไปยัง Client

ตัวอย่างเช่น ระบบลงทะเบียนคนไข้

  1. Registration Service — คนไข้ (Client) กรอกแบบฟอร์มเพื่อลงทะเบียนในระบบ เสร็จแล้ว Registration Service ทำการเรียกบริการอีก 3 ส่วนเพื่อดำเนินการลงทะเบียนจนแล้วเสร็จ
  2. User Profile Service — ระบบ (Server) จัดเก็บข้อมูลการลงทะเบียนลงฐานข้อมูล
  3. Notification Service — ระบบ (Server) ส่ง Email ไปยืนยันที่ Mailbox ของคนไข้
  4. Report Service — ระบบ (Server) เก็บข้อมูลสถิติของการลงทะเบียนในรอบเดือน

ระบบจะทำงานและถูกควบคุมตามลำดับด้วย Registration Service จนแล้วเสร็จ ซึ่งก่อให้เกิดการรอการทำงาน (Synchronous) และก่อให้เกิดการเชื่อมโยงระหว่างบริการต่างๆ (Service) ในระบบจะค่อนข้างยึดกันอย่างแน่นหนา (High Coupling)

ขั้นตอนการทำงานแบบตามลำดับ (Synchronous)

ซึ่งการทำงานในรูปแบบนี้เหมาะสมกับการรับส่งข้อมูลภายในระบบดี เพราะโครงสร้างที่ไม่ซับซ้อนและจัดการง่าย

แต่ถ้าเราต้องการส่งต่อข้อมูลนี้ออกไปยังระบบภายนอกจำนวนมากๆละ

มีระบบภายนอกมาเชื่อมต่อ 5 ระบบ

เราสามารถที่จะพัฒนา REST API เพื่อให้ระบบภายนอกเข้ามาดึงข้อมูลของเราก็ได้ แต่ถ้าต้องการข้อมูลแบบ Real Time นั้นแปลว่าระบบภายนอกจะต้องเข้ามาดึงข้อมูลที่ Server เราตลอดเวลา ยิ่งมีข้อมูลเยอะก็จะเกิดการใช้ทรัพยากรบนระบบของเรามากเกินไป ซึ่งแนวทางนึงที่สามารถช่วยแก้ไขปัญหาในเรื่องนี้ได้คือ

Event-Driven Architecture

Event-Driven Architecture

Event-Driven Architecture จะมีความแตกต่างตรงที่จะมีตัวกลางคอยเชื่อมบริการต่างๆ (Service) กันอย่างหลวมๆ (Loosely Coupling) และการทำงานจะไม่ต้องรอกันตามลำดับ (Asynchronous) โดยจะใช้เหตุการณ์ (Event) ที่เกิดแทนในการเริ่มการทำงานแทนครับ

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

ซึ่งเราจะเรียกผู้สร้างเหตุการณ์ว่า Event Producer, ผู้สนใจเหตุการณ์ว่า Event Consumer, ช่องทางในการรับและส่ง Event ว่า Event Broker

รูปแบบการสื่อสารจะเกิดขึ้นเมื่อ

  1. Event Producer มีการลงทะเบียน (Publish) ว่าจะส่งข้อมูลเข้ามาที่ Event Brokerเมื่อมี Event เกิดขึ้น
  2. Event Consumer มีการลงทะเบียน (Subscribe) ที่ Event Broker เพื่อแจ้งความประสงค์ที่จะรับข้อมูลที่เกิดจาก Event
  3. เมื่อมีการทำงานเกิดขึ้น Event Producer จะ Publish Event ขึ้นที่ Event Broker หลังจากนั้น Event Broker จะส่งต่อ Event ไปยัง Event consumer ที่ Subscribe ไว้ (Notification)
Event-Driven Architecture

ตัวอย่างระบบลงทะเบียนคนไข้ในแบบ

Event-Driven Architecture

ขั้นตอนการลงทะเบียน

  1. Event Producer (ระบบ) มีการลงทะเบียนกับ Event Broker ในการส่งต่อข้อมูลจาก Registration Service ไปยังบริการอื่นๆเมื่อมี Event คนไข้สมัครสมาชิก
  2. Event Consumer (User Profile Service, Notification Service, Report Service) ลงทะเบียนกับ Event Broker เพื่อรอรับข้อมูลจาก Event ที่มีคนไข้สมัครสมาชิก

ขั้นตอนการทำงาน

1.Registration Service — คนไข้กรอกแบบฟอร์มเพื่อลงทะเบียนในระบบของเรา

2.Registration Service — สร้าง Event คนไข้สมัครสมาชิกไปยัง Event Broker

3.User Profile Service — ระบบนำข้อมูลที่ได้จาก Event ไปจัดเก็บลงฐานข้อมูล

3.Notification Service — ระบบนำข้อมูลที่ได้จาก Event ไปส่ง Email ยืนยันที่ Mailbox ของคนไข้

3.Report Service — ระบบนำข้อมูลที่ได้จาก Event ไปเก็บเป็นสถิติของการลงทะเบียนในเดือน

ซึ่งเราจะสังเกตุว่าในขั้นตอนที่ 3 นั้นจะทำงานพร้อมๆกันเลยทั้ง User Profile Service, Notification Service, Report Service ครับ ไม่จำเป็นต้องรอให้เหตุการณ์ก่อนหน้านั้นทำงานเสร็จก่อน (Asynchronous)

Web Hooks

ตัวอย่างที่เห็นได้บ่อยๆในปัจจุบันคือการใช้ Web Hooks ในการส่งต่อข้อมูลจากระบบนึงไปยังอีกระบบนึงเมื่อมี Event เกิดขึ้น ดังเช่นภาพข้างล่างนี้นะครับ

ตัวอย่าง SCB Web Hooks สำหรับบริการจ่ายเงินด้วย QR Code นะครับ ซึ่งเมื่อมีการจ่ายเงินแล้วทาง SCB จะส่งข้อมูลกลับมายังระบบของเรา ซึ่งเราได้ทำการลงทะเบียนไว้กับทาง SCB ว่าให้ส่งข้อมูลเข้ามาที่ช่องทางนี้

Azure Event Grid

เป็นบริการบน Azure ในรูปแบบ Publish-Subscribe Model ที่จะช่วยกระจายข้อมูลเมื่อมี Event เกิดขึ้น โดยที่ต้นทางและปลายทางสามารถเป็นได้ทั้งบริการบน Azure หรือเป็นระบบที่ทำขึ้นมาเองครับ ทำให้เราสามารถพัฒนาระบบแบบ Event-Based หรือว่า Serverless ได้สะดวกรวดเร็วขึ้นครับ

องค์ประกอบ

choose-a-messaging-model-in-azure-to-connect-your-services
  • Events — คือเหตุการณ์ที่เกิดขึ้น ตัวอย่างเช่น มีการอัพโหลดไฟล์ใหม่ขึ้น File Server
  • Event sources (Event Producer) — คือตำแหน่งที่เหตุการณ์นั้นเกิดขึ้น เช่นในที่นี้คือ File Server
  • Topics (Event Broker) — เป็นช่องทางที่ Event Source จะ Publish Event เข้ามา ส่วนใหญ่จะเป็นบริการบน Azure เองครับ เช่น Azure Blob Storage (File Server) แต่ในบทความผมจะพูดถึง Custom Topic ซึ่งเป็นการเขียน Code จากระบบของเราเองเพื่อสร้าง Event ใน Azure Event Grid เพื่อให้เห็นว่าเราไม่จำเป็นว่าต้องอยู่บน Azure เท่านั้นก็สามารถใช้บริการบางส่วนของ Azure มาช่วยได้ครับ
  • Event subscriptions (Event Broker)— เป็นช่องทางที่ผู้รับเหตุการณ์ (Subscriber) จะเข้ามา Subscribe เพื่อรับข้อมูลเมื่อมี Event เกิดขึ้น
  • Event handlers (Event Consumer)— บริการที่จะรองรับข้อมูลที่ส่งมาจาก Event Subscriptions และนำไปประมวลผลต่อ โดยที่ Event Source ไม่จำเป็นต้องทราบว่าจะทำอะไรต่อบ้าง ส่วนใหญ่จะเป็นบริการบน Azure เช่น Low Code แบบ Azure Logic App หรือ Serverless แบบ Azure Functions แต่ในบทความผมจะพูดถึง Web Hooks ซึ่งจะทำให้เราสามารถส่ง Event ต่อไปยังระบบอื่นๆของเราได้ครับ ไม่จำเป็นว่าต้องอยู่บน Azure เท่านั้น
ตัวอย่างการนำ Azure Event Grid ทำงานร่วมกับ Azure Function เพื่อวิเคราะห์ภาพที่ถูกอัพโหลดขึ้น Azure Blob Storage

ประโยชน์ที่ได้รับ

ถ้าเรามี Requirements ที่ต้องการส่งข้อมูลจากระบบเราไปยังระบบภายนอก โดยที่ปล่อยให้ปลายทางเป็นคนพิจารณาในการนำข้อมูลไปใช้ต่อเองนั้นจะช่วยให้เราลดเวลาในการพัฒนาในส่วนของการทำ Publishing/Subscription ลงได้เยอะเลยครับ โดยเฉพาะถ้าเราต้องการให้ข้อมูลใน 1 เหตุการณ์นั้นส่งต่อไปยังหลายๆที่พร้อมๆกัน (Fan-out) Event Grid จะช่วยตอบโจทย์ตรงนี้มากๆเลยครับ

ข้อสังเกตุ

ถ้าใช้ในรูปแบบ Web Hooks นั้น ปลายทางต้องสามารถที่จะพัฒนา Web API ให้รองรับการติดต่อกับ Event Grid ทั้งการยืนยันตัวตนและการรับส่งข้อมูล

เมื่อใช้บริการบน Azure ก็จะมีค่าใช้จ่ายครับ แต่ราคาผมมองว่าค่อนข้างคุ้ม เพราะ 1 แสน Requests แรกต่อเดือนนั้นฟรีเลยครับ หลังจากนั้นจะคิดราคาทุก 1 ล้าน Requests ที่ $0.60 ต่อเดือน

ขั้นตอนการพัฒนา Event-Driven Architectures ด้วย Azure Event Grid แบบ Custom Topic และ Web Hooks

รูปแบบการใช้งาน Event Grid ด้วย Custom Topic + Web Hooks

1. ต้องพัฒนา Web API แบบ HTTP Method Post เพื่อรองรับ Request Payload 2 แบบนะครับ

1.1. Payload สำหรับการยืนยันตัวตนระหว่าง Event Grid และ Web API ครับ ซึ่ง Event Grid จะส่ง Code มาให้เราและให้เรา Response Code นั้นกลับไป โดยจะทำแค่ครั้งเดียวตอนที่เราเพิ่ม Web Hooks Endpoint ที่ Event Grid นะครับ

1.2. Payload สำหรับการส่ง Event จาก Event Grid ไปยัง Web API ซึ่งในรอบนี้ เราไม่จำเป็นต้อง Response อะไรกลับไปนะครับ เพราะ Event Grid แค่ต้องการจะส่งข้อมูลมาให้เฉยๆ

ตัวอย่าง Web API ที่พัฒนาด้วย JavaScript เพื่อรองรับ Payload ทั้ง 2 แบบ

ศึกษาเพิ่มเติมที่ https://docs.microsoft.com/th-th/azure/event-grid/receive-events

2. สร้าง Custom Topic โดยทำการเลือกสร้างบริการ Azure Event Grid Topics

3. เพิ่ม Web Hooks Endpoint ไปยัง Azure Event Grid Topics

4. ทดสอบการทำงานโดยการเขียน Request ไปยัง REST API บน Azure Event Grid Topics เพื่อสร้าง Event และดูผลของ Web Hook ที่เกิดขึ้นบน Web API ของเรา

เริ่มทดลองใช้งานจริง

สร้าง Azure Event Grid

ใน ขั้นตอนแรกนั้นให้เราเข้าไปที่ Azure Portal — Subscript ของเราก่อนเพื่อทำการเปิดใช้งาน Event Grid resource provider ถึงจะสามารถสร้าง Event Grid ได้นะครับ

สร้าง Event Source Custom Topic เพื่อเป็นช่องทางในการ Publish Event

  • พิมพ์คำว่า Event Grid Topics ที่ช่อง Search
  • เลือก Event Grid Topics
  • เลือก Add เพื่อสร้าง Topic
  • ที่ Tab Basic — ระบุ Subscription, Resource Group, Topic Name และ เลือก Region Southeast Asia ที่ใกล้ไทยที่สุด
  • ที่ Tab Advance- เลือก Event Grid Schema และเลือก Create
  • เราจะเห็น Topic อยู่ข้างล่างตามภาพนี้นะครับ

ทดสอบการเชื่อมต่อของ Azure Event Grid ในแบบ Web Hooks

ในหัวข้อก่อนหน้านี้เราได้อธิบายว่าการสร้าง Web Hooks Endpoint ใน Azure Event Grid นั้นจะมีการส่ง Validation Payload ไปยัง Web Hooks ของเรานะครับ

ในขั้นตอนนี้ผมเลยอยากมาพิสูจน์กันว่าข้อมูลที่ Event Grid ส่งมานั้นหน้าตาของจริงเป็นยังไงบ้าง โดยใช้วิธีง่ายๆคือสร้าง Mock Web Hooks บน Website webhook.site ครับผม

  • เข้า https://webhook.site/
  • ระบบจะทำการสร้าง Web Hooks Endpoint ให้เราครับ
  • ให้เรา Copy Web Hooks Endpoint นั้นเก็บไว้นะครับ
  • กลับมาที่ Azure Event Grid
  • เลือก + Event Subscription
  • เลือก Endpoint Type เป็น Web Hook
  • ระบุ Endpoint เสร็จแล้วกด Create เพื่อให้ Event Grid ส่ง Validation Event ไปยัง Web Hooks ของเราครับ
  • เราจะพบว่าที่ Azure Event Grid นั้นจะทำการส่ง Validation Event ด้วย Validation Code ไปหา Web Hooks ของเราและรอให้ Web Hooks ส่ง Code นั้นกลับมาเพื่อยืนยันการเชื่อมต่อ แต่เมื่อ Web Hooks ของเราไม่ได้มี Logic ที่จะส่ง Validation Code กลับไป ทำให้การทำงานไม่สมบูรณ์นะครับ
รอประมาณ 10 นาทีแล้วทาง Azure จะแจ้งว่าไม่สามารถเพิ่ม Endpoint ได้เพราะว่าไม่ได้รับ Validation Code กลับมาจาก Web API ครับผม

พัฒนา Web API เพื่อรองรับ Web Hooks จาก Azure Event Grid

  • Microsoft ได้เตรียม Code ตัวอย่าง ASP.NET Core 3.1 และใช้ SignalR (Web Socket) เพื่อแสดงผลข้อมูลที่ได้รับจาก Web Hooks แบบ Realtime
  • ให้เราทำการ Clone Repository ข้างล่างนี้น่ะครับ
  • เสร็จแล้วเปิด Code ด้วย VS Code หรือ VS Studio 2019 นะครับ (ในบทความนี้ผมเลือก VS Studio 2019 ครับ)
  • ให้เรารัน Code จน Website แสดงขึ้นมาจะได้หน้าตาแบบนี้นะครับให้เปิดค้างไว้ได้เลย
เดี๋ยวเวลามีข้อมูลเข้ามาแล้วจะแสดงผลที่ Website แบบ Realtime เลยครับผ่าน Web Socket
  • ระบบจะรองรับ Input ผ่าน RESTful API ที่ช่องทางนี้นะครับ
{POST} /api/updates
  • โดยจะรับ Payload สองแบบคือ Validation Event และ Custom Event ครับ
  • ทดสอบ Website ของเราด้วย Postman กันครับ โดยให้ทำงาน Download Postman Collection ข้างล่างนี้นะครับ
  • เสร็จแล้วให้เราแตก Zip Files และนำทั้ง Environment, Collection ไป Import ใน Postman นะครับ
  • ผลลัพธ์ที่ได้บน Postman นะครับ
  • ให้เราทำการเลือก Environment ก่อนและแก้ไขค่าตามนี้นะครับ
  • APIEndpoint ให้ระบุ Endpoint ที่รัน Website ของเราบน Browser
  • AzureEventGridEndpoint ให้ระบุ Endpoint ของ Event Grid Custom Topic
  • AzureEventGridKey ให้ระบุ Key ของ Event Grid Custom Topic
  • เสร็จแล้วให้เลือก Environment นั้นบน Dropdown
  • ตอนนี้เราได้เตรียม Postman Environment พร้อมแล้วครับ ต่อไปให้เราทำการเปิด Collection และทำการรัน 1.Event Grid Validation เพื่อทดสอบว่า Web API สามารถรับ Validation Code จาก Event Grid และ Response ได้ถูกต้อง
  • จากภาพข้างบนจะพบว่าระบบ Response Code กลับมาได้ถูกต้องแล้วนะครับ แสดงว่า Web API ของเราสามารถที่จะเชื่อมกับ Azure Event Grid ได้แล้ว
  • ลองย้อนกลับมาดูที Website ของเราจะเห็นข้อมูลที่ส่งมาแสดงผลพร้อมกับ Event Type ครับ
  • ทำการรัน 2. Event Grid notificationเพื่อทดสอบว่า Web API สามารถรับ ข้อมูลจาก Event Grid ได้ถูกต้อง

เปิดให้ Website เข้าถึงได้จากภายนอก ด้วย Ngrok

เพราะว่าในตอนนี้ Azure ไม่สามารถเข้าถึง Website ของเราได้ครับ เราจึงนำ Ngrok เข้ามาช่วย Expose Website โดยมีขั้นตอนดังนี้

https://www.somkiat.cc/expose-localhost-to-anywhere/
  • Download และติดตั้ง Ngrok จาก https://ngrok.com/download
  • สมัครสมาชิก Ngrok ใน Website และนำ Token มาเก็บไว้
  • เปิด Ngrok ในเครื่องของเราเพื่อยืนยันตัวตนด้วยคำสั่ง
./ngrok authtoken <your_auth_token>
  • เสร็จแล้ว Expose Website ของเราด้วยคำสั่งข้างล่างนี้
.\ngrok http https://localhost:<port> -host-header="localhost:<port>" -region ap
  • Ngrok จะสร้าง Public Endpoint ที่สามารถเข้าถึงได้จากภายนอกและต่อมายัง Website ของเราใน Local นะครับ ให้คัดลอก Public Endpoint นั้นไว้
  • ทดลองใช้งาน Public Endpoint ด้วยการแก้ไข APIEndpoint ใน Postmtan ให้เปลี่ยนจาก Local ไปเป็น Public Endpoint
  • ทดลองรัน Postman Collection 1.Event Grid Validation และ 2. Event Grid notification อีกรอบเพื่อทดสอบว่า Public Endpoint ทำงานได้ถูกต้องครับ

Subscribe Public Endpoint to Azure Event Grid

  • หลักจากที่เรามี Public Endpoint พร้อมแล้ว ให้เราทำการ Subscribe Event บน Event Grid กันนะครับ
  • โดยกลับไปที่ Azure Event Grid Topics -> + Event Subscription
  • ระบุชื่อ Subscription -> เลือก Web Hooks -> ระบุตำแหน่งของ Endpoint ใน format
{Public API Endpoint}/api/updates
  • เมื่อเรากด Create จะพบว่า Event Grid จะส่ง Validation Event มาที่ Public Endpoint ของเรานะครับ

รัน Postman เพื่อสร้าง Event บน Event Grid

  • ในขั้นตอนสุดท้ายนี้เราจะใช้ RESTful API บน Event Grid เพื่อจำลองการสร้าง Event ขึ้นนะครับ
  • โดยให้เรากลับไปที่ Postman Collection และรัน 3. Generate Event To Event Grid ครับ เราจะพบว่า Azure Event Grid ได้ทำการสร้าง Event และส่งต่อไปยัง Subscription ของเรา นั้นคือ Web Hooks -> Web API นั้นเองครับ จบแว้วววววววว

ขอบคุณผู้อ่านทุกๆท่านมากๆเลยนะครับ ผมไม่ได้เขียนบทความมานานหลายเดือนแล้ว ด้วยปริมาณงานที่มากขึ้นและอยากให้เวลากับการออกกำลังกายมากขึ้น (ผมแบ่งเวลาไปหัดเล่น Surfskate ครับ)

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

ดีใจที่ได้กลับมาเขียนอีกนะครับ รอบนี้ใช้เวลาศึกษา, ทดลองใช้, ใช้ในงานจริง, เขียนบทความ อยู่หลายสัปดาห์เลยครับ ผมตั้งใจกับบทความนี้มากๆเลยครับ หวังว่าเนื้อหาจะมีประโยชน์กับผู้อ่านนะครับ ^^

นายป้องกัน

--

--

Ponggun
T. T. Software Solution

Development Manager, Web Developer with ASP.Net, ASP.net Core, Azure and Microsoft Technologies