ActiveMQ
(1)消息中间件可以做什么:应用解耦,异步通讯,流量削峰
应用解耦:没有使用消息中间件之前是A应用要和B应用,C应用通讯,一般采用http接口方式,这时A和B,C是耦合的。采用消息中间件后,A,B,C只和消息中间件通讯,实现了应用之间的解耦
异步通讯:对于非主要业务的逻辑可以采用发送消息的方式
流量削峰:利用消息中间件的缓存作用,可以缓存一部分请求
(2)JMS
Java消息服务(Java Message Service)应用程序接口是一个Java平台中关于面向消息中间件(MOM)的API
消息队列模式:
①客户端包括生产者和消费者
②队列中的一个消息只能被一个消费者使用
③消费者可以随时取消息
发布订阅模式:
①客户端包括发布者和订阅者
②主题中的消息可以被所有订阅者消费
③消费者不能消费订阅之前发送的消息
(3)AMQP
Advanced Message Queuing Protocol,高级消息队列协议
(4)JMS和AMQP的区别
JMS是定义于Java,而AMQP是一种传输层协议。
JMS是属于Java的API,而AMQP是跨语言的。
JMS消息类型只有两种(主题和队列),而AMQP有五种。
(5) ActiveMQ消息签收机制:
客戶端成功接收一条消息的标志是一条消息被签收,成功应答。
消息的签收情形分两种:
1、带事务的session
如果session带有事务,并且事务成功提交,则消息被自动签收。如果事务回滚,则消息会被再次传送。
2、不带事务的session
不带事务的session的签收方式,取决于session的配置。
Activemq支持一下三種模式:
Session.AUTO_ACKNOWLEDGE 消息自动签收
Session.CLIENT_ACKNOWLEDGE 客戶端调用acknowledge方法手动签收
textMessage.acknowledge();//手动签收
Session.DUPS_OK_ACKNOWLEDGE 不是必须签收
(6)Activemq使用
引入依赖
<dependencies> <dependency> <groupId>org.apache.activemq</groupId> <artifactId>activemq-all</artifactId> <version>5.9.0</version> </dependency> </dependencies>
队列模式
package com.irish.queues; import javax.jms.Connection; import javax.jms.Destination; import javax.jms.JMSException; import javax.jms.Message; import javax.jms.MessageListener; import javax.jms.Session; import javax.jms.TextMessage; import org.apache.activemq.ActiveMQConnectionFactory; public class MessageConsumer { //定义ActivMQ的连接地址 private static final String ACTIVEMQ_URL = "tcp://127.0.0.1:61616"; //定义发送消息的队列名称 private static final String QUEUE_NAME = "MyMessage"; public static void main(String[] args) throws JMSException { //创建连接工厂 ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(ACTIVEMQ_URL); //创建连接 Connection connection = activeMQConnectionFactory.createConnection(); //打开连接 connection.start(); //创建会话 Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); //创建队列目标 Destination destination = session.createQueue(QUEUE_NAME); //创建消费者 javax.jms.MessageConsumer consumer = session.createConsumer(destination); //创建消费的监听 consumer.setMessageListener(new MessageListener() { @Override public void onMessage(Message message) { TextMessage textMessage = (TextMessage) message; try { System.out.println("获取消息:" + textMessage.getText()); } catch (JMSException e) { e.printStackTrace(); } } }); } }
package com.irish.queues; import javax.jms.Connection; import javax.jms.Destination; import javax.jms.JMSException; import javax.jms.Session; import javax.jms.TextMessage; import org.apache.activemq.ActiveMQConnectionFactory; public class MessageProducer { //定义ActivMQ的连接地址 private static final String ACTIVEMQ_URL = "tcp://127.0.0.1:61616"; //定义发送消息的队列名称 private static final String QUEUE_NAME = "MyMessage"; public static void main(String[] args) throws JMSException { //创建连接工厂 ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(ACTIVEMQ_URL); //创建连接 Connection connection = activeMQConnectionFactory.createConnection(); //打开连接 connection.start(); //创建会话 Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); //创建队列目标 Destination destination = session.createQueue(QUEUE_NAME); //创建一个生产者 javax.jms.MessageProducer producer = session.createProducer(destination); //创建模拟100个消息 for (int i = 1 ; i <= 100 ; i++){ TextMessage message = session.createTextMessage("我发送message:" + i); //发送消息 producer.send(message); //在本地打印消息 System.out.println("我现在发的消息是:" + message.getText()); } //关闭连接 connection.close(); } }
主题模式
package com.irish.topics; import javax.jms.Connection; import javax.jms.Destination; import javax.jms.JMSException; import javax.jms.Session; import javax.jms.TextMessage; import org.apache.activemq.ActiveMQConnectionFactory; public class MessageTopicProducer { //定义ActivMQ的连接地址 private static final String ACTIVEMQ_URL = "tcp://127.0.0.1:61616"; //定义发送消息的主题名称 private static final String TOPIC_NAME = "MyTopicMessage"; public static void main(String[] args) throws JMSException { //创建连接工厂 ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(ACTIVEMQ_URL); //创建连接 Connection connection = activeMQConnectionFactory.createConnection(); //打开连接 connection.start(); //创建会话 Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); //创建主题 Destination destination = session.createTopic(TOPIC_NAME); //创建一个生产者 javax.jms.MessageProducer producer = session.createProducer(destination); //创建模拟100个消息 for (int i = 1; i <= 100; i++) { TextMessage message = session.createTextMessage("当前message是(主题模型):" + i); //发送消息 producer.send(message); //在本地打印消息 System.out.println("我现在发的消息是:" + message.getText()); } //关闭连接 connection.close(); } }
package com.irish.topics; import javax.jms.Connection; import javax.jms.Destination; import javax.jms.JMSException; import javax.jms.Message; import javax.jms.MessageListener; import javax.jms.Session; import javax.jms.TextMessage; import org.apache.activemq.ActiveMQConnectionFactory; public class MessageTopicConsumer { //定义ActivMQ的连接地址 private static final String ACTIVEMQ_URL = "tcp://127.0.0.1:61616"; //定义发送消息的队列名称 private static final String TOPIC_NAME = "MyTopicMessage"; public static void main(String[] args) throws JMSException { //创建连接工厂 ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(ACTIVEMQ_URL); //创建连接 Connection connection = activeMQConnectionFactory.createConnection(); //打开连接 connection.start(); //创建会话 Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); //创建队列目标 Destination destination = session.createTopic(TOPIC_NAME); //创建消费者 javax.jms.MessageConsumer consumer = session.createConsumer(destination); //创建消费的监听 consumer.setMessageListener(new MessageListener() { @Override public void onMessage(Message message) { TextMessage textMessage = (TextMessage) message; try { System.out.println("获取消息:" + textMessage.getText()); } catch (JMSException e) { e.printStackTrace(); } } }); } }