RabbitMQ官方教程一Hello World(GOLANG语言实现)
介绍
RabbitMQ是消息中间件:它接受并转发消息。
您可以将其视为邮局系统:将要发送的邮件放在邮箱中时,
可以确保邮递员最终将邮件传递给收件人。
以此类推,RabbitMQ是一个邮箱,一个邮局和一个邮递员。
RabbitMQ与邮局之间的主要区别在于,
它不处理纸张,而是接收,存储和转发数据消息的二进制数据。
以下是RabbitMQ和消息发送的术语
- Producer:生产者。负责生产消息。

- Queue:队列。负责存储消息。队列在RabbitMQ中充当邮箱的角色,消息传递到RabbitMQ中,只能存储在队列中。队列受主机内存和磁盘大小的约束。本质是一个很大的消息缓冲区。
许多生产者可以将消息发送到一个队列,许多消费者可以尝试从一个队列接收数据。

- Consumer:消费者。负责处理消息。
** 笔者补充
Connect:连接。生产者和RabbitMQ服务之间建立的TCP连接。
Channel:信道,一条连接可包含多条信道,不同信道之间通信互不干扰。考虑下多线程应用场景,每个线程对应一条信道,而不是对应一条连接,这样可以提高性能。
body:消息主体,要传递的数据。
exchange:交换器,负责把消息转发到对应的队列。交换器本身没有缓存消息的功能,消息是在队列中缓存的,如果队列不存在,则交换器会直接丢弃消息。常用的有四种类型的交换器:direct、fanout、topic、headers。不同类型的交换器有不同的交换规则,交换器会根据交换规则把消息转发到对应的队列。
exchangeName:交换器名称,每个交换器对应一个名称,发送消息时会附带交换器名称,根据交换器名称选择对应的交换器。
BandingKey:绑定键,一个队列可以有一个到多个绑定键,通过绑定操作可以绑定交换器和队列,交换器会根据绑定键的名称找到对应的队列。
RotingKey:路由键,发送消息时,需要附带一条路由键,交换器会对路由键和绑定键进行匹配,如果匹配成功,则消息会转发到绑定键对应的队列中。
**简而言之就是:
生产者指定路由Key和交换器的名字发送给RabbitMQ服务
指定名字的交换器根据路由key去找到绑定的队列
将消息放入队列当中
消费者从队列中取出消息进行处理


实战 "Hello World"
golang语言实现
在本教程的这一部分中,我们将用Go编写两个小程序。 发送单个消息的生产者和接收消息并打印出来的消费者。 我们将介绍Go RabbitMQ API中的一些细节,仅着眼于此非常简单的事情。 这是消息传递的“ Hello World”。
在下图中,“ P”是我们的生产者,“ C”是我们的消费者。 中间的框是一个队列-RabbitMQ代表使用者保留的消息缓冲区。

Go RabbitMQ客户端库
RabbitMQ使用多种协议。 本教程使用AMQP 0-9-1,这是一种开放的通用消息传递协议。 RabbitMQ有许多不同语言的客户。 在本教程中,我们将使用Go amqp客户端。
go get github.com/streadway/amqp
生产者发送数据到队列

