activemq 配置细节使用(二)

消息的发送策略

  • 持久化消息
    默认情况下,生产者发送的消息是持久化的。消息发送到broker以后,producer会等待broker对这条消息的处理情况的反馈
    可以设置消息发送端发送持久化消息的异步方式
			// 持久化消息 异步发送(默认同步)
			connectionFactory.setUseAsyncSend(false);
			// 回执窗口大小设置, 消费端不可能一直发,缓冲区存不了
			connectionFactory.setProducerWindowSize(1024);
  • 非持久化消息
    非持久化消息模式下,默认就是异步发送过程,如果需要对非持久化消息的每次发送的消息都获得broker的回执的话
			// 非持久化消息 同步发送(默认异步)
			connectionFactory.setAlwaysSyncSend(true);
			...
			// 非持久化消息
			textMessage.setJMSDeliveryMode(DeliveryMode.NON_PERSISTENT);

consumer获取消息是pull/push

默认情况下,mq服务器(broker)采用异步方式向客户端主动推送消息(push)。也就是说broker在向某个消费者会话推送消息后,不会等待消费者响应消息,直到消费者处理完消息以后,主动向broker返回处理结果

协议更改

更改配置activemq.xml文件,添加

<transportConnector name="nio" uri="nio://0.0.0.0:55555?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>

代码即可用

ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("nio://176.16.0.135:55555");

ActiveMQ持久化存储

  • kahaDB
    默认的存储方式
  • AMQ 基于文件的存储方式
    写入速度很快,容易恢复。
    文件默认大小是32M
  • JDBC 基于数据库的存储
    具体实现:https://blog.csdn.net/dengjili/article/details/88410037
  • LevelDB
    5.8以后引入的持久化策略。通常用于集群配置

ActiveMQ的网络连接

用来配置broker与broker之间的通信连接

在这里插入图片描述

静态网络连接

修改activemq.xml,增加如下内容(每个主机都需要配置

主机192.168.1.103配置

		 <networkConnectors>
           <networkConnector uri="static:(tcp://192.168.1.103:61616,tcp://192.168.1.104:61616)"/>
        </networkConnectors>

主机192.168.1.104配置

		<networkConnectors>
            <networkConnector uri="static:(tcp://192.168.1.104:61616,tcp://192.168.1.103:61616)"/>
         </networkConnectors>
测试一,页面测试

测试:192.168.1.103
在这里插入图片描述

测试:192.168.1.104
在这里插入图片描述

测试二,代码测试

192.168.1.103 生产消息2个

生产者代码

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;

import org.apache.activemq.ActiveMQConnectionFactory;

public class JmsSender {
	public static void main(String[] args) {
		ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://192.168.1.103:61616");
		System.out.println(connectionFactory);
		Connection connection = null;
		try {
			// 创建连接
			connection = connectionFactory.createConnection();
			connection.start();
			
			// 创建会话
			Session session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);
			
			// 创建队列,第一次才创建,first-queue表示名称,destination表示目的地
			Destination destination = session.createQueue("first-queue");
			MessageProducer producer = session.createProducer(destination);
			
			TextMessage textMessage = session.createTextMessage();
			for (int i = 0; i < 1; i++) {
				textMessage.setText("这是我的消息: " + i);
				textMessage.setStringProperty("name", "张三");
				producer.send(textMessage);
			}
			
			
			session.commit();
			session.close();
		} catch (JMSException e) {
			e.printStackTrace();
		} finally {
			if (connection != null) {
				try {
					connection.close();
				} catch (JMSException e1) {
					e1.printStackTrace();
				}
			}
		}
	}
}

在这里插入图片描述

192.168.1.104 消费消息2个

当前192.168.1.104主机显示没有任务
在这里插入图片描述
消费者代码

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageConsumer;
import javax.jms.Session;
import javax.jms.TextMessage;

import org.apache.activemq.ActiveMQConnectionFactory;

public class JmsReceiver {
	public static void main(String[] args) {
		ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://192.168.1.104:61616");
		System.out.println(connectionFactory);
		Connection connection = null;
		try {
			// 创建连接
			connection = connectionFactory.createConnection();
			connection.start();
			
			// 创建会话
			Session session = connection.createSession(Boolean.TRUE, Session.CLIENT_ACKNOWLEDGE);
			
			// 创建队列,第一次才创建,first-queue表示名称,destination表示目的地
			Destination destination = session.createQueue("first-queue");
			MessageConsumer consumer = session.createConsumer(destination);
			
			for (int i = 0; i < 1; i++) {
				TextMessage message = (TextMessage) consumer.receive();
				String text = message.getText();
				String name = message.getStringProperty("name");
				
				System.out.println(text);
				System.out.println(name);
			}
			session.commit();
			session.close();
		} catch (JMSException e) {
			e.printStackTrace();
		} finally {
			if (connection != null) {
				try {
					connection.close();
				} catch (JMSException e1) {
					e1.printStackTrace();
				}
			}
		}
	}
}

  1. 先消费一个
    192.168.1.103上面已经没有任务了,任务转移了
    在这里插入图片描述

192.168.1.104上面还剩下一个任务
在这里插入图片描述

  1. 192.168.1.104继续消费

在这里插入图片描述
消费完成。

当192.168.1.104上面还有一个任务时候,192.168.1.103可以消费吗,答案是不可以,将出现丢失消息

丢失的消息

一些consumer连接到broker1、消费broker2上的消息。消息先被broker1从broker2消费掉,然后转发给这些consumers。假设,转发消息的时候broker1重启了,这些consumers发现brokers1连接失败,通过failover连接到broker2.但是因为有一部分没有消费的消息被broker2已经分发到broker1上去了,这些消息就好像消失了。除非有消费者重新连接到broker1上来消费

从5.6版本开始,在destinationPolicy上新增了一个选项replayWhenNoConsumers属性,这个属性可以用来解决当broker1上有需要转发的消息但是没有消费者时,把消息回流到它原始的broker。同时把enableAudit设置为false,为了防止消息回流后被当作重复消息而不被分发
通过如下配置,在activeMQ.xml中。 分别在两台服务器都配置。即可完成消息回流处理

修改activemq.xml下的<policyEntries>

<policyEntry queue=">" enableAudit="false">
    <networkBridgeFilterFactory>
        <conditionalNetworkBridgeFilterFactory replayWhenNoConsumers="true"/>
    </networkBridgeFilterFactory>
</policyEntry>

解决上面上一个问题
192.168.1.103 (显示了三条消费)
在这里插入图片描述
192.168.1.104 (显示了二条消费)
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值