案例场景:用户下单后需要多个微服务(如营销、会员)分别订阅并处理订单事件,且每个微服务可能有多个集群实例,需要保证同一个微服务的集群中,只有一个实例消费到消息。

        不同于Kafka和rocketMQ有分组消费的功能,rabbitMQ需要通过topic Exchange实现。

        1、消息设计

{"event_type": "order_created",  // 事件类型(如下单、支付成功)"order_id": "123456","user_id": "user_789","items": [{"product_id": "p1001", "quantity": 2},{"product_id": "p1002", "quantity": 1}],"total_amount": 399.00,"created_at": "2025-07-01T12:00:00Z"
}

        2、rabbitMQ设计

        使用 topic 类型的 Exchange:支持灵活的路由规则,不同微服务可通过 binding key 订阅特定事件。
Exchange 名称示例:order_events。

微服务	    队列名	            绑定键(binding key)
营销系统	    marketing_queue	    order.created.marketing
会员系统	    member_queue	    order.created.member绑定键规则:<event_type>.<microservice_name>,便于后续扩展(如 order.cancel.marketing)。

        3、消息发布

        生产者(订单服务)发布消息时,指定路由键(routing key) 为 order.created

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.fasterxml.jackson.databind.ObjectMapper;public class OrderProducer {private static final String EXCHANGE_NAME = "order_events";private static final String ROUTING_KEY = "order.created";public static void main(String[] args) throws Exception {// 1. 创建连接ConnectionFactory factory = new ConnectionFactory();factory.setHost("localhost");factory.setUsername("guest");factory.setPassword("guest");try (Connection connection = factory.newConnection();Channel channel = connection.createChannel()) {// 2. topic Exchangechannel.exchangeDeclare(EXCHANGE_NAME, "topic", true);// 3. 构造消息OrderEvent event = new OrderEvent();event.setEvent_type("order_created");event.setOrder_id("123456");event.setUser_id("user_789");event.setItems(List.of(Map.of("product_id", "p1001", "quantity", 2)));event.setTotal_amount(399.00);event.setCreated_at("2025-07-02T22:00:00Z");ObjectMapper mapper = new ObjectMapper();String messageJson = mapper.writeValueAsString(event);// 4. 发布消息channel.basicPublish(EXCHANGE_NAME,ROUTING_KEY,true, // 持久化消息new AMQP.BasicProperties.Builder().deliveryMode(2) // 持久化.build(),messageJson.getBytes());System.out.println("Sent order event: " + messageJson);}}
}

        4、消息订阅(营销服务)

        不同服务只需要修改 QUEUE_NAME 和 BINDING_KEY 就可以了。 

import com.rabbitmq.client.*;
import com.fasterxml.jackson.databind.ObjectMapper;public class MarketingConsumer {private static final String QUEUE_NAME = "marketing_queue";private static final String BINDING_KEY = "order.created.marketing";public static void main(String[] args) throws Exception {ConnectionFactory factory = new ConnectionFactory();factory.setHost("localhost");factory.setUsername("guest");factory.setPassword("guest");Connection connection = factory.newConnection();Channel channel = connection.createChannel();// 1. 声明队列并绑定到 Exchangechannel.queueDeclare(QUEUE_NAME, true, false, false, null);channel.queueBind(QUEUE_NAME, "order_events", BINDING_KEY);// 2. 消费者回调DeliverCallback deliverCallback = (consumerTag, delivery) -> {String messageJson = new String(delivery.getBody(), "UTF-8");ObjectMapper mapper = new ObjectMapper();OrderEvent event = mapper.readValue(messageJson, OrderEvent.class);// 3. 业务逻辑:发送营销短信System.out.println("Marketing: Sending SMS for order " + event.getOrder_id());// 4. 手动确认消息channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);};// 5. 设置手动确认channel.basicConsume(QUEUE_NAME, false, deliverCallback, consumerTag -> {});}
}

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

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

相关文章

kotlin 通道trysend方法

trySend 方法是 Kotlin 协程中 Channel 类的一个重要功能。它用于向通道发送元素&#xff0c;但与 send 方法不同的是&#xff0c;trySend 是非阻塞的。这意味着它不会在通道满时挂起当前协程&#xff0c;而是会立即返回。 trySend 方法的效果 非阻塞行为&#xff1a; 当你调用…

winform CheckedListBox单击选中解决方案

在WinForms的CheckedListBox控件中&#xff0c;默认需要双击才能切换选中状态&#xff08;复选框勾选&#xff09;。要实现单击即选中&#xff0c;需要通过代码处理鼠标点击事件并手动切换选中状态。以下是实现步骤&#xff1a; 1.CheckOnClick属性置为true即可。 2.通过事件处…

Docker文件操作、数据卷、挂载

一&#xff1a;容器文件操作 在Docker环境中&#xff0c;管理容器内部的文件是一个常见的需求。 无论是为了配置应用、备份数据还是调试问题&#xff0c;了解如何高效地进行文件操作都是非常重要的。 docker cp命令提供了一种简单的方法来在宿主主机和容器之间复制文件或目录…

接口漏洞怎么抓?Fiddler 中文版 + Postman + Wireshark 实战指南

接口安全是现代应用开发中的高危环节&#xff1a;一旦API存在未授权访问、参数篡改、权限绕过等漏洞&#xff0c;可能直接导致用户信息泄露、资金损失甚至整个平台瘫痪。对于开发和安全人员来说&#xff0c;光依赖后端日志排查远远不够&#xff0c;需要对接口进行主动安全性验证…

iOS 出海 App 安全加固指南:无源码环境下的 IPA 加固与防破解方法

随着越来越多国内开发团队将iOS App推向海外市场&#xff0c;如何在交付和分发环节保护应用安全成为出海过程中的重要议题。尤其是App进入多个海外应用商店或通过第三方渠道发行时&#xff0c;容易被当地黑产或竞争对手进行逆向分析&#xff0c;从而暴露内部API、核心业务流程等…

React Hooks 内部实现原理与函数组件更新机制

React Hooks 内部实现原理与函数组件更新机制 Hooks 的内部实现原理 React Hooks 的实现依赖于以下几个关键机制&#xff1a; 1. 链表结构存储 Hook 状态 React 使用单向链表来管理 Hooks 的状态。每个 Hook 节点包含&#xff1a; type Hook {memoizedState: any, // 存储…

分布式会话的演进和最佳实践,含springBoot 实现(Java版本)

一、分布式会话的背景 在微服务架构或集群部署环境下&#xff0c;请求可能落在不同的服务器节点&#xff0c;无法再依赖本地内存来维护用户 Session。因此&#xff0c;需要一种跨节点共享 Session 的机制&#xff0c;这就是 分布式会话管理的核心目标。二、分布式会话的演进历程…

ch03 部分题目思路

G. 收集 由于稀有度相同的物品需要一起处理&#xff0c;我们先把他们聚集到一起。 类似这样&#xff1a; vector<int> g[maxn]; ... {cin >> x >> c;g[c].push_back(x); }那么我们需要一个贪心的思路&#xff1a; 肯定是按 ccc 从小往大收集的&#xff1b;对…

Django多表查询(ORM)

1、建立表结构 三个表&#xff1a;book、Author、publisher。 书籍和作者是多对多的关系&#xff0c;一本书可以有多个作者&#xff0c;一个作者可以有多本书。 出版社和书籍是一对多的关系&#xff0c;一个出版社可以出版多本书&#xff08;多方&#xff0c;多方定义外键&…

C# 集合表达式和展开运算符 (..) 详解

集合表达式 (Collection Expressions)基本语法支持的集合类型展开运算符 (..)基本用法实际应用示例创建新集合合并集合与现有API结合性能考虑高级用法多维集合自定义集合注意事项与传统方式的比较总结集合表达式 (Collection Expressions) C# 12 引入了集合表达式&#xff0c;…

数学视频动画引擎Python库 -- Manim Voiceover 安装 Installation

文中内容仅限技术学习与代码实践参考&#xff0c;市场存在不确定性&#xff0c;技术分析需谨慎验证&#xff0c;不构成任何投资建议。 Manim Voiceover 是一个为 Manim 打造的专注于语音旁白的插件&#xff1a; 直接在 Python 中添加语音旁白&#xff1a; 无需使用视频编辑器&…

Git安装避坑指南:新手村通关秘籍

Git安装避坑指南&#xff1a;新手村通关秘籍 刚学编程那会儿&#xff0c;Git安装差点让我砸键盘。满心欢喜打开官网下载&#xff0c;结果卡在配置上&#xff0c;命令行死活不认识git命令。看着教程里别人行云流水的操作&#xff0c;自己对着报错信息干瞪眼——这感觉&#xff…

如何修改Siteground max_execution_time值?

这个值在Siteground 上是修改不了的。 以下是来自Siteground 官网的解释&#xff1a; 由于服务器上全局定义的 PHP 限制&#xff0c;某些 PHP 设置无法更改。最常见的无法更改的 PHP 设置包括&#xff1a; memory_limit max_execution_time max_input_time post_max_size up…

【libm】 11 fmin函数 (fmin.rs)

一、源码 这段代码实现了一个符合 IEEE 754-2008 标准的 minNum 函数&#xff08;在 Rust 中命名为 fmin&#xff09;&#xff0c;该功能在 IEEE 754-2019 标准中已被 minimumNumber 取代。 /* SPDX-License-Identifier: MIT OR Apache-2.0 */ //! IEEE 754-2008 minNum. Thi…

React 英语单词消消乐一款专为英语学习设计的互动式记忆游戏

&#x1f4d6; 项目简介 英语单词消消乐 是一款专为英语学习设计的互动式记忆游戏。通过经典的消消乐玩法&#xff0c;让用户在轻松愉快的游戏中掌握英语单词&#xff0c;提高词汇量和记忆效果。 &#x1f3af; 项目目标 让英语学习变得有趣且高效通过游戏化方式增强单词记忆…

Qt:QPushButton、QRadioButton、QCheckBox

目录 一、QPushButton 1.认识QPushButton 2.设置按钮图标 3.设置按钮的快捷键 二、QRadioButton 常用的信号 按钮的分组 三、QCheckBox 一、QPushButton 1.认识QPushButton QPushButton继承自QWidget&#xff0c;所以在上一篇文章中介绍的QWidget的属性&#xff0c;理…

docker 无法拉取镜像解决方法

目录 我在omv中通过后台页面拉取alist镜像总是失败&#xff0c;原因千奇百怪 今天再战终于解决首先&#xff0c;到dockerhub找镜像和wiki进入docker账号设置 找到里面提示了登录操作和密码命令行中执行后会提示成功之后按需配置代理&#xff0c;同时检查自己的配置检查 Docker …

安卓10.0系统修改定制化_____安卓9与安卓10系统文件差异 有关定制选项修改差异

在修改安卓10的rom之前。我们需要对rom有简单的了解。区分安卓10与安卓9之间的差异。了解不同安卓版本之间系统文件的变化以及权限的区别。对于修改一些定制化选项有很大的辅助作用. 通过博文了解💝💝💝 1💝💝💝-----安卓10与安卓9之间文件实例对比 了解差异 …

HTML表单元素全面指南:从基础到实践

引言 HTML表单是网页开发中不可或缺的一部分&#xff0c;它为用户提供了与网站交互的途径。无论是简单的登录页面还是复杂的数据提交界面&#xff0c;表单元素都扮演着关键角色。本文将详细介绍各种HTML表单元素及其使用方法。 输入框(input元素) input元素是最基础也是最灵…

深度学习的核心理论与技术

理解深度学习的基本原理、核心算法和关键技术 深度学习的核心理论与技术前言一、深度学习核心理论1. 神经网络基础核心内容练习资源2. 反向传播与梯度下降核心内容练习资源3. 卷积神经网络&#xff08;CNN&#xff09;核心内容练习资源4. 循环神经网络&#xff08;RNN&#xff…