Rabbit MQ มีองค์ประกอบอย่างไร
ภาพจาก: Introduction to RabbitMQ, Randhir Kumar, Software Consultant, Knoldus Inc.
องค์ประกอบของ Rabbit MQ มีดังนี้
- Producer : โปรแกรมที่เป็นผู้ส่ง Message (Publish Message) โดยที่ Message อาจจะเป็นงานที่ต้องการส่งให้ระบบอื่นไปทำ หรืออาจเป็นการแจ้งข้อมูลข่าวสารให้ระบบอื่น ๆ รับทราบ
- Exchange : ทำหน้าที่รับ Message และนำส่ง Message ไปให้ Queue ต่าง ๆ โดยพิจารณาจาก Routing Key ซึ่งเป็น Attribute ในแต่ละ Message
- Binding : คือ การกำหนด “Link” ว่า Queue ต่าง ๆ จะรับ Message ใดจาก Exchange โดย Binding จะเกี่ยวข้องกับ Routing Key และ Header
- Queue : ทำหน้าที่คล้ายตู้จดหมาย (Post Box) ซึ่งอยู่ภายใน Rabbit MQ เป็นที่เก็บ Message ทุกอย่างที่ผ่าน Rabbit MQ เข้ามาและออกไปยัง application โดยอาศัย Memory และ Disk ของเครื่อง Host ทำหน้าที่เป็น Buffer สำหรับเก็บ Message ดังนั้นปริมาณ Message ที่เก็บได้ ก็จะขึ้นกับขนาดของ Memory และ Disk ที่มี ในการใช้งาน Queue นั้น สามารถให้หลาย ๆ Producer ส่ง Message เข้าไปที่ Queue เดียวกันได้ และสามารถให้หลาย ๆ Consumer รับ Message จาก Queue เดียวกันได้เช่นกัน
- Consumer : โปรแกรมที่เป็นผู้รอรับ Message (Consume Message) โดยอาจจะเป็นระบบที่รับงานจาก Producer มาดำเนินการ หรือรับข้อมูลข่าวสารมาอัพเดตในระบบ หรือส่งต่อให้ระบบอื่น
ประเภทของ Exchange
Rabbit MQ รองรับ Exchange ได้หลายประเภท เช่น Direct, Fanout, Topic, Header เป็นต้น แต่ละประเภทจะมีวิธีต่างกันในการกำหนด Binding เพื่อเชื่อมโยงกับ Queue
ภาพจาก: https://www.cloudamqp.com/blog/part1-rabbitmq-best-practice.html
1. Direct Exchange
Direct Exchange จะส่ง Message โดยอาศัย Routing Key เป็นตัวกำหนดว่า Message จะถูกส่งอย่างเจาะจงไปยัง Queue ที่มี Binding Key ตรงกับ Routing Key เท่านั้น
ตัวอย่างเช่น ระบบงานเพื่อประมวลผล pdf_events ประกอบด้วย Direct Exchange 1 ตัว และ Queue 2 ตัว
- Queue A สำหรับทำงาน pdf create และมี routing key คือ pdf_create
- Queue B สำหรับทำงาน pdf log และมี routing key คือ pdf_log
การทำงานเริ่มจาก Exchange ได้รับ Message จาก Producer เข้ามา Exchange จะตรวจสอบ Binding key ที่แนบมากับ Message ถ้า Routing key เป็น pdf_create ก็จะส่ง Message ไปยัง Queue A (เนื่องจากมี Binding key = pdf_create ตรงกัน) หรือถ้า Routing key เป็น pdf_log ก็จะส่งไปยัง Queue B (เนื่องจากมี Binding key = pdf_log ตรงกัน)
ภาพจาก: https://www.cloudamqp.com/blog/part4-rabbitmq-for-beginners-exchanges-routing-keys-bindings.html
2. Fanout Exchange
Fanout Exchange ทำการส่ง Message ไปยังทุก Queue ที่ผูกกับ Exchange นั้น โดยไม่สนใจ Routing Key วิธีการนี้เหมาะสำหรับงานลักษณะ Broadcasting
ภาพจาก: https://www.cloudamqp.com/blog/part4-rabbitmq-for-beginners-exchanges-routing-keys-bindings.html
ตัวอย่างการใช้งาน #1
เมื่อระบบประมวลผลข่าวกีฬา (Sports News) ได้บันทึกข้อมูลข่าวกีฬาใหม่แล้ว ทำการ Publish Message นี้ (ซึ่งมีรายละเอียดของข่าว) ลงใน Fanout Exchange จากนั้น Fanout Exchange ทำการ Broadcast ไปยังระบบช่องทางการรายงานข่าวต่างๆ เช่น ช่องทาง Web, Mobile, TV, Radio ซึ่งแต่ละช่องทางสามารถมีวิธีการนำข้อมูลรายละเอียดของข่าวไปใช้งานแตกต่างกัน
ตัวอย่างการใช้งาน #2
เมื่อระบบงาน HR ได้บันทึกข้อมูลพนักงานใหม่แล้ว ทำการ Publish Message ลงใน Fanout Exchange ซึ่ง Messageประกอบด้วยข้อมูลของพนักงานใหม่ จากนั้น Fanout Exchange ทำการ Broadcast ไปยังระบบงานอื่นที่เกี่ยวข้อง เช่น ระบบการจองคอมพิวเตอร์ เพื่อจองเครื่องให้กับพนักงานใหม่, ระบบการพิมพ์นามบัตร เพื่อจัดพิมพ์นามบัตรให้กับพนักงานใหม่, ระบบการฝึกอบรม เพื่อจองวันปฐมนิเทศพนักงานใหม่ เป็นต้น ระบบงานเหล่านี้สามารถรับ Message ไปประมวลผลได้ทันที นอกจากนี้ระบบงาน HR ซึ่งเป็น Publisher ก็ทำงานแบบ Asynchronous คือสามารถทำงานอื่นของตนเองต่อได้ โดยไม่ต้องรอผลลัพธ์จากระบบงานอื่นๆ กลับมาก่อน
3. Topic Exchange
Topic Exchange เหมาะสำหรับงานลักษณะ Multicast เพื่อส่ง Message ให้กับ Consumer บางส่วน โดยอาศัยการ Match Pattern ของ Routing Key กับ Binding Key โดย Routing Key มีลักษณะเป็นคำคั่นด้วยจุด เช่น agreements.eu.stockholm
ภาพจาก: https://www.cloudamqp.com/blog/part4-rabbitmq-for-beginners-exchanges-routing-keys-bindings.html
ตัวอย่างเช่น ระบบงานสำหรับประมวลผล agreements ใช้ Topic Exchange และ Queue 3 ตัว ดังนี้
Queue A | สำหรับรับ Message ที่เกี่ยวกับ agreement ของ berlin เท่านั้นและกำหนด | routing key = agreements.eu.berlin.# |
Queue B | สำหรับรับ Message เกี่ยวกับ agreement ทุกอย่าง | routing key = agreements. # |
Queue C | สำหรับรับ Message เกี่ยวกับ agreement ของ headstore | routing key = agreements.*.headstore |
หมายเหตุ:
- เครื่องหมาย * หมายถึงตำแหน่งนี้ต้องมีคำปรากฏ 1 คำ
- เช่น binding key = “agreements.*.*.b.*” หมายถึง คำที่หนึ่งเป็น agreements, คำที่สี่เป็น b, ส่วนคำที่สอง สาม และห้า เป็นคำอะไรก็ได้แต่ต้องมี
- เครื่องหมาย # หมายถึงตำแหน่งนี้จะมีคำใดๆปรากฏหรือไม่มีเลยก็ได้
- เช่น binding key = “agreements.eu.berlin.#” หมายถึง คำที่หนึ่งเป็น agreements, คำที่สองเป็น eu, คำที่สามเป็น berlin, ส่วนคำที่สี่จะมีหรือไม่มีก็ได้
Example Scenario
Message #1 เข้ามา ด้วย routing key = agreements.eu. berlin.headstore | Message #1 จะถูกส่งไปยัง Queue A เนื่องจาก 3 คำแรก (agreements, eu, berlin) ตรงกับ binding key agreements.eu.berlin.headstore VS agreements.eu.berlin.#
Queue B เนื่องจากคำแรก (agreements) ตรงกับ binding key agreements.eu.berlin.headstore VS agreements.#
Queue C เนื่องจากคำที่หนึ่งและสี่ (agreements, headstore) ตรงกับ binding key agreements.eu.berlin.headstore VS agreements.*.headstore
|
Message #2 เข้ามา ด้วย routing key = agreements.eu. berlin.tailstore | Message #2 จะถูกส่งไปยัง Queue A, B Queue A เนื่องจาก 3 คำแรก (agreements, eu, berlin) ตรงกับ binding key agreements.eu.berlin.tailstore VS agreements.eu.berlin.#
Queue B เนื่องจากคำแรก (agreements) ตรงกับ binding key agreements.eu.berlin.tailstore VS agreements.#
|
Message #3 เข้ามา ด้วย routing key = agreements.us. headstore | Message #3 จะถูกส่งไปยัง Queue B, C Queue B เนื่องจากคำแรก (agreements) ตรงกับ binding key agreements.us.headstore VS agreements.#
Queue C เนื่องจากคำที่หนึ่งและสี่ (agreements, headstore) ตรงกับ binding key agreements.us.headstore VS agreements.*.headstore
|
4. Header Exchange
Header Exchange อาศัยข้อมูลใน Header ในการกำหนดเส้นทางการส่ง Message โดยไม่ได้อาศัย Routing Key
ภาพจาก: https://www.cloudamqp.com/blog/part4-rabbitmq-for-beginners-exchanges-routing-keys-bindings.html
ตัวอย่างเช่น ระบบงานสำหรับประมวลผล agreements ใช้ Header Exchange และ Queue 3 ตัว
Queue A | สำหรับรับ Message ที่รูปแบบเป็น pdf และเป็นข้อมูลประเภท report | x-match = all |
Queue B | สำหรับรับ Message ที่รูปแบบเป็น pdf และเป็นข้อมูลประเภท log | x-match = any |
Queue C | สำหรับรับ Message ที่รูปแบบเป็น zip และเป็นข้อมูลประเภท report | x-match = all |
X-match = any หมายถึง ต้องมี Header value อย่างน้อย 1 ตัว ใน Message ที่จะต้อง Match กับ Binding
ส่วน X-match = all หมายถึงทุก Header value ใน Message จะต้อง Match กับ Binding
Example Scenario
Message #1 มี Header Argument format=pdf, type=report | – Message #1 ถูกส่งไป Queue A เนื่องจาก Message Header ทั้ง format: pdf, type: report ตรงกับ Binding ทั้งหมดของ Queue A (X-Match = all) – Message #1 ถูกส่งไป Queue B ด้วย เนื่องจาก Message Header format: pdf, type: report ตรงกับ Binding ของ Queue B อย่างน้อย 1 ตัว (X-Match = any) – Message #1 ไม่ถูกส่งไป Queue C เนื่องจาก Queue C กำหนด X-Match = all คือต้องมีทั้ง format: zip และ type: log |
Message #2 มี Header Argument format=pdf | – Message #2 ถูกส่งไป Queue B เนื่องจาก Message Header มี format: pdf ตรงกับ Binding 1 อย่าง (X-Match = any) – Message #2 ไม่ถูกส่งไป Queue A เนื่องจาก Queue A กำหนด X-Match = all คือต้องมีทั้ง format: pdf และ type: report – Message #2 ไม่ถูกส่งไป Queue C เนื่องจาก Queue C กำหนด X-Match = all คือต้องมีทั้ง format: zip และ type: log
|
Message #3 มี ด้วย Header Argument format=zip, type=log | – Message #2 ถูกส่งไป Queue B เนื่องจาก Message Header มี type: log ตรงกับ Binding 1 อย่าง (X-Match = any) – Message #2 ไม่ถูกส่งไป Queue A เนื่องจาก Queue A กำหนด X-Match = all คือต้องมีทั้ง format: pdf และ type: report – Message #2 ไม่ถูกส่งไป Queue C เนื่องจาก Queue C กำหนด X-Match = all คือต้องมีทั้ง format: zip และ type: log
|
ทั้งหมดนี้ก็คือส่วนสำคัญของ Rabbit MQ ครับ หากใครยังไม่ทันได้อ่านตอนที่ 1 ไปติดตามกันในลิ้งก์ https://www.stream.co.th/rabbit-mq-part1/ นะครับ
สนใจโซลูชั่นด้านดิจิทัล สามารถติดต่อเราได้ที่อีเมล Marketing@stream.co.th หรือโทร. 02-679-2233 ครับ