#send.go 生产者,发送消息到消息队列中
package main
import (
"github.com/streadway/amqp"
"log"
)
func main(){
// 连接RabbitMQ服务器
conn, err := amqp.Dial("amqp://guest:guest@127.0.0.1:5672/")
failOnError(err, "Failed to connect to RabbitMQ")
defer conn.Close()
// 创建一个channel
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")
// 发送消息到队列中
body := "Hello World!"
err = ch.Publish(
"", // exchange
q.Name, // routing key
false, // mandatory
false, // immediate
amqp.Publishing {
ContentType: "text/plain",
Body: []byte(body),
})
failOnError(err, "Failed to publish a message")
fmt.Println("send message success\n"
}
// 帮助函数检测每一个amqp调用
func failOnError(err error, msg string) {
if err != nil {
log.Fatalf("%s: %s", msg, err)
}
}
消费者从队列接收数据

package main
import (
"github.com/streadway/amqp"
"log"
)
func main(){
// 连接RabbitMQ服务器
conn, err := amqp.Dial("amqp://admin:admin@47.97.215.189:5672/admin")
failOnError(err, "Failed to connect to RabbitMQ")
defer conn.Close()
// 创建一个channel
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")
// 申明一个goroutine,一遍程序始终监听
forever := make(chan bool)
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
}
// 帮助函数检测每一个amqp调用
func failOnError(err error, msg string) {
if err != nil {
log.Fatalf("%s: %s", msg, err)
}
}
RabbitMQ官方教程一Hello World(GOLANG语言实现)的更多相关文章
- RabbitMQ官方教程三 Publish/Subscribe(GOLANG语言实现)
RabbitMQ官方教程三 Publish/Subscribe(GOLANG语言实现) 在上一个教程中,我们创建了一个工作队列. 工作队列背后的假设是,每个任务都恰好交付给一个worker处理. 在这 ...
- RabbitMQ官方教程二 Work Queues(GOLANG语言实现)
RabbitMQ官方教程二 Work Queues(GOLANG语言实现) 在第一个教程中,我们编写了程序来发送和接收来自命名队列的消息. 在这一部分中,我们将创建一个工作队列,该队列将用于在多个wo ...
- Cobalt Strike使用教程一
Cobalt Strike使用教程一 0x00 简介 Cobalt Strike是一款基于java的渗透测试神器,常被业界人称为CS神器.自3.0以后已经不在使用Metasploit框架而作为 ...
- NGUI系列教程一
NGUI是Unity的一个插件,使用它来制作你的游戏UI必定将事半功倍.为什么这么说呢?首先我们说说GUI与NGUI的区别,GUI是Unity自带的绘制界面工具,它的成像原理是基于表层的,所以执行效率 ...
- RabbitMQ系列教程之二:工作队列(Work Queues)(转载)
RabbitMQ系列教程之二:工作队列(Work Queues) 今天开始RabbitMQ教程的第二讲,废话不多说,直接进入话题. (使用.NET 客户端 进行事例演示) ...
- Quartz教程一:使用quartz
原文链接 | 译文链接 | 翻译:nkcoder | 校对:方腾飞 本系列教程由quartz-2.2.x官方文档翻译.整理而来,希望给同样对quartz感兴趣的朋友一些参考和帮助,有任何不当或错误之处 ...
- TODO:Golang语言TCP/UDP协议重用地址端口
TODO:Golang语言TCP/UDP协议重用地址端口 这是一个简单的包来解决重用地址的问题. go net包(据我所知)不允许设置套接字选项. 这在尝试进行TCP NAT时尤其成问题,其需要在同一 ...
- CRL快速开发框架系列教程一(Code First数据表不需再关心)
本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...
- hbase rest api接口链接管理【golang语言版】
# go-hbase-resthbase rest api接口链接管理[golang语言版]关于hbase的rest接口的详细信息可以到官网查看[http://hbase.apache.org/boo ...
随机推荐
- MySQL UPDATE 更新
以下是 UPDATE 命令修改 MySQL 数据表数据的通用 SQL 语法: UPDATE table_name SET field1=new-value1, field2=new-value2 [W ...
- FCS省选模拟赛 Day4
传送门 Solution Code /* 斯坦纳树:O(n*3^n+kE*2^n) 暂且把O(k*E)当成是spfa的复杂度 15:15~16:20 原题:bzoj_4774 */ #include ...
- encode(编码)和decode(解码)方法
JS对文字进行编码涉及3个函数:escape,encodeURI,encodeURIComponent,相应3个解码函数:unescape,decodeURI,decodeURIComponent 1 ...
- HikariCP 连接最快的连接池
三点原因 1.字节码精简 2.自定义 FastList 代替ArrayList ;避免每次get()调用都要进行range check,避免调用remove()时的从头到尾的扫描: 3.优化代码和拦截 ...
- 第06组 Alpha冲刺(3/6)
队名:拾光组 组长博客链接 作业博客链接 团队项目情况 燃尽图(组内共享) 组长:宋奕 过去两天完成了哪些任务 主要完成了用户论坛模块的接口设计 完善后端的信息处理 GitHub签入记录 接下来的计划 ...
- Android系统分区
Android系统开发时,经常会遇到添加或者调整系统分区大小的问题,下面以mstar的一款产品为例进行分析: (1)mount指令可以查看到板子中挂在的分区,主要关注ext4类型分区,例如tvserv ...
- JVM 启动类加载器2
在运行期,一个Java类是由该类的完全限定名(binary name,二进制名)和用于加载该类的定义类加载器(defining loading)所共同决定的.如果同样名字(即相同的完全限定名)的类由两 ...
- CMU Database Systems - Sorting,Aggregation,Join
Sorting 排序如果可在内存里面排,用经典的排序算法就ok,比如快排 问题在于,数据表中的的数据是很多的,没法一下都放到内存里面进行排序 所以就需要用到,外排,多路并归排序 看下最简单的,2路并归 ...
- 人脸替换(FaceSwap)的一些思考
本文链接:https://blog.csdn.net/cy1070779077/article/details/85224347人脸替换(FaceSwap)的一些思考 最一开始,我使用了openCV( ...
- 我大概知道他在说什么了,是对内存单元的竞争访问吧。Python有GIL,在执行伪码时是原子的。但是伪码之间不保证原子性。 UDP丢包,你是不是做了盲发?没有拥塞控制的情况下,确实会出现丢包严重的情况。你先看看发送速率,还有是否带有拥塞控制。
我大概知道他在说什么了,是对内存单元的竞争访问吧.Python有GIL,在执行伪码时是原子的.但是伪码之间不保证原子性. UDP丢包,你是不是做了盲发?没有拥塞控制的情况下,确实会出现丢包严重的情 ...