發佈與訂閱模式
生產者的消息會被所有的消費者獲取
發佈訂閱模式下創建RabbitMq實例
發佈訂閱模式queueName必須爲空,要傳入交換機exChangeName的名稱,routingkey爲空
func NewRabbitMqPubSub(exchangeName string) *RabbitMq {
//創建mq實例
rabbitmq := NewRabbitMq("", exchangeName, "")
return rabbitmq
}
發佈訂閱模式下生產者
1、生產者首先必須嘗試創建交換機,(嘗試創建表示如果交換機存在就直接使用,自己理解),ExchangeDeclare的第二個參數kind必須爲fanout
2、推送消息使用的是channel.Pubish發送消息,隊列名稱必須爲空,傳入交換機Exchange名稱
func (r *RabbitMq) PublishPub(message string) {
//嘗試創建交換機
err := r.channel.ExchangeDeclare(
r.Exchange,
//是在127.0.0.1:15672後臺的exchange中看到
"fanout",
//是否持久化
false,
//
false,
//如果internal設置爲true,表示exchage不可以被client用來推送消息,僅用來進行exchange和exchage之間的綁定
false,
false,
nil)
r.failOnErr(err, "failed to declare an exchange")
//2. 發送消息
r.channel.Publish(
//交換機
r.Exchange,
"",
//mandatory如果爲true會根據exchange類型和routekey規則,
//如果無法找到符合條件的隊列就把消息返還給發送者
false,
//immediate如果爲true,當exchage發送消息到隊列後,
//如果發現隊列上沒有綁定消費者就把消息返還給發送者
false,
//發送的信息
amqp.Publishing{
ContentType: "text/plain",
Body: []byte(message),
})
}
發佈訂閱模式下的消費者
1、消費者嘗試創建交換機channel.ExchangeDeclare也是使用fanout模式
2、嘗試創建隊列channel.QueueDeclare
3、綁定隊列到交換機中channel.Queuebind
4、消費channel.Consume消費消息
func (r *RabbitMq) RecivedSub() {
//嘗試創建交換機
err := r.channel.ExchangeDeclare(
r.Exchange,
//是在127.0.0.1:15672後臺的exchange中看到
"fanout",
//是否持久化
false,
false,
//如果internal設置爲true,表示exchage不可以被client用來推送消息,僅用來進行exchange和exchage之間的綁定
false,
false,
nil)
r.failOnErr(err, "failed to declare an exchange")
//2 嘗試創建隊列
q, err := r.channel.QueueDeclare(
"",
false,
false,
true,
false,
nil)
r.failOnErr(err, "failed to declare an queue")
//3 綁定隊列到exchange中
err = r.channel.QueueBind(
q.Name,
//在pub和sub模式下這裏的key要爲空
"",
r.Exchange,
false,
nil)
//消費消息
msgs, err := r.channel.Consume(
q.Name,
"",
true,
false,
false,
false,
nil)
if err != nil {
fmt.Printf("channel.Consume failed, error:%+v\n", err)
return
}
forever := make(chan bool)
go func() {
for d := range msgs {
//實現我們要處理的邏輯函數
log.Printf("Received a message:%s", d.Body)
}
}()
log.Printf("[*] Waiting for message, exit to press CTRL + C")
<-forever
}
使用案例
生產者
package main
import (
"rabbitmq/RabbitMq"
"strconv"
"time"
)
func main(){
rabbitmq := RabbitMq.NewRabbitMqPubSub("newProduct")
for i:=0;i<100;i++ {
rabbitmq.PublishPub("訂閱發佈模式生產消息 imooc" + strconv.Itoa(i))
time.Sleep( 10 * time.Millisecond)
}
}
消費者
package main
import "rabbitmq/RabbitMq"
func main(){
rabbitmq := RabbitMq.NewRabbitMqPubSub("newProduct")
rabbitmq.RecivedSub()
}
===================================================
package main
import "rabbitmq/RabbitMq"
func main(){
rabbitmq := RabbitMq.NewRabbitMqPubSub("newProduct")
rabbitmq.RecivedSub()
}
分析:
發佈訂閱模式下:生產者生產的消息會被所有的消費者獲取到
輸出結果
消費者1輸出結果
2019/07/04 11:35:16 [*] Waiting for message, exit to press CTRL + C
2019/07/04 11:35:20 Received a message:訂閱發佈模式生產消息 imooc0
2019/07/04 11:35:20 Received a message:訂閱發佈模式生產消息 imooc1
2019/07/04 11:35:20 Received a message:訂閱發佈模式生產消息 imooc2
2019/07/04 11:35:20 Received a message:訂閱發佈模式生產消息 imooc3
2019/07/04 11:35:20 Received a message:訂閱發佈模式生產消息 imooc4
2019/07/04 11:35:20 Received a message:訂閱發佈模式生產消息 imooc5
2019/07/04 11:35:20 Received a message:訂閱發佈模式生產消息 imooc6
2019/07/04 11:35:20 Received a message:訂閱發佈模式生產消息 imooc7
2019/07/04 11:35:20 Received a message:訂閱發佈模式生產消息 imooc8
2019/07/04 11:35:20 Received a message:訂閱發佈模式生產消息 imooc9消費者2輸出結果
2019/07/04 11:35:16 [*] Waiting for message, exit to press CTRL + C
2019/07/04 11:35:20 Received a message:訂閱發佈模式生產消息 imooc0
2019/07/04 11:35:20 Received a message:訂閱發佈模式生產消息 imooc1
2019/07/04 11:35:20 Received a message:訂閱發佈模式生產消息 imooc2
2019/07/04 11:35:20 Received a message:訂閱發佈模式生產消息 imooc3
2019/07/04 11:35:20 Received a message:訂閱發佈模式生產消息 imooc4
2019/07/04 11:35:20 Received a message:訂閱發佈模式生產消息 imooc5
2019/07/04 11:35:20 Received a message:訂閱發佈模式生產消息 imooc6
2019/07/04 11:35:20 Received a message:訂閱發佈模式生產消息 imooc7
2019/07/04 11:35:20 Received a message:訂閱發佈模式生產消息 imooc8
2019/07/04 11:35:20 Received a message:訂閱發佈模式生產消息 imooc9