ActiveMQ发送ObjectMessage的一个问题

本文探讨了使用ActiveMQ发送序列化对象时遇到的消息重复问题。问题出现在特定代码分支中,当对象实例的一个变量未设置值时,接收到的消息数量异常增多。通过设置该变量的值,问题得以解决。

最近对公司实现分布服务,然后通过ActiveMQ发送消息,消息我是封装到一个实现了序列化的对象里面通过发送ObjectMessage来发送,在接收的时候发现虽然只发送了一个消息,但是在Listener的日志里面看到似乎消息被接收了N次,但是看发送端的Log,消息确实只发送了一次,而且另外一个代码分支发送同样的类的实例,却是正常的,后来看了一下,在出错的代码分支里面,类实例里面的一个变量没有设值,设置了值以后就好了。如下:

 

 

 

 

 

<think>首先,用户的问题是基于系统级指令和提供的引用内容。指令要求: - 所有行内数学表达式用 $...$ 格式。 - 独立公式用 $$...$$ 格式并单独成段。 - LaTeX语法正确。 - 使用中文回答。 - 生成相关问题。 - 回答中引用的段落末尾自然地添加引用标识,例如 [^1]。 - 用户可见层:回答结构清晰,帮助用户逐步解决问题,尽量保证回答真实可靠。 用户查询:"我想查找Java使用ActiveMQ进行消息发送的示例 请问Java使用ActiveMQ发送消息的示例" 用户引用了三个引用: - 引用[1]: 关于ActiveMQ的两种核心分发模式(P2P与Pub/Sub)。 - 引用[2]: 关于ActiveMQ的安全审计机制。 - 引用[3]: Java使用ActiveMQ的示例代码,具体是监听器(MessageListener)的实现。 用户说:"上述引用仅供参考,并不是用户真正的需求,请尽可能多的参考用户上一次的问题和你的回答。" 但在这个上下文中,没有先前的对话历史。系统提示说:"参考用户上一次的问题和你的回答",但这是第一条消息,所以可能没有先前的交互。我应该专注于当前查询。 核心需求:用户想要Java使用ActiveMQ发送消息的示例代码。引用[3]提供了监听器代码,但没有发送消息的代码。所以我需要提供发送消息的示例。 步骤: 1. **回答结构清晰,逐步解决问题**:我应该从基础开始介绍,然后提供代码示例。既然用户提到了引用[1]的分发模式,我应该简要提及,但重点在发送消息。 2. **提供代码示例**:引用[3]只有监听器代码。我需要补充发送消息的代码。使用Java和ActiveMQ,通常使用JMS(Java Message Service)。 - 发送消息的基本步骤: - 创建连接工厂。 - 创建连接和会话。 - 创建目的地(队列或主题)。 - 创建生产者。 - 发送消息。 - 关闭资源。 3. **参考引用**:引用[1]讨论了P2P和Pub/Sub模式。在发送消息时,我需要指定是发送到队列(P2P)还是主题(Pub/Sub)。用户没有指定,所以我应该涵盖基本队列发送,并简要提及模式。 4. **添加引用标识**:在回答中,如果引用了引用内容,添加 [^1], [^2], [^3]。例如,引用[1]是关于分发模式的,如果我提到模式,就添加引用。 5. **生成相关问题**:在回答后,添加 "§§相关问题§§" 部分,列出相关问题。 6. **语言**:使用中文。 7. **数学表达式**:用户查询中没有明显的数学内容,但指令说所有行内数学表达式用 $...$。可能不需要,除非涉及数学。在消息队列中,通常没有数学,所以可能不需要。 内容大纲: - **介绍**:简要解释ActiveMQ发送消息的重要性和基本概念。参考引用[1]的分发模式。 - **步骤说明**:逐步描述如何使用Java发送消息到ActiveMQ。 - **代码示例**:提供完整的Java代码示例,包括发送消息的部分。 - **解释**:解释代码的关键部分。 - **相关问题**:生成相关问题。 代码示例基于引用[3]的监听器,我需要添加发送者代码。 完整示例: - 发送者类:发送消息。 - 监听器类:接收消息(从引用[3])。 但用户只问发送示例,所以我聚焦发送部分。引用[3]提供了监听器,我可以提到它,但提供发送代码。 发送消息的Java代码示例: ```java import org.apache.activemq.ActiveMQConnectionFactory; import javax.jms.*; public class MessageSender { public static void main(String[] args) { // ActiveMQ connection URL String brokerUrl = "tcp://localhost:61616"; String queueName = "TEST.QUEUE"; ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(brokerUrl); Connection connection = null; Session session = null; MessageProducer producer = null; try { // Create connection connection = connectionFactory.createConnection(); connection.start(); // Create session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); // Create destination (queue) Destination destination = session.createQueue(queueName); // Create producer producer = session.createProducer(destination); // Create message TextMessage message = session.createTextMessage("Hello, ActiveMQ!"); // Send message producer.send(message); System.out.println("Sent message: " + message.getText()); } catch (JMSException e) { e.printStackTrace(); } finally { // Close resources try { if (producer != null) producer.close(); if (session != null) session.close(); if (connection != null) connection.close(); } catch (JMSException e) { e.printStackTrace(); } } } } ``` 在回答中,我需要结构化。 添加引用:引用[1]提到分发模式,所以我可以说在发送消息时可以选择队列或主题。 相关问题:例如,如何配置ActiveMQ,如何接收消息(参考引用[3]),安全机制(参考引用[2])。 最后,确保语言中文。 </think> ### Java使用ActiveMQ发送消息示例 在分布式系统中,ActiveMQ作为Java生态中广泛使用的消息中间件,通过JMS(Java Message Service)规范实现了高效的消息传递。用户查询重点在于发送消息的示例,我将基于引用内容提供清晰的步骤和代码。ActiveMQ支持两种核心分发模式(参考引用[1]): - **P2P模式(点对点)**:消息发送到队列(Queue),每个消息只被一个消费者接收。 - **Pub/Sub模式(发布/订阅)**:消息发送到主题(Topic),所有订阅的消费者都能接收消息。 发送消息的关键步骤包括创建连接、会话、目的地(队列或主题)、生产者,然后发送消息。下面使用队列(P2P模式)作为示例。 #### 步骤说明 1. **设置ActiveMQ连接**:创建连接工厂,指定ActiveMQ代理的URL(如默认的`tcp://localhost:61616`)。 2. **创建会话**:建立连接后,创建JMS会话,用于管理事务和消息确认。 3. **定义目的地**:选择发送到队列(Queue)或主题(Topic),本例使用队列。 4. **创建生产者**:基于目的地初始化消息生产者。 5. **发送消息**:创建文本消息(如`TextMessage`)并发送。 6. **资源清理**:关闭生产者、会话和连接以释放资源。 #### 完整代码示例 以下是Java发送消息到ActiveMQ队列的完整代码。需要依赖`activemq-client`库(可通过Maven或Gradle添加)。 ```java import org.apache.activemq.ActiveMQConnectionFactory; import javax.jms.*; public class ActiveMQSender { public static void main(String[] args) { // 1. 设置ActiveMQ连接参数 String brokerUrl = "tcp://localhost:61616"; // ActiveMQ默认URL String queueName = "TEST.QUEUE"; // 队列名称 Connection connection = null; Session session = null; MessageProducer producer = null; try { // 2. 创建连接工厂和连接 ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(brokerUrl); connection = connectionFactory.createConnection(); connection.start(); // 启动连接 // 3. 创建会话(非事务性,自动确认消息) session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); // 4. 创建目的地(队列) Destination destination = session.createQueue(queueName); // 5. 创建生产者 producer = session.createProducer(destination); // 6. 创建并发送消息 TextMessage message = session.createTextMessage("Hello, ActiveMQ! This is a test message."); producer.send(message); // 发送消息 System.out.println("消息发送成功: " + message.getText()); } catch (JMSException e) { e.printStackTrace(); } finally { // 7. 关闭资源 try { if (producer != null) producer.close(); if (session != null) session.close(); if (connection != null) connection.close(); } catch (JMSException e) { e.printStackTrace(); } } } } ``` #### 代码解释 - **连接工厂 (ConnectionFactory)**:使用`ActiveMQConnectionFactory`指定代理地址,支持多种协议(如TCP, SSL)。 - **会话 (Session)**:参数`false`表示非事务性会话,`Session.AUTO_ACKNOWLEDGE`确保消息自动确认(避免消息丢失)。 - **目的地 (Destination)**:`createQueue`用于P2P模式;若需Pub/Sub模式,改为`createTopic("TOPIC.NAME")`。 - **消息类型**:`TextMessage`适用于文本数据;其他类型如`BytesMessage`或`ObjectMessage`可通过类似方式发送。 - **错误处理**:使用`try-catch`捕获`JMSException`,确保资源关闭在`finally`块中。 #### 注意事项 - **依赖添加**:在Maven项目中,添加以下依赖到`pom.xml`: ```xml <dependency> <groupId>org.apache.activemq</groupId> <artifactId>activemq-client</artifactId> <version>5.16.6</version> <!-- 使用最新版本 --> </dependency> ``` - **运行前提**:确保ActiveMQ服务已启动(默认在`localhost:61616`)。消息发送后,可使用引用[3]提供的监听器代码接收消息。 - **模式选择**:P2P模式适合点对点通信,而Pub/Sub模式适合广播场景,选择取决于系统需求。ActiveMQ的模式对比详见引用[1]。 - **安全配置**:生产环境中,建议添加安全审计(如认证和加密),参考引用[2]的机制提升消息安全性。 如果您已有ActiveMQ运行,运行此代码将发送消息到指定队列。消费者端可使用类似引用[3]的监听器接收消息[^3]。
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值