【RabbitMQ】golang客户端教程1——HelloWorld
一、介绍
本教程假设RabbitMQ已安装并运行在本机上的标准端口(5672)。如果你使用不同的主机、端口或凭据,则需要调整连接设置。如果你未安装RabbitMQ,可以浏览我上一篇文章Linux系统服务器安装RabbitMQ
RabbitMQ是一个消息代理:它接受并转发消息。你可以把它想象成一个邮局:当你把你想要邮寄的邮件放进一个邮箱时,你可以确定邮差先生或女士最终会把邮件送到你的收件人那里。在这个比喻中,RabbitMQ是一个邮箱、一个邮局和一个邮递员。
RabbitMQ和邮局的主要区别在于它不处理纸张,而是接受、存储和转发二进制数据块——消息。
RabbitMQ和一般的消息传递都使用一些术语。
-
生产仅意味着发送。发送消息的程序是生产者:

-
队列是位于RabbitMQ内部的邮箱的名称。尽管消息通过RabbitMQ和你的应用程序流动,但它们只能存储在队列中。队列只受主机内存和磁盘限制的限制,实际上它是一个大的消息缓冲区。许多生产者可以向一个队列发送消息,而许多消费者可以尝试从一个队列接收数据。以下是我们表示队列的方式:

-
消费与接收具有相似的含义。消费者是一个主要等待接收消息的程序:

请注意,生产者,消费者和代理(broker)不必位于同一主机上。实际上,在大多数应用程序中它们不是。一个应用程序既可以是生产者,也可以是消费者。
二、Hello World
在本教程的这一部分中,我们将在Go中编写两个小程序:发送单个消息的生产者和接收消息并将其打印出来的消费者。我们将忽略Go-RabbitMQ API中的一些细节,只关注非常简单的事情,以便开始教程。这是一个消息传递版的“Hello World”。
在下图中,“ P”是我们的生产者,“ C”是我们的消费者。中间的框是一个队列——RabbitMQ代表消费者保存的消息缓冲区。

RabbitMQ讲多种协议。本教程使用amqp0-9-1,这是一个开放的、通用的消息传递协议。RabbitMQ有许多不同语言的客户端。在本教程中,我们将使用Go amqp客户端。
首先,使用go get安装amqp
go get github.com/streadway/amqp
三、发送

