簡介
官網
RabbitMQ是一個訊息代理:它接受并轉發訊息,你可以把它想象成一個郵局:當你把你想要郵寄的郵件放進一個郵箱時,你可以確定郵差先生或女士最侄訓把郵件送到你的收件人那里,在這個比喻中,RabbitMQ是一個郵箱、一個郵局和一個郵遞員,
RabbitMQ和郵局的主要區別在于它不處理紙張,而是接受、存盤和轉發二進制資料塊——訊息,
RabbitMQ和一般的訊息傳遞都使用一些術語,
- 生產僅意味著發送,發送訊息的程式是生產者
- 佇列是位于RabbitMQ內部的郵箱的名稱,盡管訊息通過RabbitMQ和你的應用程式流動,但它們只能存盤在佇列中,佇列只受主機記憶體和磁盤限制的限制,實際上它是一個大的訊息緩沖區,許多生產者可以向一個佇列發送訊息,而許多消費者可以嘗試從一個佇列接收資料,
- 消費與接收具有相似的含義,消費者是一個主要等待接收訊息的程式:
請注意,生產者,消費者和代理(broker)不必位于同一主機上,實際上,在大多數應用程式中它們不是,一個應用程式既可以是生產者,也可以是消費者,
安裝
撰寫docker-compose.yml
version: '3'
services:
rabbitmq:
image: rabbitmq:3.8.3-management
container_name: rabbitmq
restart: always
hostname: rabbitmq_host
ports:
- 15672:15672 # web UI 管理介面
- 5672:5672 # 生產者和消費者連接使用的介面
volumes:
- ./log:/var/log/rabbitmq #掛載 RabbitMQ日志
- ./data:/var/lib/rabbitmq #掛載 RabbitMQ資料
environment:
- RABBITMQ_DEFAULT_USER=root
- RABBITMQ_DEFAULT_PASS=123456
說明
-
15672:UI端使用埠
5672:golang連接rabbitmq使用的介面
瀏覽器訪問 ip:15672即可,輸入用戶名,密碼登錄, -
application.yml檔案中推薦為docker容器設定hostname,因為rabbitmq默認使用hostname作為存盤資料的節點名,設定hostname可以避免生成隨機的節點名,方便追蹤資料,官網原文如下
One of the important things to note about RabbitMQ is that it stores data based on what it calls the "Node Name", which defaults to the hostname. What this means for usage in Docker is that we should specify -h/--hostname explicitly for each daemon so that we don't get a random hostname and can keep track of our data:
-
RABBITMQ_DEFAULT_USER 和 RABBITMQ_DEFAULT_PASS
用來設定超級管理員的賬號和密碼,如果不設定,默認都是 guest -
docker鏡像使用像這樣 rabbitmq:3.8.3-management 帶有后綴 -management的鏡像,之前使用沒帶這個后綴的鏡像,網頁訪問失敗
Hello World使用
首先,使用go get安裝amqp
go get github.com/streadway/amqp
生產者
producer.go
package main
import (
"log"
"github.com/streadway/amqp"
)
func main() {
// 1. 嘗試連接RabbitMQ,建立連接
// 該連接抽象了套接字連接,并為我們處理協議版本協商和認證等,
conn, err := amqp.Dial("amqp://root:123456@127.0.0.1:5672/")
if err != nil {
log.Fatalf("%s", "Failed to connect to RabbitMQ", err)
return
}
defer conn.Close()
// 2. 接下來,我們創建一個通道,大多數API都是用過該通道操作的,
ch, err := conn.Channel()
if err != nil {
log.Fatalf("%s", "Failed to open a channel", err)
return
}
defer ch.Close()
// 3. 宣告訊息要發送到的佇列
q, err := ch.QueueDeclare(
"hello", // name
false, // durable
false, // delete when unused
false, // exclusive
false, // no-wait
nil, // arguments
)
if err != nil {
log.Fatalf("%s", "Failed to declare a queue", err)
return
}
body := "Hello World!"
// 4.將訊息發布到宣告的佇列
err = ch.Publish(
"", // exchange
q.Name, // routing key
false, // mandatory
false, // immediate
amqp.Publishing{
ContentType: "text/plain",
Body: []byte(body),
})
if err != nil {
log.Fatalf("%s", "Failed to publish a message", err)
return
}
log.Printf(" [x] Sent %s", body)
}
消費者
consumer.go
package main
import (
"log"
"github.com/streadway/amqp"
)
func main() {
// 建立連接
conn, err := amqp.Dial("amqp://root:123456@127.0.0.1:5672/")
if err != nil {
log.Fatalf("%s", "Failed to connect to RabbitMQ", err)
return
}
defer conn.Close()
// 獲取channel
ch, err := conn.Channel()
if err != nil {
log.Fatalf("%s", "Failed to open a channel", err)
return
}
defer ch.Close()
// 宣告佇列
//請注意,我們也在這里宣告佇列,因為我們可能在發布者之前啟動使用者,所以我們希望在嘗試使用佇列中的訊息之前確保佇列存在,
q, err := ch.QueueDeclare(
"hello", // name
false, // durable
false, // delete when unused
false, // exclusive
false, // no-wait
nil, // arguments
)
if err != nil {
log.Fatalf("%s", "Failed to declare a queue", err)
return
}
// 獲取接收訊息的Delivery通道
msgs, err := ch.Consume(
q.Name, // queue
"", // consumer
true, // auto-ack
false, // exclusive
false, // no-local
false, // no-wait
nil, // args
)
if err != nil {
log.Fatalf("%s", "Failed to register a consumer", err)
return
}
go func() {
for d := range msgs {
log.Printf("Received a message: %s", d.Body)
}
}()
log.Printf(" [*] Waiting for messages. To exit press CTRL+C")
select {}
}
參考檔案:
Kafka、RabbitMQ、RocketMQ 之間的區別是什么 ?
RabbitMQ Go語言客戶端教程
RabbitMQ官網的Go語言客戶端系列教程
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/254455.html
標籤:區塊鏈
上一篇:nvm使用
