ActiveMQ之JMS及保证消息的可靠性<持久化、事务、签收>(三)
1.JAVAEE 是一套使用Java 进行企业级开发的13 个核心规范工业标准 , 包括:
JDBC 数据库连接
JNDI Java的命名和目录接口
EJB Enterprise java bean
RMI 远程方法调用 一般使用TCP/IP 协议
Java IDL 接口定义语言
JSP
Servlet
XML
JMS Java 消息服务
JTA
JTS
JavaMail
JAF
JMS部件:

5 个主要的消息头:

发送和接收的消息类型必须一致
消息属性:识别、去重、重点标注
2. 如何保证消息的可靠性
JMS 可靠性:Persistent 持久性 、 事务 、 Acknowledge 签收
2.1 持久化
// 在队列为目的地的时候持久化消息
messageProducer.setDeliveryMode(DeliveryMode.PERSISTENT); // 队列为目的地的非持久化消息
messageProducer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
持久化的消息,服务器宕机后消息依旧存在,只是没有入队,当服务器再次启动,消息任就会被消费。
但是非持久化的消息,服务器宕机后消息永远丢失。 而当你没有注明是否是持久化还是非持久化时,默认是持久化的消息。
对于目的地为主题(topic)来说,默认就是非持久化的,让主题的订阅支持化的意义在于:对于订阅了公众号的人来说,当用户手机关机,在开机后任就可以接受到关注公众号之前发送的消息。
代码实现:持久化topic 的消费者
…… // 前面代码相同,不复制了
Topic topic = session.createTopic(TOPIC_NAME);
TopicSubscriber topicSubscriber = session.createDurableSubscriber(topic,"remark..."); // 5 发布订阅
connection.start(); Message message = topicSubscriber.receive();// 一直等
while (null != message){
TextMessage textMessage = (TextMessage)message;
System.out.println(" 收到的持久化 topic :"+textMessage.getText());
message = topicSubscriber.receive(3000L); // 等1秒后meesage 为空,跳出循环,控制台关闭
}
……
持久化生产者
……
MessageProducer messageProducer = session.createProducer(topic);
// 6 通过messageProducer 生产 3 条 消息发送到消息队列中
// 设置持久化topic 在启动
messageProducer.setDeliveryMode(DeliveryMode.PERSISTENT);
connection.start();
for (int i = 1; i < 4 ; i++) {
// 7 创建字消息
TextMessage textMessage = session.createTextMessage("topic_name--" + i);
// 8 通过messageProducer发布消息
messageProducer.send(textMessage);
MapMessage mapMessage = session.createMapMessage();
// mapMessage.setString("k1","v1");
// messageProducer.send(mapMessage);
}
// 9 关闭资源
……

当生产者启动后:

消息被消费,并且: (因为我在receive方法中设置了如果接收到消息后3秒还没有消息就离线,也也可以设置永久存活)

