网站开发 系统需求文档东莞厚街网站建设
2026/6/9 20:32:01 网站建设 项目流程
网站开发 系统需求文档,东莞厚街网站建设,h5小程序,专业网站开发开发TL;DR 场景#xff1a;JMS Topic 在应用集群中广播#xff0c;导致同一业务被多节点重复消费结论#xff1a;用 ActiveMQ Virtual Topic#xff08;或 JMS 2.0 Shared Subscription#xff09;把“组间广播 组内竞争消费”落到中间件层产出#xff1a;Queue/Topic 选型…TL;DR场景JMS Topic 在应用集群中广播导致同一业务被多节点重复消费结论用 ActiveMQ Virtual Topic或 JMS 2.0 Shared Subscription把“组间广播 组内竞争消费”落到中间件层产出Queue/Topic 选型边界、PERSISTENT/NON_PERSISTENT 语义、集群去重方案与排错卡版本矩阵状态说明已验证说明未验证JMS 1.1 规范链接Oracle JCP 文档你文中已给出 URL用于概念对齐不代表实现可互通未验证JMS 2.0Shared Consumer / Shared Durable Consumer用于 Topic 下“组内竞争”语义文中未给出具体实现与配置示例未验证Jakarta Messaging 3.1API 级别概念延续 JMS 2.0需结合具体 ProviderActiveMQ/Artemis 等落地未验证ActiveMQ Virtual Topic依赖 ActiveMQ 的特性非 JMS 规范文中给出命名与思路未给出 broker 侧策略/版本与实测参数JMS模式续接上篇Java-198 RabbitMQ JMS 模式详解Queue/Topic、6 类消息与对象模型JMS 2.0 / Jakarta Messaging 3.1消息模式Java消息服务JMS应用程序支持两种主要的消息传递模式每种模式都有其特定的应用场景和优势点对点队列模式Point-to-Point简称P2P基本特征基于消息队列的一对一通信模式工作流程消息生产者将消息发送到特定队列消息消费者从队列中提取并处理消息每条消息只能被一个消费者接收典型应用场景订单处理系统如电商平台的订单队列异步任务处理如后台报表生成负载均衡场景多个消费者分担队列消息关键特性消息持久化支持消息确认机制消息优先级设置发布/订阅模式Publish/Subscribe简称Pub/Sub基本特征基于主题的一对多广播式通信工作流程消息发布者向特定主题发送消息所有订阅该主题的消费者都会收到消息副本支持持久订阅和非持久订阅两种方式典型应用场景实时通知系统如股票价格变动通知事件驱动架构如微服务间的事件传播日志广播系统关键特性主题的持久化支持消息过滤机制订阅者生命周期管理两种模式的主要区别消息传递方式P2P是定向传递Pub/Sub是广播传递消费者数量P2P每个消息只有一个消费者Pub/Sub可以有多个消费者耦合程度P2P生产者消费者需要知道队列名称Pub/Sub只需知道主题消息生命周期P2P消息被消费后即消失Pub/Sub消息与订阅者状态相关在实际应用中开发者可以根据业务需求选择合适的模式或者组合使用两种模式构建复杂的消息处理系统。点对点在消息队列系统中生产者Producer和消费者Consumer通过特定的队列Queue进行解耦的异步通信。以下是这个通信过程的详细说明1. 消息发布与消费机制定向发布生产者明确知道目标队列的名称或标识通过调用队列服务API如RabbitMQ的basic_publish或Kafka的producer.send直接将消息投递到指定队列。示例场景订单服务生产者将新订单消息发布到名为order_queue的队列物流服务消费者监听该队列获取订单信息。独占消费队列默认采用竞争消费模式即一条消息只会被一个活跃消费者实例获取。例如在RabbitMQ中多个消费者订阅同一队列时消息会通过轮询Round-Robin方式分配。2. 异步处理特性运行时解耦生产者发布消息后即可终止运行无需等待消费者处理。消息会持久化存储在队列中需配置持久化选项。消费者可以随时启动或停止离线期间的消息会保留在队列中需设置消息TTL避免堆积。典型应用电商系统的库存扣减操作库存服务可能因维护停机但订单服务仍可持续发送扣减消息到队列。3. 消息确认机制自动确认Auto-ACK消费者获取消息后消息队列服务自动标记为已处理如RabbitMQ的autoAcktrue。风险若消费者处理失败但消息已被确认会导致消息丢失。手动确认Manual-ACK消费者处理完成后显式发送确认指令如RabbitMQ的basic_ack。处理失败时可选择basic_nack拒绝并重新入队basic_reject直接丢弃最佳实践支付系统通常采用手动确认确保交易记录处理成功后才确认消息。4. 补充技术细节队列声明参数// RabbitMQ队列声明示例channel.queueDeclare(order_queue,true,// 持久化false,// 非独占队列false,// 不自动删除null// 额外参数);消息属性可设置delivery_mode2实现消息持久化通过correlation_id实现请求-响应模式5. 异常处理死信队列DLX当消息被拒绝且达到最大重试次数时可路由到专用异常队列配置方式通过x-dead-letter-exchange参数指定这种点对点通信模式适用于需要严格保证消息顺序、避免重复消费的场景如金融交易、工单处理等关键业务系统。发布订阅支持向一个特定的主题发布消息0或者多个订阅者可能对接收特定消息主题的消费感兴趣发布者和订阅者彼此不知道对方多个消费者可以获得消息在发布者和订阅者之间存在时间依赖性。发布者需要建立一个主题以便于客户可以订阅订阅者必须保持持续的活跃状态来接收消息否则会丢失未上线的消息对于持久订阅订阅者未连接时发布的消息将在订阅者重连时重发。传递方式JMSJava Message Service提供了两种消息传递方式它们在可靠性和性能方面有显著差异NON_PERSISTENT非持久性消息特点最多投递一次不保证消息一定能被接收实现机制消息直接发送给消费者不在中间存储应用场景实时股票行情推送丢失个别报价不影响整体在线游戏中的玩家位置更新社交媒体动态更新优势传输速度快系统开销小风险当服务中断时未传递的消息会永久丢失PERSISTENT持久性消息特点保证消息投递采用暂存-转送机制实现流程消息首先被持久化存储到磁盘或数据库服务确认接收后才会从存储中删除若服务中断消息会保留直到服务恢复典型应用银行交易处理订单支付确认重要系统日志性能影响需要额外的I/O操作可能降低吞吐量默认设置JMS默认使用NON_PERSISTENT模式可通过Message.setJMSDeliveryMode()方法显式设置持久性设置通常在生产者端指定存储考量非持久性消息通常只占用内存持久性消息需要磁盘存储空间大型系统可能需要专用消息存储服务器恢复机制持久性消息队列会记录消费进度服务重启后会从最后确认的位置继续投递支持事务的消息系统能确保原子性操作在实际架构设计中通常会混合使用两种模式根据业务重要性进行权衡。例如电商系统可能对支付消息使用持久性传递而对商品浏览记录使用非持久性传递。供应商开源的版本Apache ActiveMQRabbitMQRocketMQHornetQJoramMantaRayOpenJMS应用集群问题描述JSM在应用集群中的问题生产环境中应用基本上都是以集群的方式部署的在 Queue 模式下消息的消费没有什么问题因为不同节点的相同应用会抢占式的消费消息这样还可以分摊负载。但是如果使用 Topic 广播模式对于一个消息不同节点的相同应用都会收到该消息进行相应的操作此时就导致重复消费了。那我们该怎么办呢方案一选择Queue模式时常见的做法是创建多个相同的Queue队列每个消费者应用独立消费自己的Queue。这种架构设计虽然简单直接但也存在一些明显的弊端存储资源浪费问题每个Queue都需要独立存储所有消息当消息量较大时会占用多倍的存储空间例如如果发送1GB消息有3个消费者就需要3GB存储空间生产者负担加重生产者需要明确知道下游消费者的数量每增加一个消费者生产者就要多发送一份消息需要维护消费者列表并实时更新在微服务架构中这种耦合会带来维护困难扩展性问题新增消费者时需要修改生产者配置难以实现动态扩容例如在突发流量场景下无法快速增加临时消费者一致性维护成本需要确保所有Queue中的消息完全一致某个Queue处理失败时难以保证其他Queue的状态同步错误恢复机制复杂适用场景消费者数量固定且较少的情况消息处理要求完全隔离的环境对存储成本不敏感的场景替代方案建议考虑使用Pub/Sub模式实现一对多消息分发采用消息复制机制而非完全独立的Queue使用消息路由功能动态分发消息方案二选择 Topic 模式时通常会在业务层面采用散列Hash或分布式锁等机制来实现不同节点之间的任务竞争和负载均衡。这种方案的具体实现方式包括业务散列实现通过对消息键Message Key或业务ID进行哈希计算根据哈希结果将消息路由到特定的消费者节点例如订单ID % 消费者节点数 目标节点索引分布式锁方案使用Redis、Zookeeper等中间件实现分布式锁消费者在消费前需要先获取锁锁获取失败则放弃本次消费然而这些方案存在明显的弊端业务侵入性强需要在业务代码中显式处理路由逻辑系统复杂度高引入额外的组件如分布式锁服务可维护性差路由策略变更需要修改代码并重新部署扩展性受限增减消费者节点时需要调整哈希算法这些方案虽然能解决问题但从架构设计的角度来看它们破坏了消息中间件应有的解耦特性不是优雅的解决方案。更理想的方式应该是在消息中间件层面实现透明的负载均衡机制。虚拟主题ActiveMQ 的虚拟主题Virtual Topic机制巧妙地结合了 P2P 和 Pub/Sub 两种消息模式的优点为分布式系统中的消息消费提供了更灵活的解决方案。以下是其工作原理和典型应用场景的详细说明虚拟主题的核心机制生产者将消息发布到一个虚拟主题命名格式通常为VirtualTopic.XXXActiveMQ 会自动为每个消费者组创建一个对应的队列格式为Consumer.应用名.VirtualTopic.XXX同一消费者组内的多个实例以竞争方式消费P2P 模式不同消费者组的应用则各自获取全量消息Topic 模式实际应用场景示例订单处理系统支付服务集群3个实例共享消费Consumer.Payment.VirtualTopic.Orders物流服务集群2个实例共享消费Consumer.Shipping.VirtualTopic.Orders每个服务组都能获取完整订单消息但组内实例不会重复处理配置实现步骤!-- 生产者配置 --destinationnameVirtualTopic.Orderstypetopic/!-- 消费者配置示例 --destinationnameConsumer.Payment.VirtualTopic.Orderstypequeue/优势对比特性传统Topic传统Queue虚拟主题消息广播✓✗✓负载均衡✗✓✓避免重复消费✗✓✓性能优化建议对于高吞吐场景建议设置合理的 prefetch limit通常 50-100可以结合消息选择器Selector实现更精细的消息过滤监控各消费者组的积压情况及时调整消费者实例数量这种模式特别适合微服务架构中需要一次发布多方消费的场景既保证了消息的广播特性又实现了消费者组的负载均衡是 ActiveMQ 在实际生产环境中最有价值的功能之一。JMS规范文档https://download.oracle.com/otndocs/jcp/7195-jms-1.1-fr-spec-oth-JSpec/JMS是J2EE平台的标准消息传递API它可以在商业和开源实现中使用每个实现都包括一个JMS服务器一个JMS客户端以及用于管理消息传递系统的其他特定于实现的组件。JMS提供程序可以是消息传递服务的独立实现也可以非JMS消息传递系统的桥梁。JMS客户端API是标准化的因此JMS应用程序可以在供应商的实现之间一致但是底层消息传递实现未指定因此JMS实现之间没有互操作性除非存在桥接技术否则想要共享消息传递的Java应用程序必须全部使用相同的JMS实现。如果没有供应商特定的JMS客户端来启动互操作性则非Java应用程序将无法访问JMS。AMQP 0-9-1 是一种消息传递协议而不像JMS这样的API任何实现该协议的客户端都可以访问支持 AMQP 0-9-1 的代理。协议及的互操作性允许以任何编程语言编写且在任何操作系统上运行的AMQP 0-9-1 客户端都可以参与消息传递系统而不需要桥接不兼容的服务实现。错误速查症状根因定位修复方案Topic模式同一条业务在多台应用都执行Pub/Sub广播语义每个订阅者各得一份同一messageId/业务ID在不同实例日志同时出现Topic订阅数与实例数一致用Virtual Topic组内Queue抢占或JMS 2.0 Shared(Durable) Subscription最终仍保留业务幂等应用重启/网络闪断后出现“少消息”默认NON_PERSISTENT非持久订阅离线丢失查看DeliveryMode订阅类型是否durablebroker重启后队列/主题是否保留关键链路改PERSISTENTTopic用durable或shared durable必要时开启事务/手动ACKQueue模式仍出现重复处理处理失败触发redeliveryACK在业务完成前已确认/事务回滚检查redelivered标记/重投次数消费端异常栈DLQ是否增长ACK放在业务成功之后启用事务引入幂等键业务ID去重表/缓存与可观测重试策略消息堆积、延迟越来越大消费者吞吐不足prefetch/并发配置不匹配TTL未设导致无限堆积监控队列深度、消费速率、积压时间看消费者线程/CPUbroker指标扩容消费者实例调整并发与prefetch设置TTL DLQ拆分队列/按key分片DLQ持续增长、同类消息反复失败毒消息格式/版本不兼容/下游依赖异常导致达到最大重试统计DLQ中message type、异常码、发生时间对照发布版本增加消息schema兼容在消费端做降级/隔离对毒消息单独处理与告警避免影响主链路其他系列 AI篇持续更新中长期更新AI炼丹日志-29 - 字节跳动 DeerFlow 深度研究框斜体样式架 私有部署 测试上手 架构研究持续打造实用AI工具指南AI研究-132 Java 生态前沿 2025Spring、Quarkus、GraalVM、CRaC 与云原生落地 AI模块直达链接 Java篇持续更新中长期更新Java-196 消息队列选型RabbitMQ vs RocketMQ vs KafkaMyBatis 已完结Spring 已完结Nginx已完结Tomcat已完结分布式服务已完结Dubbo已完结MySQL已完结MongoDB已完结Neo4j已完结FastDFS 已完结OSS已完结GuavaCache已完结EVCache已完结RabbitMQ正在更新… 深入浅出助你打牢基础 Java模块直达链接 大数据板块已完成多项干货更新300篇包括 Hadoop、Hive、Kafka、Flink、ClickHouse、Elasticsearch 等二十余项核心组件覆盖离线实时数仓全栈大数据-278 Spark MLib - 基础介绍 机器学习算法 梯度提升树 GBDT案例 详解 大数据模块直达链接

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询