1.什么是消息中间件?
客户端与服务器之间进行异步通讯的。发送者将消息发送给消息服务器,消息服务器将消感存放在若干队列中,在合适的时候再将消息转发给接收者。
2.为什么要用消息中间件?
在客户端与服务器进行通讯时.客户端调用后,必须等待服务对象完成处理返回结果才能继续执行。
主要解决高并发:生成者发送消息之后,消费者不用立即消费,缓存在队列中。
3.消息中间件的通讯方式?
○ Point-to-Point(P2P) --- 点对点通讯:一对一通讯,生产者生产消息,只能允许有一个消费者进行消费。
○ Publish/Subscribe(Pub/Sub)---发布订阅:一对多,允许有多个消费者。
4.什么是jms?
JMS,它是J2EE的13个规范之一,提供的是消息中间件的规范,是Java消息服务,客户端之间可以通过JMS服务进行异步的消息传输。
JMS包括以下基本构件:
连接工厂,是客户用来创建连接的对象,ActiveMQ提供的是ActiveMQConnectionFactory;
创建连接connection,然后启动;
创建会话session,是发送和接收消息的上下文,用于创建消息生产者,消息消费者,队列,消息;
创建回话的同时,传参指定是否开启事物,以及消息接受类型。生产者用来设置是否持久化,以及发送消息。
目的地destination,指定生产消息的目的地和消费消息的来源对象;
5.消息中间件windows环境下的安装?
下载mq软件:链接: https://pan.baidu.com/s/1V_FX9XZpycmKE_FSWvXeZQ 密码: 63mc
启动mq,默认端口为8161
相关内容解释
我们通过java创建了10个消息。
6.MQ生产者
package com.dudu.lizhen.activemqtest; import org.apache.activemq.ActiveMQConnectionFactory; import javax.jms.*; /** * activeMq 生产者 * Created by lizhen on 2018/4/3 0003. */ public class ActiveMQProdcer { public static void main(String[] args) throws JMSException { //获取MQ的连接工厂 ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory (ActiveMQConnectionFactory.DEFAULT_USER, ActiveMQConnectionFactory.DEFAULT_PASSWORD, "tcp://127.0.0.1:61616"); //创建连接 Connection connection = activeMQConnectionFactory.createConnection(); //启动连接 connection.start(); //创建回话工厂 Session session = connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE); //创建队列 Queue lizhen_queue = session.createQueue("lizhen_queue"); //创建生产者 MessageProducer producer = session.createProducer(lizhen_queue); //设置持久化,需要做持久化。 producer.setDeliveryMode(DeliveryMode.PERSISTENT); //设置是否持久化,我们在这先不持久化 // producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT); for (int i = 0; i < 10; i++) { sendMessage(session, producer, "我是生产者:" + i); } } public static void sendMessage(Session session, MessageProducer messageProducer, String i) throws JMSException { //创建消息 Message message = session.createTextMessage(i); //发送消息 messageProducer.send(message); } }
7.MQ消费者
package com.dudu.lizhen.activemqtest; import org.apache.activemq.ActiveMQConnectionFactory; import javax.jms.*; /** * ActiveMQ 消费者 * Created by lizhen on 2018/4/3 0003. */ public class ActiveMQConsumer { public static void main(String[] args) throws JMSException { //获取MQ的连接工厂 ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory (ActiveMQConnectionFactory.DEFAULT_USER, ActiveMQConnectionFactory.DEFAULT_PASSWORD, "tcp://127.0.0.1:61616"); //创建连接 Connection connection = activeMQConnectionFactory.createConnection(); //启动连接 connection.start(); //创建回话工厂 Session session = connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE); //创建队列 Queue lizhen_queue = session.createQueue("lizhen_queue"); //创建消费者 MessageConsumer consumer = session.createConsumer(lizhen_queue); //持续监听消息 while (true) { TextMessage textMessage = (TextMessage) consumer.receive(); String text = textMessage.getText(); if(null!=text){ System.out.println("获取到的消息为:" + text); }else{ break; } } } }
8.使用MQ的注意事项?
A消费者,接受消息之后调用第三方接口,接口暂时无法访问,或者数据库连接异常?
B消费者,接受消息之后,抛出类型转换异常的错误?
那种需要进行消息重试?
A需要重试(如果消费端抛出异常,默认自动重试),B不需要重试(因为代码的问题,需要重新发布版本才能解决问题,不要重试。),类似于A的异常,代码中如果出现这种错误,一定不要catch,要往外抛。B的话采用在catch中捕获异常,然后将异常存放在日志中+定时job健康检查+人工补偿。
9.SpringBoot整合ActiveMQ
这个就不在黏贴了,如果想看可以再GitHub去下载代码。 https://github.com/lizhen376751/springboot.git
10.JMS可靠消息
ActiveMQ消息签收分为以下几种。。
1.自动签收:发送之后,不管生产者活消费者有没有问题,都表示消息已经发送完成。
2.事物消息:
生产者完后发送消息后,必须提交给队列
消费者获取消息,如果消息没有提交事物,默认表示没有进行消费。---默认自动重试机制。
3.手动签收:消费者没有手动签收消息,表示没有进行消费。(开发中一般都会用这种)
11.消息中间件如何保证消息幂等性问题?
消费没有及时的手动签收,MQ自动重试机制,造成重复消费
使用全局id进行,进行消息区分,如果已经消费直接进行手动签收。以下这三种都可以作为全局id
//比如我们获取的消息内容是一个订单号,然后判断订单号
String text = textMessage.getText();
//获取全局id,主要解决MQ重试机制,避免重复消费的问题,判断缓存中的id是否相同
String jmsMessageID = textMessage.getJMSMessageID();
//获取消息的日期戳,每次消息的日期戳都不同
long jmsTimestamp = textMessage.getJMSTimestamp();