1. 模式介绍
RabbitMQ官方把这种叫做hello world
,我的理解是消息点对点传播,一个生产者对应一个消费者
2. 成员
- 一个生产者
- 默认交换机,无需声明
- 一个消息队列,具名队列,持久化的
- 一个消费者
3. 公共代码
抽取一部分公共代码作为工具,避免代码冗余,新建utils
目录,创建channel.go
文件
- 获取信道的代码
- 生成消息内容的代码
package utils
import (
"github.com/streadway/amqp"
"strings"
)
const url = "amqp://guest:guest@192.168.18.3:5672/"
func GetChannel() *amqp.Channel {
connection, err := amqp.Dial(url)
if err != nil {
panic(err)
}
channel, err := connection.Channel()
if err != nil {
panic(err)
}
return channel
}
func BodyFrom(args []string) string {
var s string
if len(args) < 2 || args[1] == "" {
s = "hello"
} else {
s = strings.Join(args, " ")
}
return s
}
4. 实现简单模式
新建work_model/hello_world
目录,创建send.go
与receive.go
文件。
- 先实现生产者代码
package main
import (
"fmt"
"github.com/streadway/amqp"
"rabbitmq-demo/utils"
)
func main() {
channel := utils.GetChannel()
// 使用默认交换机,无需声明
// 声明队列
queue, err := channel.QueueDeclare("hello world",
true,
false,
false,
false,
nil)
if err != nil {
panic(err)
}
// 发布消息
err = channel.Publish("",
queue.Name,
false,
false,
amqp.Publishing{
ContentType: "text/plain",
Body: []byte("hello world"),
})
if err != nil {
fmt.Println("发送消息失败")
}
}
运行代码,查看web管理界面,多了一个hello world
队列,队列里有一条消息,消息内容是hello world
- 再实现消费者代码
package main
import (
"fmt"
"rabbitmq-demo/utils"
)
func main() {
channel := utils.GetChannel()
// 使用默认交换机
// 声明队列
queue, err := channel.QueueDeclare("hello world", // 队列名
true, // 开启持久化,宕机或重启时,队列存在
false, // 不自动删除
false, // 非独占
false, // 不等待
nil) // 其他参数
if err != nil {
panic(err)
}
// 消费消息
deliveries, err := channel.Consume(queue.Name, // 队列名
"", // 消费者tag
false, // 手动Ack
false, // 非独占
false, // 不等待
false, //
nil)
if err != nil {
panic(err)
}
for delivery := range deliveries {
fmt.Println(string(delivery.Body))
delivery.Ack(false)
}
}
运行代码,消费到一条消息hello wolrd
,协程阻塞。