--- title: 用 Docker 自架 RabitMQ tags: RabbitMQ description: Use `{%hackmd theme-dark %}` syntax to include this theme. --- # 用 Docker 自架 RabbitMQ ## 為何架設 RabbitMQ? ### 實現瀏覽器接收Server端主動傳遞的訊息(WebSocket/MQTT) #### WebSocket - 說明: - 用於 PC 上,Websocket 是基於 TCP 協議。同時借用 HTTP 的協議完成握手(handshake)。 主要解決 HTTP 協議中一個 request 對應一個 response 的尷尬。(http server 不能主動發送信息給 http client)。 - 白話文: - 第一次藉由HTTP方式達成協議後,Server 端擁有發送訊息給Client 端的主動權。 - 應用: - 網頁聊天室。 - 補充: - 凡 Client 端 是 Web,就是需要經過 WebSocket。 #### MQTT - 說明: - 跟 Websocket 一樣基於 TCP 協議。是輕量級基於代理的發布 / 訂閱的消息傳輸協議。不適用與 Web。 - 特點: - 使用發布 / 訂閱消息模式,提供一對多的消息發布。 - 有三種消息發布服務質量(Qos)。 - 小型傳輸,開銷很小(固定長度的頭部是 2 字節)。 - 應用: - 適合用於處理器資源及網路頻寬有限(網路差、不穩)的物聯網裝置。 #### MQTT over WebSocket - 說明: - 是把 MQTT control message 包裝成 WebSocket 包,通過 WebSocket 管道發送。即使用 WebSocket 來支持 MQTT Client 和 Broker 的連接。 - 應用: - 主要用於 MQTT 設備跟 Web 端通信。 ## 什麼是 RabbitMQ? - RabbitMQ 是實現了進階訊息佇列協定(AMQP)的開源訊息代理軟體(亦稱訊息導向中介層) - 白話文:實現 MQTT 功能的 Broker ## 安裝步驟 ### 安裝環境 - macOS 10.14.6 ### 安裝步驟 #### 直接 Run rabbitmq 的 image - `docker run -d --hostname my-rabbit --name some-rabbit -p 15672:15672 -p 5672:5672 -p 1883:1883 -p 15675:15675 daocloud.io/library/rabbitmq:3.7.4` - 15672 是 rabbitmq management 管理介面預設訪問埠 - 5672 是 amqp 預設埠 - 1883 是 mqtt tcp 協議預設埠 - 15675 是 web_mqtt websocket 協議預設埠 #### 啟動 rabbitmq 的 plugins - `docker exec ${container_id} rabbitmq-plugins enable rabbitmq_management` - rabbitmq 管理介面 - `docker exec ${container_id} rabbitmq-plugins enable rabbitmq_mqtt` - 插件:rabbitmq_mqtt - `docker exec ${container_id} rabbitmq-plugins enable rabbitmq_web_mqtt` - 插件:rabbitmq_web_mqtt #### Restart Container - `docker restart ${container_id}` ## 驗證是否安裝成功 ### 使用工具 - MQTT-Box(https://chrome.google.com/webstore/detail/mqttbox/kaajoficamnjijhkeomgfljpicifbkaf?hl=zh-TW) ### 驗證步驟 #### 打開 MQTT-Box #### 點擊 Create MQTT Client ![](https://i.imgur.com/ywb6UTR.jpg) #### 設定連接 RabbitMQ 的參數 ![](https://i.imgur.com/wOw5OlG.jpg) - 1. 命名 - 2. 現在 ws(websocket) - 3. 宿主機的ip:15675/ws - 15675 為預設,可以更改 - /ws 為寫死的,固定要這樣 - 4. 儲存 #### 看到 Connected => 代表已成功連到 RabbitMQ ![](https://i.imgur.com/n3Pd0a1.jpg) #### 嘗試 publish 訊息 & subscribe 是否有收到 - 隨意定義一個 topic(記得 subscribe 要一致) ![](https://i.imgur.com/BLnIJ7B.jpg) - 點擊 subscribe - 在 Payload 隨意輸入JSON 格式的訊息,並按 Publish ![](https://i.imgur.com/EQFzQZM.jpg) - 如有出現訊息,代表成功了! ## 附上 code 訂閱版本 ```javascript= const mqtt = require('mqtt') subscribeMQTT() function subscribeMQTT() { const client = mqtt.connect('ws://${宿主IP}:15675/ws') const topic = 'helloworld' client.on('connect', () => { client.subscribe(topic, error => { if() { console.log('subscribe success') }else { console.log('subscribe fail') } }) }) client.on('message', (topic, message) =>{ console.log('FROM : ', topic, JSON.parse(message)) }) } ``` ## 超快速架設/安裝方法 ### 新建一個 `Dockerfile` ### 編輯 `Dockerfile` - ```Dockerfile FROM daocloud.io/library/rabbitmq:3.7.4 RUN /usr/sbin/rabbitmq-plugins enable rabbitmq_management RUN /usr/sbin/rabbitmq-plugins enable rabbitmq_mqtt RUN /usr/sbin/rabbitmq-plugins enable rabbitmq_web_mqtt ``` ### 打包 `Image` - `docker build -t ${Image名稱} .` ### Run Container - `docker run -d --hostname my-rabbit --name some-rabbit -p 15672:15672 -p 5672:5672 -p 1883:1883 -p 15675:15675 ${Image名稱}` ### 完成! ## 補充說明 ### 如想看 RabbitMQ Web 介面 - 瀏覽器網址輸入: 宿主機IP:15672 - 預設帳號/密碼: guest/guest ### 如果只需要走 mqtt(不需要web) - Port 改為 1883 - Protocol 改為 mqtt ### 在 Mac 查詢目前使用中的 port 及 process id - `lsof -n -i | grep LISTEN` ### 在 Mac 查詢特定 port 的服務,以 80 port 為例 - `lsof -n -i:80 | grep LISTEN` ## 待優化項目: - 備份 RabbitMQ(Broker)接收的訊息 ## 參考 - 安裝:https://www.itread01.com/content/1547720656.html - RabbitMQ介紹: https://kucw.github.io/blog/2020/11/rabbitmq/ - MQTT & WebSocket 差異: - https://www.zhihu.com/question/21816631 - https://www.cnblogs.com/shanyou/p/4085802.html - 認識 MQTT:https://swf.com.tw/?p=1002