【RabbitMQ】golang客户端教程5——使用topic交换器

topic交换器(主题交换器)

发送到topic交换器的消息不能具有随意的routing_key——它必须是单词列表,以点分隔。这些词可以是任何东西,但通常它们指定与消息相关的某些功能。一些有效的routing_key示例:“stock.usd.nyse”“nyse.vmw”“quick.orange.rabbit”routing_key中可以包含任意多个单词,最多255个字节。

绑定键也必须采用相同的形式。topic交换器背后的逻辑类似于direct交换器——用特定路由键发送的消息将传递到所有匹配绑定键绑定的队列。但是,绑定键有两个重要的特殊情况: - *(星号)可以代替一个单词。 - #(井号)可以替代零个或多个单词。

通过下面这个示例可以很容易看明白这一点:

在这里插入图片描述
在这个例子中,我们将发送一些都是描述动物的信息。将使用包含三个词(两个点)的路由密钥发送消息。路由键中的第一个单词将描述速度,第二个是颜色,第三个是种类:“<speed>.<colour>.<species>”

我们创建了三个绑定关系:Q1与绑定键“ * .orange. * ”绑定,Q2与“* .* .rabbit”和“lazy.#”绑定。

这些绑定可以总结为:

  • Q1对所有橙色动物都感兴趣
  • Q2想接收有关兔子(rabbit)的一切消息,以及有关懒惰(lazy)动物的一切消息。

路由键设置为“quick.orange.rabbit”的消息将传递到两个队列。消息“lazy.orange.elephant”也将发送给他们两个。另一方面,“quick.orange.fox”将仅进入第一个队列,而“lazy.brown.fox”将仅进入第二个队列。即使“lazy.pink.rabbit”与两个绑定匹配(匹配Q2的两个绑定),也只会传递到第二个队列一次。 “quick.brown.fox”与任何绑定都不匹配,因此将被丢弃。

如果我们打破约定并发送一个或四个单词的消息,例如“orange”“quick.orange.male.rabbit”,会发生什么?好吧,这些消息将不匹配任何绑定,并且将会丢失。

另外,“lazy.orange.male.rabbit”即使有四个单词,也将匹配最后一个绑定,并将其传送到第二个队列。

topic交换器

topic交换器功能强大,可以像其他交换器一样运行。

当队列用“#”(井号)绑定键绑定时,它将接收所有消息,而与路由键无关,就像在fanout交换器中一样。

当在绑定中不使用特殊字符“*”(星号)和“#”(井号)时,topic交换器的行为就像direct交换器一样。

完整示例

我们将在日志记录系统中使用topic交换器。我们将从一个可行的假设开始,即日志的路由键将包含两个词:“<facility>.<severity>”

emit_log_topic.go的代码:

