官网:https://www.rabbitmq.com/getstarted.html
视频:https://www.bilibili.com/video/BV15k4y1k7Ep?p=1&vd_source=304ddde222ac891d9516a57f8192f02b
在安装的sbin路径下,打开cmd窗口,输入命令:
abbitmq-plugins enable rabbitmq_management
启动mq,打开http://127.0.0.1:15672/ 链接,进入控制台
登录账号:guest
密码:guest
package main
import (
"fmt"
"github.com/streadway/amqp"
)
func main() {
// 1. 尝试连接RabbitMQ,建立连接
// 该连接抽象了套接字连接,并为我们处理协议版本协商和认证等
conn, err := amqp.Dial("amqp://guest:guest@localhost:5672/")
if err != nil {
fmt.Println(err)
}
//defer conn.Close()
// 2. 接下来,我们创建一个通道,大多数API都是用过该通道操作的。
ch, err := conn.Channel()
if err != nil {
fmt.Println(err)
}
//defer ch.Close()
// 3. 声明消息要发送到的队列
//参数:
//1.queue:队列名称
//2.durable:是否持久化,当mq重启之后,还在
//3.exclusive:参数有两个意思 a)是否独占即只能有一个消费者监听这个队列 b)当connection关闭时,是否删除队列
//4.autoDelete:是否自动删除。当没有Consumer时,自动删除掉
//5.argument:参数。配置如何删除
//如果没有一个名字叫hello的队列,则会创建该队列,如果有则不会创建
q, err := ch.QueueDeclare(
"hello", // name
false, // durable
false, // delete when unused
false, // exclusive
false, // no-wait
nil, // arguments
)
if err != nil {
fmt.Println(err)
}
body := "Hello rabbitMq~~!"
// 4.将消息发布到声明的队列
err = ch.Publish(
"", // exchange 交换机名称 简单模式下交换机会使用默认的""
q.Name, // routing key 路由名称
false, // mandatory
false, // immediate
amqp.Publishing{ //发送消息数据
ContentType: "text/plain",
Body: []byte(body),
})
}
消费者代码
package main
import (
"fmt"
"github.com/streadway/amqp"
"log"
)
func main() {
// 1. 尝试连接RabbitMQ,建立连接
conn, err := amqp.Dial("amqp://guest:guest@localhost:5672/")
if err != nil {
fmt.Println(err)
}
//defer conn.Close()
// 2. 接下来,我们创建一个通道,大多数API都是用过该通道操作的。
ch, err := conn.Channel()
if err != nil {
fmt.Println(err)
}
//defer ch.Close()
// 3. 声明消息要发送到的队列
//如果没有一个名字叫hello的队列,则会创建该队列,如果有则不会创建
q, err := ch.QueueDeclare(
"hello", // name
false, // durable
false, // delete when unused
false, // exclusive
false, // no-wait
nil, // arguments
)
if err != nil {
fmt.Println(err)
}
// 4.接收消息
msgs, err := ch.Consume( // 注册一个消费者(接收消息)
q.Name, // queue
"", // consumer
true, // auto-ack
false, // exclusive
false, // no-local
false, // no-wait
nil, // args
)
for d := range msgs {
log.Printf("Received a message: %s", d.Body)
}
}
与简单模式相比,多了一个或一些消费端,多个消费端共同消费同一个队列中的消息
应用场景:对于任务过重或任务较多情况使用工作队列可以提高任务处理的速度
几个消费者交替顺序消费,代码与简单模式一致
package main
import (
"fmt"
"github.com/streadway/amqp"
)
func main() {
// 1. 尝试连接RabbitMQ,建立连接
// 该连接抽象了套接字连接,并为我们处理协议版本协商和认证等
conn, err := amqp.Dial("amqp://guest:guest@localhost:5672/")
if err != nil {
fmt.Println(err)
}
defer conn.Close()
// 2. 接下来,我们创建一个通道,大多数API都是用过该通道操作的。
ch, err := conn.Channel()
if err != nil {
fmt.Println(err)
}
defer ch.Close()
//3. 创建交换机
//参数:
//1、name:交换机名称
//2、kind:交换机类型
//amqp.ExchangeDirect 定向
//amqp.ExchangeFanout 扇形(广播),发送消息到每个队列
//amqp.ExchangeTopic 通配符的方式
//amqp.ExchangeHeaders 参数匹配
//3、durable:是否持久化
//4、autoDelete:自动删除
//5、internal:内部使用 一般false
//6、noWait bool,
//7、args:参数
exchangeName := "test_fanout"
ch.ExchangeDeclare(exchangeName, amqp.ExchangeFanout, true, false, false, false, nil)
//4. 创建队列
queue1Name := "test_fanout_queue1"
queue2Name := "test_fanout_queue2"
ch.QueueDeclare(queue1Name, true, false, false, false, nil)
ch.QueueDeclare(queue2Name, true, false, false, false, nil)
//5. 绑定队列和交换机
ch.QueueBind(queue1Name, "", exchangeName, false, nil)
ch.QueueBind(queue2Name, "", exchangeName, false, nil)
//6. 发送消息
body := "日志信息:方法被调用,日志级别:info..."
err = ch.Publish(
exchangeName, // exchange 交换机名称 简单模式下交换机会使用默认的""
"", // routing key 路由名称
false, // mandatory
false, // immediate
amqp.Publishing{ //发送消息数据
ContentType: "text/plain",
Body: []byte(body),
},
)
}
运行之后,控制台就会产生两个队列,并且有两条待发送的消息
消费者代码示例
package main
import (
"fmt"
"github.com/streadway/amqp"
)
func main() {
// 1. 尝试连接RabbitMQ,建立连接
conn, err := amqp.Dial("amqp://guest:guest@localhost:5672/")
if err != nil {
fmt.Println(err)
}
//defer conn.Close()
// 2. 接下来,我们创建一个通道,大多数API都是用过该通道操作的。
ch, err := conn.Channel()
if err != nil {
fmt.Println(err)
}
//defer ch.Close()
// 3. 声明消息要发送到的队列
//如果没有一个名字叫hello的队列,则会创建该队列,如果有则不会创建
q, err := ch.QueueDeclare(
"test_fanout_queue1", // name
true, // durable
false, // delete when unused
false, // exclusive
false, // no-wait
nil, // arguments
)
if err != nil {
fmt.Println(err)
}
// 4.将消息发布到声明的队列
msgs, err := ch.Consume( // 注册一个消费者(接收消息)
q.Name, // queue
"", // consumer
true, // auto-ack
false, // exclusive
false, // no-local
false, // no-wait
nil, // args
)
for d := range msgs {
fmt.Printf("Received a message: %s\n", d.Body)
fmt.Println("将日志信息保存到数据库")
}
}
package main
import (
"fmt"
"github.com/streadway/amqp"
)
func main() {
// 1. 尝试连接RabbitMQ,建立连接
// 该连接抽象了套接字连接,并为我们处理协议版本协商和认证等
conn, err := amqp.Dial("amqp://guest:guest@localhost:5672/")
if err != nil {
fmt.Println(err)
}
defer conn.Close()
// 2. 接下来,我们创建一个通道,大多数API都是用过该通道操作的。
ch, err := conn.Channel()
if err != nil {
fmt.Println(err)
}
defer ch.Close()
//3. 创建交换机
//参数:
//1、name:交换机名称
//2、kind:交换机类型
//amqp.ExchangeDirect 定向
//amqp.ExchangeFanout 扇形(广播),发送消息到每个队列
//amqp.ExchangeTopic 通配符的方式
//amqp.ExchangeHeaders 参数匹配
//3、durable:是否持久化
//4、autoDelete:自动删除
//5、internal:内部使用 一般false
//6、noWait bool,
//7、args:参数
exchangeName := "test_direct"
ch.ExchangeDeclare(exchangeName, amqp.ExchangeDirect, true, false, false, false, nil)
//4. 创建队列
queue1Name := "test_direct_queue1"
queue2Name := "test_direct_queue2"
ch.QueueDeclare(queue1Name, true, false, false, false, nil)
ch.QueueDeclare(queue2Name, true, false, false, false, nil)
//5. 绑定队列和交换机
//队列1绑定 error
ch.QueueBind(queue1Name, "error", exchangeName, false, nil)
//队列2绑定 info error warning
ch.QueueBind(queue2Name, "info", exchangeName, false, nil)
ch.QueueBind(queue2Name, "error", exchangeName, false, nil)
ch.QueueBind(queue2Name, "warning", exchangeName, false, nil)
//6. 发送消息
body := "日志信息:delete方法被调用,日志级别:error..."
err = ch.Publish(
exchangeName, // exchange 交换机名称 简单模式下交换机会使用默认的""
"error", // routing key 路由名称
false, // mandatory
false, // immediate
amqp.Publishing{ //发送消息数据
ContentType: "text/plain",
Body: []byte(body),
},
)
}
消费者代码
package main
import (
"fmt"
"github.com/streadway/amqp"
)
func main() {
// 1. 尝试连接RabbitMQ,建立连接
conn, err := amqp.Dial("amqp://guest:guest@localhost:5672/")
if err != nil {
fmt.Println(err)
}
//defer conn.Close()
// 2. 接下来,我们创建一个通道,大多数API都是用过该通道操作的。
ch, err := conn.Channel()
if err != nil {
fmt.Println(err)
}
//defer ch.Close()
// 3. 声明消息要发送到的队列
//如果没有一个名字叫hello的队列,则会创建该队列,如果有则不会创建
q, err := ch.QueueDeclare(
"test_direct_queue1", // name
true, // durable
false, // delete when unused
false, // exclusive
false, // no-wait
nil, // arguments
)
if err != nil {
fmt.Println(err)
}
// 4.将消息发布到声明的队列
msgs, err := ch.Consume( // 注册一个消费者(接收消息)
q.Name, // queue
"", // consumer
true, // auto-ack
false, // exclusive
false, // no-local
false, // no-wait
nil, // args
)
for d := range msgs {
fmt.Printf("Received a message: %s\n", d.Body)
fmt.Println("将日志信息保存到数据库")
}
}
package main
import (
"fmt"
"github.com/streadway/amqp"
)
func main() {
// 1. 尝试连接RabbitMQ,建立连接
// 该连接抽象了套接字连接,并为我们处理协议版本协商和认证等
conn, err := amqp.Dial("amqp://guest:guest@localhost:5672/")
if err != nil {
fmt.Println(err)
}
defer conn.Close()
// 2. 接下来,我们创建一个通道,大多数API都是用过该通道操作的。
ch, err := conn.Channel()
if err != nil {
fmt.Println(err)
}
defer ch.Close()
//3. 创建交换机
//参数:
//1、name:交换机名称
//2、kind:交换机类型
//amqp.ExchangeDirect 定向
//amqp.ExchangeFanout 扇形(广播),发送消息到每个队列
//amqp.ExchangeTopic 通配符的方式
//amqp.ExchangeHeaders 参数匹配
//3、durable:是否持久化
//4、autoDelete:自动删除
//5、internal:内部使用 一般false
//6、noWait bool,
//7、args:参数
exchangeName := "test_topic"
ch.ExchangeDeclare(exchangeName, amqp.ExchangeTopic, true, false, false, false, nil)
//4. 创建队列
queue1Name := "test_topic_queue1"
queue2Name := "test_topic_queue2"
ch.QueueDeclare(queue1Name, true, false, false, false, nil)
ch.QueueDeclare(queue2Name, true, false, false, false, nil)
//5. 绑定队列和交换机
//routing key 系统名称.日志级别
//需求:所有error级别的日志村日数据库,所有order系统的日志存入数据库
//队列1绑定
ch.QueueBind(queue1Name, "#.error", exchangeName, false, nil)
ch.QueueBind(queue1Name, "order.*", exchangeName, false, nil)
//队列2绑定
ch.QueueBind(queue2Name, "*.*", exchangeName, false, nil)
//6. 发送消息
body := "日志信息:delete方法被调用,日志级别:error..."
err = ch.Publish(
exchangeName, // exchange 交换机名称 简单模式下交换机会使用默认的""
"goods.info", // routing key 路由名称
false, // mandatory
false, // immediate
amqp.Publishing{ //发送消息数据
ContentType: "text/plain",
Body: []byte(body),
},
)
}