目录
一 持久化
1.1 API设置
java默认是持久化的
1.2 Topic持久化
默认
情况下,topic发布时,如果订阅者不在线。消息就会丢失
但我们可以用持久化Topic来解决这个问题。
先启动订阅在启动生产
生产者
变化不多
package com.zyc.activemqdemo.consumer;
import org.apache.activemq.ActiveMQConnectionFactory;
import javax.jms.*;
/**
* @ClassName JmsProduce
* @Description TODO
* @Author DuanYueFeng
* @Version 1.0
**/
public class JmsProduce_Topic_p {
public static final String URL = "tcp://192.168.196.4:61616";
public static final String topic_name = "topic_p";
public static void main(String[] args) throws JMSException {
ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory(URL);
Connection connection = factory.createConnection();
Session session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
Topic topic = session.createTopic(topic_name);
MessageProducer producer = session.createProducer(topic);
producer.setDeliveryMode(DeliveryMode.PERSISTENT);
connection.start();//start放后面
for (int i = 1; i <=3; i++) {
TextMessage textMessage = session.createTextMessage("Topic mag..." + i);
producer.send(textMessage);
}
producer.close();
session.close();
connection.close();
System.out.println("完成....");
}
}
订阅者
package com.zyc.activemqdemo.consumer;
import org.apache.activemq.ActiveMQConnectionFactory;
import javax.jms.*;
import java.io.IOException;
/**
* @ClassName JmsConsumer
* @Description TODO
* @Author DuanYueFeng
* @Version 1.0
**/
public class JmsConsumer_Topic_p {
public static final String URL = "tcp://192.168.196.4:61616";
public static final String topic_name = "topic_p";
public static void main(String[] args) throws JMSException, IOException, InterruptedException {
System.out.println("我是3号消费者。。。");
ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory(URL);
Connection connection = factory.createConnection();
connection.setClientID("z3");//订阅者的客户端id
Session session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
Topic topic = session.createTopic(topic_name);
TopicSubscriber durableSubscriber = session.createDurableSubscriber(topic, "remark..");//后面是订阅者的名称
connection.start();//start也要延后
Message message = durableSubscriber.receive();
while (null!=message){
TextMessage textMessage = (TextMessage)message;
System.out.println("收到的持久化:"+textMessage.getText());
message = durableSubscriber.receive(1000L);
}
System.in.read();
// Thread.sleep(1000);
session.close();
connection.close();
System.out.println("完成....");
}
}
二 事务
事务偏生产者
2.1 生产者事务
事务的配置优先度高于应答模式(签收)
//第一个参数是是否创建session,第二个参数表示应答模式
Session session = connection.createSession(true,Session.AUTO_ACKNOWLEDGE);
不开启事务时
只要执行send就进入到队列中
开启事务后
需要在最后使用session.commit();
,某一条异常也可以用session.rollback();
2.2 消费者事务
不开启事务时
消息拿到就算作被消费了
开启事务时
没有commit
,消息就不会算作被消费。会有重复消费的
可能
三 签收
签收偏消费者
3.1 非事务模式
自动签收(默认)
Session.AUTO_ACKNOWLEDGE
手动签收
Session.CLIENT_ACKNOWLEDGE
客户端调用acknowledge
方法手动签收
允许重复消息
Session.DUPS_OK_ACKNOWLEDGE
消息可重复
确认,意思是此模式下,可能
会出现重复消息,并不是一条消息需要发送多次ACK才行。它是一种潜在的"AUTO_ACK"确认机制,为批量确认
而生,而且具有“延迟”确认
的特点。对于开发者而言,这种模式下的代码结构和AUTO_ACKNOWLEDGE
一样,不需要像CLIENT_ACKNOWLEDGE那样调用acknowledge()方法来确认消息。
3.2 事务模式下
消费者事务开启,只有
commit后才能将全部消息变为已消费,写ack没有作用
,即使写了签收也不会签收出队
3.3 和事务的联系
- 在事务性会话中,当一个事务被成功提交则消息被自动签收。如果事务
回滚
,则消息会被再次传送
- 非事务会话中,消息何时被确认取决于创建会话时的
应答模式(acknowledgement)
四 Broker
就是可以创建一个迷你
的mq服务器
4.1 是什么
4.2 不同的conf配置文件模拟不同的实例
原来并没有`后面的那一部分制定配置文件的命令
4.3 嵌入式Broker
依赖
启动
package com.atguigu.activemq.embed;
import org.apache.activemq.broker.BrokerService;
/**
* @ClassName EmbedBroker
* @Description TODO
* @Author DuanYueFeng
* @Version 1.0
**/
public class EmbedBroker {
public static void main(String[] args) throws Exception {
BrokerService brokerService = new BrokerService();
brokerService.setUseJmx(true);
brokerService.addConnector("tcp://localhost:61616");
brokerService.start();
}
}