package mainimport ("log""os""strings""github.com/streadway/amqp"
)func failOnError(err error, msg string) {if err != nil {log.Fatalf("%s: %s", msg, err)}
}func main() {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()err = ch.ExchangeDeclare("logs_topic", // name"topic",      // typetrue,         // durablefalse,        // auto-deletedfalse,        // internalfalse,        // no-waitnil,          // arguments)failOnError(err, "Failed to declare an exchange")body := bodyFrom(os.Args)err = ch.Publish("logs_topic",          // exchangeseverityFrom(os.Args), // routing keyfalse, // mandatoryfalse, // immediateamqp.Publishing{ContentType: "text/plain",Body:        []byte(body),})failOnError(err, "Failed to publish a message")log.Printf(" [x] Sent %s", body)
}func bodyFrom(args []string) string {var s stringif (len(args) < 3) || os.Args[2] == "" {s = "hello"} else {s = strings.Join(args[2:], " ")}return s
}func severityFrom(args []string) string {var s stringif (len(args) < 2) || os.Args[1] == "" {s = "anonymous.info"} else {s = os.Args[1]}return s
}

receive_logs_topic.go 的代码:

package mainimport ("log""os""github.com/streadway/amqp"
)func failOnError(err error, msg string) {if err != nil {log.Fatalf("%s: %s", msg, err)}
}func main() {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()err = ch.ExchangeDeclare("logs_topic", // name"topic",      // typetrue,         // durablefalse,        // auto-deletedfalse,        // internalfalse,        // no-waitnil,          // arguments)failOnError(err, "Failed to declare an exchange")q, err := ch.QueueDeclare("",    // namefalse, // durablefalse, // delete when unusedtrue,  // exclusivefalse, // no-waitnil,   // arguments)failOnError(err, "Failed to declare a queue")if len(os.Args) < 2 {log.Printf("Usage: %s [binding_key]...", os.Args[0])os.Exit(0)}// 绑定topicfor _, s := range os.Args[1:] {log.Printf("Binding queue %s to exchange %s with routing key %s",q.Name, "logs_topic", s)err = ch.QueueBind(q.Name,       // queue names,            // routing key"logs_topic", // exchangefalse,nil)failOnError(err, "Failed to bind a queue")}msgs, err := ch.Consume(q.Name, // queue"",     // consumertrue,   // auto ackfalse,  // exclusivefalse,  // no localfalse,  // no waitnil,    // args)failOnError(err, "Failed to register a consumer")forever := make(chan bool)go func() {for d := range msgs {log.Printf(" [x] %s", d.Body)}}()log.Printf(" [*] Waiting for logs. To exit press CTRL+C")<-forever
}

想要接收所有的日志:

go run receive_logs_topic.go "#"

要从“kern”接收所有日志:

go run receive_logs_topic.go "kern.*"

或者,如果你只想接收“critical”日志:

go run receive_logs_topic.go "*.critical"

你可以创建多个绑定:

go run receive_logs_topic.go "kern.*" "*.critical"

并发出带有路由键“kern.critical”的日志:

go run emit_log_topic.go "kern.critical" "A critical kernel error"

你可以自己尝试玩一下这个程序。请注意,代码没有对路由键或绑定键进行任何假设,你可能希望使用两个以上的路由键参数。

源自:https://www.rabbitmq.com/getstarted.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/86590.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

8月11日上课内容 nginx的多实例和动静分离

多实例部署 在一台服务器上有多个tomcat的服务。 配置多实例之前&#xff0c;看单个实例是否访问正常。 1.安装好 jdk 2.安装 tomcat cd /opt tar zxvf apache-tomcat-9.0.16.tar.gz mkdir /usr/local/tomcat mv apache-tomcat-9.0.16 /usr/local/tomcat/tomcat1 cp -a /usr…

利用三维内容编辑器制作VR交互课件,简单好用易上手

随着虚拟现实技术的不断发展&#xff0c;越来越多的教育机构开始尝试将其应用于教育教学中。然而&#xff0c;要实现这一目标并不容易&#xff0c;需要专业的技术支持和开发团队。 为了解决这一问题&#xff0c;广州华锐互动研发了三维内容编辑器&#xff0c;它是一种基于虚拟现…

“掌握类与对象,点亮编程之路“(下)

White graces&#xff1a;个人主页 &#x1f649;专栏推荐:《C语言入门知识》&#x1f649; &#x1f649; 内容推荐:“掌握类与对象&#xff0c;点亮编程之路“(上)&#x1f649; &#x1f439;今日诗词:春风得意马蹄疾&#xff0c;一日看尽长安花&#x1f439; 目录 &…

fork创建多个子进程

fork创建多个子进程 示例代码 fork1.c #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <unistd.h>int main(int argc,char **argv) {int i, j;pid_t pid;for (i 0; i < 3; i){pid fork();if (pid < 0){perror(&q…

Python 11道字典练习题

前言 大家早好、午好、晚好吖 ❤ ~欢迎光临本文章 有字典 dic {“k1”: “v1”, “k2”: “v2”, “k3”: “v3”}&#xff0c;实现以下功能&#xff1a; 1、遍历字典 dic 中所有的key 参考答案&#xff1a; dic {k1: v1,k2:v2,k3:v3}for k in dic.keys():print(k)2、遍历…

Apollo让自动驾驶如此简单

前言&#xff1a; 最近被新能源的电价闹的不行&#xff0c;买了电车的直呼上当了、不香了。但电车吸引人不只是公里油耗低&#xff0c;还有良好的驾车使用感。比如辅助驾驶、甚至是自动驾驶。今天来介绍一个头部自动驾驶平台Apollo&#xff0c;Apollo是一个开源的、自动驾驶的软…

在SpringMVC环境下json字符串与对象转化 配置和对象方法

目录 1..json的使用 字符串与对象转化 2.通过spring配置的形式直接接受json格式字符串转化 1..json的使用 字符串与对象转化 1.导入一个json的jar坐标 <dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</…

el-dialog嵌套,修改内层el-dialog样式(自定义样式)

el-dialog嵌套使用时,内层的el-dialog要添加append-to-body属性 给内层的el-dialog添加custom-class属性,添加自定义类名 <el-dialog:visible.sync"dialogVisible"append-to-bodycustom-class"tree-cesium-container"><span>这是一段信息<…

详细教程:如何搭建废品回收小程序

废品回收是一项环保举措&#xff0c;通过回收和再利用废弃物品&#xff0c;可以减少资源浪费和环境污染。近年来&#xff0c;随着智能手机的普及&#xff0c;小程序成为了推广和运营的重要工具。本文将详细介绍如何搭建一个废品回收小程序。 1. 进入乔拓云网后台 首先&#xf…

深入浅出cgroup

一、什么是cgroup Cgroup是linux内核用来控制系统资源的机制&#xff0c;它将操作系统中的所有进程以组为单位划分&#xff0c;给这一组进程定义对某一类资源特定的访问权限。Cgroup用子系统&#xff08;subsystem&#xff09;来描述所能控制的系统资源&#xff0c;子系统具有…

头条移动端项目Day02—— app端文章查看、静态化freemarker、分布式文件系统minIO

❤ 作者主页&#xff1a;欢迎来到我的技术博客&#x1f60e; ❀ 个人介绍&#xff1a;大家好&#xff0c;本人热衷于Java后端开发&#xff0c;欢迎来交流学习哦&#xff01;(&#xffe3;▽&#xffe3;)~* &#x1f34a; 如果文章对您有帮助&#xff0c;记得关注、点赞、收藏、…

OceanBase X Flink 基于原生分布式数据库构建实时计算解决方案

摘要&#xff1a;本文整理自 OceanBase 架构师周跃跃&#xff0c;在 Flink Forward Asia 2022 实时湖仓专场的分享。本篇内容主要分为四个部分&#xff1a; 分布式数据库 OceanBase 关键技术解读 生态对接以及典型应用场景 OceanBase X Flink 在游戏行业实践 未来展望 点击…

机器学习深度学习——seq2seq实现机器翻译(数据集处理)

&#x1f468;‍&#x1f393;作者简介&#xff1a;一位即将上大四&#xff0c;正专攻机器学习的保研er &#x1f30c;上期文章&#xff1a;机器学习&&深度学习——从编码器-解码器架构到seq2seq&#xff08;机器翻译&#xff09; &#x1f4da;订阅专栏&#xff1a;机…

(el-Form)操作(不使用 ts):Element-plus 中 Form 表单组件校验规则等的使用

Ⅰ、Element-plus 提供的 Form 表单组件与想要目标情况的对比&#xff1a; 1、Element-plus 提供 Form 表单组件情况&#xff1a; 其一、Element-plus 自提供的 Form 代码情况为(示例的代码)&#xff1a; // Element-plus 自提供的代码&#xff1a; // 此时是使用了 ts 语言环…

机器学习深度学习——从编码器-解码器架构到seq2seq(机器翻译)

&#x1f468;‍&#x1f393;作者简介&#xff1a;一位即将上大四&#xff0c;正专攻机器学习的保研er &#x1f30c;上期文章&#xff1a;机器学习&&深度学习——注意力提示、注意力池化&#xff08;核回归&#xff09; &#x1f4da;订阅专栏&#xff1a;机器学习&a…

使用 prometheus client SDK 暴露指标

目录 1. 使用 prometheus client SDK 暴露指标1.1. How Go exposition works1.2. Adding your own metrics1.3. Other Go client features 2. Golang Application monitoring using Prometheus2.1. Metrics and Labels2.2. Metrics Types2.2.1. Counters:2.2.2. Gauges:2.2.3. …

写一个函数返回参数二进制中 1 的个数(c语言三种实现方法)

&#xff08;本文旨在自己做题时的总结&#xff0c;我会给出不同的解法&#xff0c;后面如果碰到新的题目还会加入其中&#xff0c;等于是我自己的题库。 1.写一个函数返回参数二进制中 1 的个数。 比如&#xff1a; 15 0000 1111 4 个 1 方法一&#xff1a; #include…

基于 eclipse-temurin 镜像部署spring boot 应用

基于 eclipse-temurin 镜像部署spring boot 应用 使用场景示例项目 使用场景 在CI流程中&#xff0c;一般都会集成 打包&#xff0c;构建镜像&#xff0c;分发&#xff0c;启动容器之类的流程&#xff1b; 这里提供一个示例&#xff0c;进攻参考 示例项目 项目结构如下 run…

Django基础

1.Django基础 路由系统视图模板静态文件和媒体文件中间件ORM&#xff08;时间&#xff09; 2.路由系统 本质上&#xff1a;URL和函数的对应关系。 2.1 传统的路由 from django.contrib import admin from django.urls import path from apps.web import viewsurlpatterns …

体渲染原理及WebGL实现【Volume Rendering】

体渲染&#xff08;Volume Rendering&#xff09;是NeRF神经场辐射AI模型的基础&#xff0c;与传统渲染使用三角形来显示 3D 图形不同&#xff0c;体渲染使用其他方法&#xff0c;例如体积光线投射 (Volume Ray Casting)。本文介绍体渲染的原理并提供Three.js实现代码&#xff…