我们将消息发布者(发送者)称为 send.go,将消息消费者(接收者)称为receive.go。发布者将连接到RabbitMQ,发送一条消息,然后退出。
在send.go中,我们需要首先导入库:
package mainimport ("log""github.com/streadway/amqp"
)
我们还需要一个辅助函数来检查每个amqp调用的返回值:
func failOnErrorSend(err error, msg string) {if err != nil {log.Fatalf("%s: %s", msg, err)}
}
然后连接到RabbitMQ服务器
// 1. 尝试连接RabbitMQ,建立连接
// 该连接抽象了套接字连接,并为我们处理协议版本协商和认证等。
conn, err := amqp.Dial("amqp://guest:guest@localhost:5672/")
failOnErrorSend(err, "Failed to connect to RabbitMQ")
defer conn.Close()
其中,amqp.Dial 是用于建立连接到 RabbitMQ 的函数,它使用 AMQP 协议进行通信。该函数的参数是 RabbitMQ 服务器的连接字符串。
amqp://<username>:<password>@<host>:<port>/<vhost>
- username : RabbitMQ 用户的用户名。
- password: RabbitMQ 用户的密码。
- host: RabbitMQ服务器的主机名或IP地址。
- port: RabbitMQ 服务器的端口号。
- vhost:需要连接的虚拟主机。
连接抽象了socket连接,并为我们处理协议版本协商和认证等。接下来,我们创建一个通道,这是大多数用于完成任务的API所在的位置:
// 2. 接下来,我们创建一个通道,大多数API都是用过该通道操作的。
ch, err := conn.Channel()
failOnErrorSend(err, "Failed to open a channel")
defer ch.Close()
要发送,我们必须声明要发送到的队列。然后我们可以将消息发布到队列:
// 3. 声明消息要发送到的队列
q, err := ch.QueueDeclare("hello", // 队列的名称false, // 队列是否持久化false, // 队列是否在最后一个消费者断开连接后自动删除false, // 是否设置队列为独占模式false, // 是否不等待服务器的响应nil, // 队列的可选参数
)
failOnErrorSend(err, "Failed to declare a queue")body := "Hello World!"
// 4.将消息发布到声明的队列
err = ch.Publish("", // 要发布消息的目标交换器的名称。q.Name, // 消息的路由键。交换器根据路由键将消息路由到相应的队列。false, // 是否要求至少一个队列接收该消息false, // 是否要求消息在发布时立即被消费者接收amqp.Publishing { ContentType: "text/plain",Body: []byte(body),})//要发布的消息内容
failOnErrorSend(err, "Failed to publish a message")
声明队列是幂等的——仅当队列不存在时才创建。消息内容是一个字节数组,因此你可以在此处编码任何内容。
完整代码:
package mainimport ("github.com/streadway/amqp""log"
)func failOnErrorSend(err error, msg string) {if err != nil {log.Fatalf("%s: %s", msg, err)}
}
func main() {//1.连接RabbitMQ,建立连接//该连接抽象了套接字连接,并为我们处理协议版本协商和认证等。conn, err := amqp.Dial("amqp://licong:123456@8.130.85.112:5672/")failOnErrorSend(err, "Failed to connect to RabitMQ")defer conn.Close()//2.接下来,我们创建一个通道,这是大多数用户完成任务的API所在的位置:ch, err := conn.Channel()failOnErrorSend(err, "Fail to open a channel")defer ch.Close()//3.声明消息要发送的队列q, err := ch.QueueDeclare("hello", //namefalse, //durablefalse, //delete when unusedfalse, //exclusivefalse, //no-waitnil, //arguments)failOnErrorSend(err, "Failed to declare a queue")body := "Hello World!"//4.将消息发布到声明的队列err = ch.Publish("", //exchangeq.Name, //routing keyfalse, //mandatoryfalse, //immediateamqp.Publishing{ContentType: "text/plain",Body: []byte(body),},)failOnErrorSend(err, "Failed to publish a message")log.Printf(" [x] Sent %s\n", body)
}
四、发送
上面是我们的发布者。我们的消费者监听来自RabbitMQ的消息,因此与发布单个消息的发布者不同,我们将使消费者保持运行状态以监听消息并打印出来。

该代码(在receive.go中)具有与send相同的导入和帮助功能:
import ("github.com/streadway/amqp""log"
)func failOnErrorReceive(err error, msg string) {if err != nil {log.Fatalf("%s: %s", msg, err)}
}
设置与发布者相同;我们打开一个连接和一个通道,并声明要消耗的队列。请注意,这与send发布到的队列匹配。
//建立连接conn, err := amqp.Dial("amqp://licong:123456@8.130.85.112:5672/")failOnErrorReceive(err, "Failed to connect to RabbitMQ")defer conn.Close()//获取channelch, err := conn.Channel()failOnErrorReceive(err, "Failed to open a channel")defer ch.Close()//声明队列q, err := ch.QueueDeclare("hello", //namefalse, //durablefalse, //delete when unusedfalse, //exclusivefalse, //no-waitnil, //argument)failOnErrorReceive(err, "Failed to declare a queue")
failOnError(err, "Failed to declare a queue")
请注意,我们也在这里声明队列。因为我们可能在发布者之前启动使用者,所以我们希望在尝试使用队列中的消息之前确保队列存在。
我们将告诉服务器将队列中的消息传递给我们。由于它将异步地向我们发送消息,因此我们将在goroutine中从通道(由amqp::Consume返回)中读取消息。
//获取接收消息的Delivery通道msgs, err := ch.Consume(q.Name, //要消费消息的队列名称"", //消费者标识,留空字符串会自动生成一个唯一标识符。true, //是否自动确认消息false, //是否设置队列为独占模式false, //是否禁止消费者接收自己发布的消息false, //是否不等待服务器的响应nil, //队列的可选参数)failOnErrorReceive(err, "Failed to register a consumer")forever := make(chan bool)go func() {for d := range msgs {log.Printf("Reveived a message:%s", d.Body)}}()log.Printf("[*] Waiting for messages. To exit press CTRL+C")<-forever
五、运行
终端运行:
go run send.go

go run receive.go

源自:https://www.rabbitmq.com/getstarted.html
相关文章:
【RabbitMQ】golang客户端教程1——HelloWorld
一、介绍 本教程假设RabbitMQ已安装并运行在本机上的标准端口(5672)。如果你使用不同的主机、端口或凭据,则需要调整连接设置。如果你未安装RabbitMQ,可以浏览我上一篇文章Linux系统服务器安装RabbitMQ RabbitMQ是一个消息代理&…...
计算机图形学笔记2-Viewing 观测
观测主要解决的问题是如何把物体的三维“模型”变成我们在屏幕所看到的二维“图片”,我们在计算机看到实体模型可以分成这样几步: 相机变换(camera transformation)或眼变换(eye transformation):想象把相机放在任意一个位置来观测物体&#…...
Redis - 三大缓存问题(穿透、击穿、雪崩)
缓存穿透 概念: 查询一个数据库中也不存在的数据,数据库查询不到数据也就不会写入缓存,就会导致一直查询数据库 解决方法: 1. 缓存空数据 如果数据库也查询不到,就把空结果进行缓存 缺点是 - 消耗内存 2. 使用布…...
web自动化测试-PageObject 设计模式
为 UI 页面写测试用例时(比如 web 页面,移动端页面),测试用例会存在大量元素和操作细节。当 UI 变化时,测试用例也要跟着变化, PageObject 很好的解决了这个问题。 使用 UI 自动化测试工具时(包…...
golang json.Marshal() 结构体、map 携带 符号 转成 “\u0026“
问题:数据结构中的值 带有 & > < 等符号,当我们要将 struct map 转成json时,使用 json.Marshal() 函数,此函数会将 值中的 & < > 符号转义 为 类似 "\u0026" 像我们某个结构体中…...
【设计模式|行为型】备忘录模式(Memento Pattern)
说明 备忘录模式是一种行为型设计模式,通过捕获一个对象的内部状态,并在该对象之外保存这个状态,以便在需要时恢复对象到原先的状态。备忘录模式包含三个核心角色:。 发起人(Originator):负责…...
Redis与其他缓存解决方案(如Memcached)的区别是什么?
Redis和其他缓存解决方案(如Memcached)在设计理念、功能和特点上有一些区别,以下是它们的主要区别: 数据类型支持:Redis支持多种数据类型(如字符串、哈希表、列表、集合、有序集合等)࿰…...
《面试1v1》Kafka的ack机制
🍅 作者简介:王哥,CSDN2022博客总榜Top100🏆、博客专家💪 🍅 技术交流:定期更新Java硬核干货,不定期送书活动 🍅 王哥多年工作总结:Java学习路线总结…...
基于双 STM32+FPGA 的桌面数控车床控制系统设计
桌 面数控 设 备 对 小 尺寸零件加工在成 本 、 功 耗 和 占 地 面 积等方 面有 着 巨 大 优 势 。 桌 面数控 设 备 大致 有 3 种 实 现 方 案 : 第 一种 为 微 型 机 床搭 配 传统 数控系 统 , 但 是 桌 面数控 设 备 对 成 本 敏感 ; 第二 种 为 基 于 PC…...
ES-5-进阶
单机 & 集群 单台 Elasticsearch 服务器提供服务,往往都有最大的负载能力,超过这个阈值,服务器 性能就会大大降低甚至不可用,所以生产环境中,一般都是运行在指定服务器集群中 配置服务器集群时,集…...
Java面试准备篇:全面了解面试流程与常见问题
文章目录 1.1 Java面试概述1.2 面试流程和注意事项1.3 自我介绍及项目介绍1.4 常见面试问题 在现代职场中,面试是求职过程中至关重要的一环,特别是对于Java开发者而言。为了帮助广大Java开发者更好地应对面试,本文将提供一份全面的Java面试准…...
Go语言进阶语法八万字详解,通俗易懂
文章目录 File文件操作FileInfo接口权限打开模式File操作文件读取 I/O操作io包 文件复制io包下的Read()和Write()io包下的Copy()ioutil包总结 断点续传Seeker接口断点续传 bufio包bufio包原理Reader对象Writer对象 bufio包bufio.Readerbufio.Writer ioutil包ioutil包的方法示例…...
Apache RocketMQ 远程代码执行漏洞(CVE-2023-37582)
漏洞简介 Apache RocketMQ是一款低延迟、高并发、高可用、高可靠的分布式消息中间件。CVE-2023-37582 中,由于对 CVE-2023-33246 修复不完善,导致在Apache RocketMQ NameServer 存在未授权访问的情况下,攻击者可构造恶意请求以RocketMQ运…...
Kotlin Multiplatform 使用 CocoaPods 创建多平台分发库
Kotlin Multiplatform 支持直接创建Framework 方式和使用CocoaPods 方式创建Framework。 1、不同之处在于创建的时候需要选择不同的方式。 2、使用CocoaPods 方式还需要在 build.gradle(.kts) 文件中添加内容 在build.gradle(.kts) 文件中添加完成后,执行一下文件。…...
前端食堂技术周刊第 92 期:VueConf 2023、TypeChat、向量数据库、Nuxt 服务器组件指南
美味值:🌟🌟🌟🌟🌟 口味:整颗牛油果酸奶 食堂技术周刊仓库地址:https://github.com/Geekhyt/weekly 大家好,我是童欧巴。欢迎来到前端食堂技术周刊,我们先…...
用C语言构建一个手写数字识别神经网络
(原理和程序基本框架请参见前一篇 "用C语言构建了一个简单的神经网路") 1.准备训练和测试数据集 从http://yann.lecun.com/exdb/mnist/下载手写数字训练数据集, 包括图像数据train-images-idx3-ubyte.gz 和标签数据 train-labels-idx1-ubyte.…...
vue关闭ESlint
在 vue.config.js里边写上这一句代码 lintOnsave:false写完后重启一下项目...
测试开发人员如何进行局部探索性测试?一张图告诉你
我们都知道全局探索性测试的漫游测试法,也知道局部探索性测试可以从用户输入、状态、代码路径、用户数据和执行环境测试着手点。 那么,如果我们能够获取开发代码,我们怎么从代码入手,进行具体的局部探索性测试呢? 简单…...
CentOS 8 上安装 Nginx
Nginx是一款高性能的开源Web服务器和反向代理服务器,以其轻量级和高效能而广受欢迎。在本教程中,我们将学习在 CentOS 8 操作系统上安装和配置 Nginx。 步骤 1:更新系统 在安装任何软件之前,让我们先更新系统的软件包列表和已安…...
【c语言进阶】字符函数和字符串函数知识总结
字符函数和字符串函数 前期背景求字符串长度函数strlen函数strlen函数三种模拟实现 长度不受限制的字符串函数strcpy函数strcpy函数模拟实现strcat函数strcat函数模拟实现strcmp函数strcmp函数模拟实现 长度受限制的字符串函数strncpy函数strncpy函数模拟实现strncat函数strnca…...
【Python】 -- 趣味代码 - 小恐龙游戏
文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...
Spring Boot 实现流式响应(兼容 2.7.x)
在实际开发中,我们可能会遇到一些流式数据处理的场景,比如接收来自上游接口的 Server-Sent Events(SSE) 或 流式 JSON 内容,并将其原样中转给前端页面或客户端。这种情况下,传统的 RestTemplate 缓存机制会…...
云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地
借阿里云中企出海大会的东风,以**「云启出海,智联未来|打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办,现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...
Qt Widget类解析与代码注释
#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码,写上注释 当然可以!这段代码是 Qt …...
Frozen-Flask :将 Flask 应用“冻结”为静态文件
Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是:将一个 Flask Web 应用生成成纯静态 HTML 文件,从而可以部署到静态网站托管服务上,如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...
2021-03-15 iview一些问题
1.iview 在使用tree组件时,发现没有set类的方法,只有get,那么要改变tree值,只能遍历treeData,递归修改treeData的checked,发现无法更改,原因在于check模式下,子元素的勾选状态跟父节…...
ETLCloud可能遇到的问题有哪些?常见坑位解析
数据集成平台ETLCloud,主要用于支持数据的抽取(Extract)、转换(Transform)和加载(Load)过程。提供了一个简洁直观的界面,以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...
unix/linux,sudo,其发展历程详细时间线、由来、历史背景
sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...
《基于Apache Flink的流处理》笔记
思维导图 1-3 章 4-7章 8-11 章 参考资料 源码: https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...
HTML前端开发:JavaScript 常用事件详解
作为前端开发的核心,JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例: 1. onclick - 点击事件 当元素被单击时触发(左键点击) button.onclick function() {alert("按钮被点击了!&…...