2.2 事务
createSession的第一个参数为true 为开启事务,开启事务之后必须在将消息提交,才可以在队列中看到消息
Session session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);
提交:
session.commit();
事务开启的意义在于,如果对于多条必须同批次传输的消息,可以使用事务,如果一条传输失败,可以将事务回滚,再次传输,保证数据的完整性。
对于消息消费者来说,开启事务的话,可以避免消息被多次消费,以及后台和服务器数据的不一致性。举个栗子:
如果消息消费的 createSession 设置为 ture ,但是没有 commit ,此时就会造成非常严重的后果,那就是在后台看来消息已经被消费,但是对于服务器来说并没有接收到消息被消费,此时就有可能被多次消费。
2.3 Acknowledge 签收 (俗称ack)
非事务 :
Session.AUTO_ACKNOWLEDGE 自动签收,默认 Session.CLIENT_ACKNOWLEDGE 手动签收
手动签收需要acknowledge
textMessage.acknowledge();
而对于开启事务时,设置手动签收和自动签收没有多大的意义,都默认自动签收,也就是说事务的优先级更高一些。
Session session = connection.createSession(true,Session.AUTO_ACKNOWLEDGE);
//Session session = connection.createSession(true,Session.CLIENT_ACKNOWLEDGE); // 也是自动签收 …… session.commit();
但是开启事务没有commit 任就会重复消费
小知识: broker
broker 就是实现了用代码形式启动 ActiveMQ 将 MQ 内嵌到 Java 代码中,可以随时启动,节省资源,提高了可靠性。
就是将 MQ 服务器作为了 Java 对象
使用多个配置文件启动 activemq
cp activemq.xml activemq02.xml // 以active02 启动mq 服务器
./activemq start xbean:file:/myactivemq/apache-activemq-5.15.9/conf/activemq02.xml
把小型 activemq 服务器嵌入到 java 代码: 不在使用linux 的服务器
需要的包:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.5</version>
</dependency>
代码实现:
/**
*Embebroker Demo
*2019-12-23 17:31:34
*/
public class Embebroker {
public static void main(String[] args) throws Exception {
// broker 服务
BrokerService brokerService = new BrokerService();
// 把小型 activemq 服务器嵌入到 java 代码
brokerService.setUseJmx(true);
// 原本的是 192.…… 是linux 上的服务器,而这里是本地windows 的小型mq 服务器
brokerService.addConnector("tcp://localhost:61616");
brokerService.start();
}
}
ActiveMQ之JMS及保证消息的可靠性<持久化、事务、签收>(三)的更多相关文章
- 《RabbitMQ》如何保证消息的可靠性
一条消费成功被消费经历了生产者->MQ->消费者,因此在这三个步骤中都有可能造成消息丢失. 一 消息生产者没有把消息成功发送到MQ 1.1 事务机制 AMQP协议提供了事务机制,在投递消息 ...
- 《即时消息技术剖析与实战》学习笔记4——IM系统如何保证消息的可靠性
IM 系统中,保证消息的可靠投递主要体现在两方面,一是消息的不丢失,二是消息的不重复. 一.消息不丢失 消息丢失的原因 首先看一下发送消息的流程,如下图所示: 消息.可以采取"时间戳比对&q ...
- activemq的高级特性:消息的可靠性
高级特性之消息的可靠性 可靠性分为:生产者.消费者.生产者必须让mq收到消息,消费者必须能够接收到消息并且消费成功,这就是消息的可靠性. 1:生产者可靠性 Session session = conn ...
- 基于Tomcat + JNDI + ActiveMQ实现JMS的点对点消息传送
前言 写了一个简单的JMS例子,之所以使用JNDI 是出于通用性考虑,该例子使用JMS规范提供的通用接口,没有使用具体JMS提供者的接口,这样可以保证我们编写的程序适用于任何一种JMS实现(Activ ...
- Kafka如何保证消息的可靠性传输
1.消费端弄丢了数据 唯一可能导致消费者弄丢数据的情况,就是说,你消费到了这个消息,然后消费者那边自动提交了 offset,让 Kafka 以为你已经消费好了这个消息,但其实你才刚准备处理这个消息,你 ...
- 解决RabbitMQ消息丢失问题和保证消息可靠性(一)
原文链接(作者一个人):https://juejin.im/post/5d468591f265da03b810427e 工作中经常用到消息中间件来解决系统间的解耦问题或者高并发消峰问题,但是消息的可靠 ...
- RabbitMQ高级之如何保证消息可靠性?
人生终将是场单人旅途,孤独之前是迷茫,孤独过后是成长. 楔子 本篇是消息队列RabbitMQ的第四弹. RabbitMQ我已经写了三篇了,基础的收发消息和基础的概念我都已经写了,学任何东西都是这样,先 ...
- JMS发布/订阅消息传送例子
前言 基于上篇文章"基于Tomcat + JNDI + ActiveMQ实现JMS的点对点消息传送"很容易就可以编写一个发布/订阅消息传送例子,相关环境准备与该篇文章基本类似,主要 ...
- 高可用保证消息绝对顺序消费的BROKER设计方案
转自: http://www.infoq.com/cn/articles/high-availability-broker-design?utm_source=tuicool&utm_medi ...
随机推荐
- SpringBoot(二)启动原理
SpringBoot自动配置模块 该配置模块的主要使用到了SpringFactoriesLoader,即Spring工厂加载器,该对象提供了loadFactoryNames方法,入参为factoryC ...
- swagger 爬坑记
Swagger 的好处不用我多说,但是一不小心可能就被坑……今天下午就被上了一课,废话不多说,直接上代码(图) 实体类: 好像没啥问题,对吧? 但是,在http://localhost:8080/sw ...
- ora00972标识符过长
oracle10G对于表名的长度限制是30个字节 表名超过30结果不能创建,提示ora00972-标识符过长. 需要将表名控制在30个字节以内
- 在VMware Workstation10下CentOS7虚拟机中创建与主机共享文件夹的详细步骤
一.前言 在使用虚拟机时,常常需要与宿主计算机(以下简称为主机)操作系统交换文件,为此需要在虚拟机与主机之间建立共享文件夹. 二. 安装VMTools 要使用共享文件机制,必须首先安装VMTools. ...
- python笔记007-函数
昨日简要: 1.文件操作: 1.1获得句柄: f = open(‘one.txt’,mode=’’,encoding=’utf-8’) f = open(‘../’) à返回上一层 f = open( ...
- 关于mq的思考
解耦场景 spark 发告警,同过kafka来解耦 削峰场景 日志采集生产环境几百台,当后续数量持续增加时,如果不加消息队列或者内存队列,可能把数据库打死 一个中间件: 为什么用 ->解决什么问 ...
- @Adaptive注解
关于@Adaptive注解 引用dubbo官方文档的一段话: Adaptive 可注解在类或方法上.当 Adaptive 注解在类上时,Dubbo 不会为该类生成代理类.注解在方法(接口方法)上时 ...
- (三)CXF之处理输入参数与输出类型为复杂类型的webService服务
一.需求 调用webService服务,把用户名和密码封装为用户对象作为参数,返回该用户所用友的角色列表. 二.发布服务 2.1 编写服务接口 @WebService public interface ...
- C#四种深拷贝方法(转载)
原文地址:https://www.cnblogs.com/profession/p/6222489.html //四种深拷贝方法 public static T DeepCopyByReflect&l ...
- Post请求数据传到后台+号变成了空格
问题: 今天遇到一个问题:页面带有"+"号的数据,传到服务端接口,结果+号变成了空格.例如:传“1+1”变成了"1 1". 解决办法: 方案一: 将“+”号替换 ...