一、ActiveMQ
1、可发送的数据类型:String,Bytes,Map,Object,Stream
2、消息大小最好在1k左右
3、消息较大,建议用kafka或者其他非消息中间件方式
4、requst-response模式:用于一对一发送应答模式,生产者发送消息后,需要得到消费者的消费情况,类似于rpc,但属于 异步模式,实现原理为,定义两个queue,一个用于生产者发送消息,一个用于消费者消费后反馈给生产者情况,生产者 同时属于消费者,消费者同时属于生产者,如图:
5、activeMq创建队列不能超过1000个,超过后对性能影响很大。
6、嵌入式Mq服务如下(嵌入式提供的功能有限,只限于测试用),生产者和消费者只是常规写法就可以
public class EmbedMQ {
public static void main(String[] args) throws Exception {
BrokerService brokerService = new BrokerService();
brokerService.setBrokerName("EmbedMQ");
brokerService.addConnector("tcp://localhost:62000");
brokerService.setManagementContext(new ManagementContext());
brokerService.start();
}
}
7、消息的持久化:kahaDB(默认,文件形式),jdbc(需在activemq.xml上配置数据库连接)
topic模式:
生产者只把消息发送给当前在线的消费者,未在线收不到此时发送的消息,即使后续在线也不会收到不在线时 生产者发送的消息。如果需要消费者在离线又上线后,不管ActiveMQ是否重启过,都保证可以接受到消息,就需 要进行持久化订阅,持久化订阅模式的消费者需要添加connection.setClientID("aaa");以及messageConsumer = session.createDurableSubscriber(destination1, "ccc");
/*默认连接用户名*/
private static final String USERNAME
= ActiveMQConnection.DEFAULT_USER;
/* 默认连接密码*/
private static final String PASSWORD
= ActiveMQConnection.DEFAULT_PASSWORD;
/* 默认连接地址*/
private static final String BROKEURL
= ActiveMQConnection.DEFAULT_BROKER_URL;
public static void main(String[] args) {
/* 连接工厂*/
ConnectionFactory connectionFactory;
/* 连接*/
Connection connection = null;
/* 会话*/
Session session;
/* 消息的目的地*/
Destination destination;
/* 消息的消费者*/
MessageConsumer messageConsumer;
/* 实例化连接工厂*/
connectionFactory
= new ActiveMQConnectionFactory(USERNAME, PASSWORD, BROKEURL);
try {
/* 通过连接工厂获取连接*/
connection = connectionFactory.createConnection();
//持久化订阅设置
connection.setClientID("aaa");
/* 启动连接*/
connection.start();
/* 创建session*/
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
/* 创建一个名为HelloActiveMq1消息队列*/
Topic destination1 = session.createTopic("HelloActiveMq1");
//持久化订阅设置
messageConsumer = session.createDurableSubscriber(destination1, "ccc");
Message message;
while ((message = messageConsumer.receive()) != null) {
System.out.println(((TextMessage) message).getText());
}
} catch (JMSException e) {
e.printStackTrace();
} finally {
if (connection != null) {
try {
connection.close();
} catch (JMSException e) {
e.printStackTrace();
}
}
}
}
8、消息的可靠性
消息发送成功后,接收端接收到了消息。然后进行处理,但是可能由于某种原因,高并发也好,IO阻塞也好,反正这条消息在接收端处理失败了。而点对点的特性是一条消息,只会被一个接收端给接收,只要接收端A接收成功了,接收端B,就不可能接收到这条消息,如果是一些普通的消息还好,但是如果是一些很重要的消息,比如说用户的支付订单,用户的退款,这些与金钱相关的,是必须保证成功的,那么这个时候要怎么处理呢?必须要保证消息的可靠性,除了消息的持久化,还包括两个方面,一是生产者发送的消息可以被ActiveMQ收到,二是消费者收到了ActiveMQ发送的消息。
对于生产者:在生产者端,我们会使用send() 方法向ActiveMQ发送消息,默认情况下,持久化消息以同步方式发送,send() 方法会被阻塞,直到 broker 发送一个确认消息给生产者,这个确认消息表示broker已经成功接收到消息,并且持久化消息已经把消息保存到二级存储中。生产者在创建session时,可以设置开启事务:session = connection.createSession(true,Session.AUTO_ACKNOWLEDGE);第一个参数true是开启事务,开启事务后,当生产者发送消息调用send()方法时,消息不会发送到broker,直到生产者调用session.commit()后,消息才真正发送到broker.为保证消息可以被ActiveMQ收到,我们应该采用事务消息或持久化消息。
对于消费者:消费者对消息的确认有4中机制
AUTO_ACKNOWLEDGE(自动确认)、CLIENT_ACKNOWLEDGE(客户端手动确认)、 DUPS_OK_ACKNOWLEDGE(自动批量确认)、SESSION_TRANSACTED(事务提交并确认)
这四种机制(ack_mode)描述了Consumer与broker确认消息的方式(时机),比如当消息被Consumer接收之 后,Consumer将在何时确认消息。
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
第一个参数:是否支持事务,如果为true,则会忽略第二个参数,自动被jms服务器设置 为 SESSION_TRANSACTED。
AUTO_ACKNOWLEDGE(自动确认):
CLIENT_ACKNOWLEDGE(客户端确认) :
DUPS_OK_ACKNOWLEDGE(自动批量确认):
SESSION_TRANSACTED(事务提交并确认):