macOS中安装RabbitMQ:
brew install erlang
brew install rabbitmq
cd /usr/local/Celler/rabbitmq/3.8.11
sudo sbin/rabbitmq-plugins enable rabbitmq_management
open ~/.zshrc
// 添加以下两行
export RABBIT_HOME = /usr/local/Celler/3.8.11
export PATH = $PATH:RABBIT_HOME/sbin
source ~/.zshrc
sudo rabbitmq-server -detached
rabbitmqctl stop
在golang中尝试RabbitMQ的几种模式:
i: 安装amqp库
go get github.com/streadway/amqp
ii: 定义url
// url格式:amqp://账号:密码@rabbitmq服务地址/vhost
const MQURL = "amqp://chensir:[email protected]:5672/chen"
iii: 定义RabbitMQ对象结构体
type RabbitMQ struct {
conn *amqp.Connection
channel *amqp.Channel
// 队列名称
QueueName string
// 交换机
Exchange string
// key
Key string
// 链接信息
Mqurl string
}
i: 创建RabbitMQ结构体实例
func NewRabbitMQ(queueName string, exchange string, key string) *RabbitMQ {
rabbitmq := &RabbitMQ{
QueueName: queueName,
Exchange: exchange,
Key: key,
Mqurl: MQURL,
}
var err error
// 创建rabbitmq链接
rabbitmq.conn, err = amqp.Dial(rabbitmq.Mqurl)
rabbitmq.failOnError(err, "创建链接错误")
rabbitmq.channel, err = rabbitmq.conn.Channel()
rabbitmq.failOnError(err, "获取channel失败")
return rabbitmq
}
ii: Simple模式下生产者
func (r *RabbitMQ) PublishSimple(message string){
// 1. 申请队列,如果队列不存在,自动创建;如果存在则跳过创建,保证消息能发送到队列中
_, err := r.channel.QueueDeclare(
r.QueueName,
//控制是否持久化
false,
// 是否自动删除
false,
// 是否具有排他性
false,
// 是否阻塞
false,
// 额外属性
nil)
if err != nil {
fmt.Println(err)
}
// 发送消息到队列中
r.channel.Publish(
r.Exchange,
r.QueueName,
// 如果为true和exchage类型和routKey规则,如果无法找到符合条件的队列,那么会把消息返回给发送者
false,
// 如果为true, 当exchange发送消息到队列后发现队列上没有绑定消费者,则会把消息还给发送者
false,
amqp.Publishing{
ContentType: "text/plain",
Body: []byte(message),
})
}
iii: Simple模式下消费者
func (r *RabbitMQ) ConsumeSimple(){
// 尝试申请队列
_, err := r.channel.QueueDeclare(
r.QueueName,
//控制是否持久化
false,
// 是否自动删除
false,
// 是否具有排他性
false,
// 是否阻塞
false,
// 额外属性
nil)
if err != nil {
fmt.Println(err)
}
// 接收消息
msgs, err := r.channel.Consume(
r.QueueName,
// 用来区分多个消费者的key
"",
// 是否自动应到
true,
// 是否具有排他性
false,
// 如果设置为true,表示不能将同一个connection中发送的消息传递给这个connection中的消费者
false,
// 队列消费是否为阻塞
false,
nil)
if err != nil {
fmt.Println(err)
}
// 消费消息
forever := make(chan bool)
go func(){
for d := range msgs {
log.Printf("Receive a message: %s", d.Body)
}
}()
log.Println("[*] waiting for message, To exit press Ctrl + c")
<-forever
}
i: 订阅模式下创建RabbitMQ实例
func NewRabbitMQPubSub(exchangeName string) *RabbitMQ {
// 指定交换机名称, 而队列名称则为空即可
rabbitmq := NewRabbitMQ("", exchangeName, "")
var err error
rabbitmq.conn, err = amqp.Dial(rabbitmq.Mqurl)
rabbitmq.failOnError(err, "failed to connect rabbitmq")
// 获取channel
rabbitmq.channel, err = rabbitmq.conn.Channel()
rabbitmq.failOnError(err, "failed to open a channel")
return rabbitmq
}
ii: 订阅模式下生产信息
func (r *RabbitMQ) PublishPub(message string){
// 尝试创建交换机
err := r.channel.ExchangeDeclare(
r.Exchange,
// 交换机类型为广播类型
"fanout",
true,
false,
false,
false,
nil)
r.failOnError(err, "failed to declare an exchange")
// 发送消息
err = r.channel.Publish(
r.Exchange,
"",
false,
false,
amqp.Publishing{
ContentType: "text/plain",
Body: []byte(message),
})
r.failOnError(err, "failed to send a message")
}
iii: 订阅模式下接收消息
func (r *RabbitMQ) ReceiveSub(){
err := r.channel.ExchangeDeclare(
r.Exchange,
"fanout",
true,
false,
// YES表示这个exchange不可以被client用来推送消息,仅用来进行exchange和exchange之间的绑定
false,
false,
nil)
r.failOnError(err, "failed to declare an exchange")
// 创建队列
q, err := r.channel.QueueDeclare(
"", // 随机生产队列名称
false,
false,
true,
false,
nil)
// 绑定队列到exchange中
r.failOnError(err, "failed to declare a queue")
err = r.channel.QueueBind(
q.Name,
// 在Pub/Sub模式下,这里的key要为空
"",
r.Exchange,
false,
nil)
// 消费消息
message, err := r.channel.Consume(
q.Name,
"",
true,
false,
false,
false,
nil)
forever := make(chan bool)
go func(){
for d := range message {
log.Printf("Receive a message: %s", d.Body)
}
}()
log.Println("退出请按: Ctrl + c")
<-forever
}
func NewRabbitMQRouting(exchangeName string, routingKey string) *RabbitMQ {
rabbitmq := NewRabbitMQ("", exchangeName, routingKey)
var err error
rabbitmq.conn, err = amqp.Dial(rabbitmq.Mqurl)
rabbitmq.failOnError(err, "failed to connect rabbitmq")
// 获取channel
rabbitmq.channel, err = rabbitmq.conn.Channel()
rabbitmq.failOnError(err, "failed to open a channel")
return rabbitmq
}
-------本文结束