Message Queue
with RabbitMQ and Node.js
Who am I ?
Frontend Developer who
like backend technology but have no relevant work experience.
Application Intergration
在一個系統中,一般不會只有一隻程式在運作,而是會有多隻程式同時負責各種不同的任務,而程式之間難免會有互相傳遞資料進行處理的需求,而這類的需求,以下都統稱為 applcation 的整合。
一般常見的 application 整合方式大概可以分為以下幾種
What is message queue?
What is message queue?
訊息佇列(Message Queue,簡稱MQ),從字面意思上看,本質是個佇列,FIFO先入先出,只不過佇列中存放的內容是message。
其主要用途:
- 不同程序 Process 之間
- 不同執行緒 Thread 之間
- 不同服務之間 (Microservice)
的訊息溝通
Queue
queue 是將等待處理的任務排好,之後依照順序將任務從 queue 中取出處理(先進先出), Message Queue 就是將存在 queue 中的 message 在兩端(Producer、Consumer)中傳遞。
Message
Message 其實就是 sender 與 reciever 之間傳遞的資料,例如通知一個服務執行某項任務的訊息或是傳遞一項 task 執行後的相關資訊
基本上 message queue 的架構由 Producers 、 Message Queue 、 Consumers 組成, Producers 負責創建訊息並傳遞訊息至 Message Queue,Consumers 負責從 queue 中取出訊息並執行對應的行為。存放在 queue 中的 Message 會在被 Consumers 接收後才會移除。
Message Queue 的特性
Asynchronous Communications Protocol
Producers 傳送訊息至 Message Queue 之後不需要立即得到 response 以繼續處理其他事情。
舉例: Email,你在送出 email 之後不會特別去確認信件真的傳遞到對方信箱,而是會繼續去做其他事情。
Message Queue 的優勢
Better performence
- 非同步溝通
- consumer 有空時才會處理 message
- 比起持續 polling 的方式相對有效率
Decoupling
- 將 publisher 與 consumer 進行 decouple 了,因此程式開發人員可以各自專心負責規模較小 & 單純的程式開發工作
- publisher 與 consumer 不需要知道雙方的實際的位置(例如:IP address),只要將資料往 message queue 送就好
- break up apps && migrate to microservice
Message Queue 的優勢
Reliablity
- queue 使 data 不易丟失
- 即使 consumer 短暫的無法提供服務也沒關係,message queue 可以將資料暫存起來,等待 consumer 重新上線時再送過去
Flexiability of scaling
- producer, queue, consumer 可以依照需求擴張或縮減
Message queue simple use case
Q:假設你擁有一個 web service,每秒需要接受大量 request,request 不能被丟失,但 request 又要經過一個大量運算的 function 才能得到 response....
換句話說,你需要你的 server 可以保持在可以接收 request 的狀態,不被前一個 request block 住。
Message queue simple use case
A:在 web service 跟 process service 中間加入 message queue。
1. web service 收到 request 時傳送 "start processing" 的 message 到 queue 裡
2. process service 按照順序處理訊息
3. 兩個 service 獨立運作且不需要互相等待
4. 大量 request 進來 process service 依然能夠處理
5. 需求變多系統需要 scaling ? Add more consumers.
Microservice
RabbitMQ
Why RabbitMQ
自己實作 queue 不行?用 db 當 queue 不行?
試問如何解決:
避免兩個Consumer同時拿到同一個Message
Error Handling
Message 的順序問題
其他 message queue
- Kafka
- AWS SQS
RabbitMQ是實現AMQP(Advanced Message Queuing Protocol,進階訊息佇列協議) 中間件設計的一種。伺服器端用Erlang語言編寫,支持多種客戶端,如:Python、Ruby、.NET、Java、JMS、C、PHP、ActionScript、XMPP、STOMP等,亦支持AJAX。用於在分布式系統中存儲轉發訊息,在易用性、擴展性、高可用性等方面表現不俗。
RabbitMQ 元件介紹
RabbitMQ 元件介紹
producer:
負責丟訊息到 Queue 中
若有定義 Exchange,則丟給 Exchange 決定要給誰
consumer:
負責接收來自 Queue 的訊息
queue:
負責存放所需要的資料
跟資料結構的 Queue 一樣,有先進先出 (FIFO) 特性
每個 Queue 都會有他的名字當 id
RabbitMQ 元件介紹
exchange:
用來決定 Producer 給的資料要丟給哪一個Queue
主要有這四種方式:
- direct: 直接丟給指定的 Queue
- topic: 類似 regular expression,設定 binding 規則,丟給符合的 Queue
- headers: 透過傳送資料的 header 來特別指定所要的 Queue
- fanout: 一次丟給全部負責的 Queue
透過以上概念可以做到什麼事?
RabbitMQ 元件屬性
RabbitMQ 失敗重試處理
如何實作“可靠”的訊息佇列?
錯誤處理 (Error handling) : 訊息處理失敗怎麼辦?
retry -> retry 一定次數仍然不行? -> 人為處理
deck
By oldmo860617
deck
- 619