零、前言
本文记录了笔者在学习消息队列和RabbitMQ的基础知识的过程,
在RabbitMQ-下,也就是本文中,我们介绍如何在Windows下的Docker中安装RabbitMQ;
并使用Golang测试RabbitMQ。
若笔者有任何疏忽纰漏之处,烦请不吝赐教。
本文会不断的补充、修改和完善,期待您的宝贵意见。
一、环境准备
环境:
- Windows 10
- Docker
- VSCode
- 勤劳的双手
笔者致力于创作上至老奶奶,下至小狗狗都能看懂的教程!
二、 Docker下安装RabbitMQ
拉取镜像:
在cmd中直接输入以下即可,实测不需要打开管理员权限,也不需要切换目录;
docker search rabbitMq
docker pull docker.io/rabbitmq:3.8-management
创建容器:
进入 Docker Desktop 查看镜像ID,当然你也可以docker images
将其复制并在cmd中输入以下指令来创建rabbitMq容器:
docker run --name rabbitmq -d -p 15672:15672 -p 5672:5672 818bf18535d7
参数说明:
--name是容器名称,这里我们使用的是rabbitmq-d是令容器后台运行-p是设置容器内部端口号与主机的映射,web端口默认值为15672,数据通信端口默认值为5672
如果返回一大串容器ID那就说明创建成功啦!
查看状态:
这个时候我们可以查看容器是否在运行,当然你也可以使用docker ps来查看
同样的,我们在这里把容器ID复制下来之后使用
docker logs -f <ID>可以查看容器的日志;
特别地,容器的ID可以简写,前提是保证前缀不与其他容器的相同。
就像这样:
三、 Web端的简单测试
进入Web端:
首先进入cmd输入ipconfig获取本机IP:
随后输入<IP>:15672进入RabbitMQ的Web端,
例如笔者就是192.168.1.4:15672,随后出现如下界面:
这个时候我们还没有创建任何账户,默认使用guest进行登录(账密都是):
Oh非常好,我们看到了想要的界面!
创建新的账户:
人活一世,总不能连个名字都没有,接下来我们就来创建一个新的账户,
毕竟guest有各种访问限制;
我们首先进入容器:docker exec -i -t <容器ID> bin/bash
当然你也可以使用点击即送的方法进入,不过这次并不推荐:
随后添加用户:rabbitmqctl add_user <username> <password>
方便起见,我们就用root了,如下:
root@638f5fe7d784:/# rabbitmqctl add_user root 13243546
Adding user "root" ...
Done. Don't forget to grant the user permissions to some virtual hosts! See 'rabbitmqctl help set_permissions' to learn more.
这个时候root还不是"root"呀,我们不能袖手旁观,需要赋予权限:
rabbitmqctl set_permissions -p / root ".*" ".*" ".*"
这样可能还不够,还需要给其赋予administrator的角色:
rabbitmqctl set_user_tags root administrator
查看所用用户:
rabbitmqctl list_users
以上的cmd效果:
root@638f5fe7d784:/# rabbitmqctl set_permissions -p / root ".*" ".*" ".*"
Setting permissions for user "root" in vhost "/" ...
root@638f5fe7d784:/# rabbitmqctl set_user_tags root administrator
Setting tags for user "root" to [administrator] ...
root@638f5fe7d784:/# rabbitmqctl list_users
Listing users ...
user tags
guest [administrator]
root [administrator]
回到Web端,再次登录:
这时可以关闭退出容器了,直接exit + 右上角关闭cmd即可;
然后Log Out一下guest账户,重新输入刚才的账户:
可以看到,我们卷土重来了!
四、 Go + RabbitMQ实现HelloWorld
没错,你没有看错,又是HelloWorld,话不多说让我们进入正题:
打开cmd,进入你想要的项目文件夹,老规矩go mod init <...>
go mod init go-rabbitmq-demo
go: creating new go.mod: module go-rabbitmq-demo
code . // 打开我们亲爱的VSCode
随后创建send.go
引入github.com/streadway/amqp并go mod tidy
辅助函数
定义一个辅助函数用于检查每个amqp调用的返回值;
发送方和接收方最好都要有;
// 定义辅助函数
func failOnError(err error, msg string) {
if err != nil {
log.Fatalf("%s: %s", msg, err)
}
}
send.go主函数
func main() {
// 建立与 RabbitMQ 的连接
// 配置连接套接字,定义连接的协议与身份验证
conn, err := amqp.Dial("amqp://guest:guest@localhost:5672/")
failOnError(err, "Failed to connect to RabbitMQ")
defer conn.Close()
// 创建通道来传递消息
ch, err := conn.Channel()
failOnError(err, "Failed to open a channel")
defer ch.Close()
// 声明要发送到的队列
q, err := ch.QueueDeclare(
"hello",
false,
false,
false,
false,
nil,
)
failOnError(err, "Failed to declare a queue")
// ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
// defer cancel()
body := "Hello World!"
// 将消息发布到声明的队列
err = ch.Publish(
"",
q.Name,
false,
false,
amqp.Publishing{
ContentType: "text/plain",
Body: []byte(body),
})
failOnError(err, "Failed to publish a message")
// log.Printf(" [x] Sent %s\n", body)
}
receive.go主函数
func main() {
// 建立与 RabbitMQ 的连接
conn, err := amqp.Dial("amqp://guest:guest@localhost:5672/")
failOnError(err, "Failed to connect to RabbitMQ")
defer conn.Close()
// 获取通道
ch, err := conn.Channel()
failOnError(err, "Failed to open a channel")
defer ch.Close()
// 声明队列
q, err := ch.QueueDeclare(
"hello",
false,
false,
false,
false,
nil,
)
failOnError(err, "Failed to declare a queue")
msgs, err := ch.Consume(
q.Name, // queue
"", // consumer
true, // auto-ack
false, // exclusive
false, // no-local
false, // no-wait
nil, // args
)
failOnError(err, "Failed to register a consumer")
var forever chan struct{}
go func() {
for d := range msgs {
log.Printf("Received a message: %s", d.Body)
}
}()
log.Printf(" [*] Waiting for messages. To exit press CTRL+C")
<-forever
}
运行!
分别在两个cmd里面执行go run send.go和go run receive.go
注意,send可以执行多次之后再执行receive,也可以先开启receive,读者不妨自己尝试一下;
我们可以在Web端看到,Channel中有数据的情况:
终端的情况是这样的:
文件目录结构
很简单,就这四个东西:
THE END.