声明:部分内容来自于互联网 不完全原创 但都经过本人实测
简介
ActiveMQ是JMS的实现
目的:为了系统与系统之间的解耦和通信
消息形式:
1、点对点 生产者--消费者 队列模式 Queue
2、发布/订阅 生产者---多个消费者 广播模式 Topic
两种模式的区别
Queue:消息发出后缓存再服务器端 有客户端上线 即可读取
Topic:消息发布时 不在线的服务端将不会接收到消息 即不会缓存再服务端
安装ActiveMQ
1、上传gz包 或者 wget
2、解压
3、开启ActiveMQ服务 ActiveMQ/bin/activemq start
jetty默认端口 8161
服务默认端口 61616
管理面板默认密码 admin admin
ActiveMQ下载地址
http://activemq.apache.org/download-archives.html
注意:服务器机器名有下划线 ActiveMQ是启动不了的
需要修改/activeMQ/conf/activemq.xml 把0.0.0.0改为127.0.0.1
把61616端口的改成0.0.0.0 否则外网连接不了
再修改jetty.xml中的host为外网ip
ActiveMQ 依赖JDK版本(非常重要,JDK对应不上 、高版本编译,低版本JDK上是运行不了的)
MQ版本号 | Build-Jdk | 依赖JDK |
apache-activemq-5.0.0 | 1.5.0_12 | 1.5+ |
apache-activemq-5.1.0 | 1.5.0_12 | 1.5+ |
apache-activemq-5.2.0 | 1.5.0_15 | 1.5+ |
apache-activemq-5.3.0 | 1.5.0_17 | 1.5+ |
apache-activemq-5.4.0 | 1.5.0_19 | 1.5+ |
apache-activemq-5.5.0 | 1.6.0_23 | 1.6+ |
apache-activemq-5.6.0 | 1.6.0_26 | 1.6+ |
apache-activemq-5.7.0 | 1.6.0_33 | 1.6+ |
apache-activemq-5.8.0 | 1.6.0_37 | 1.6+ |
apache-activemq-5.9.0 | 1.6.0_51 | 1.6+ |
apache-activemq-5.10.0 | 1.7.0_12-ea | 1.7+ |
apache-activemq-5.11.0 | 1.7.0_60 | 1.7+ |
apache-activemq-5.12.0 | 1.7.0_80 | 1.7+ |
apache-activemq-5.13.0 | 1.7.0_80 | 1.7+ |
apache-activemq-5.14.0 | 1.7.0_80 | 1.7+ |
apache-activemq-5.15.0 | 1.8.0_112 | 1.8+ |
如何查看官方发布ActiveMQ依赖JDK版本
以版本 apache-activemq-5.15.0 为例
方法1:查看 release-note
ActiveMQ 5.15.0 Release Java 8 Required The minimum Java version has been upgraded to Java 8.
方法2:查看文件 activemq-all-*.jar\META-INF\MANIFEST.MF 属性值 Build-Jdk
Manifest-Version: 1.0 Implementation-Title: ActiveMQ :: All JAR bundle Implementation-Version: 5.15.0 Archiver-Version: Plexus Archiver Built-By: cshannon Specification-Vendor: The Apache Software Foundation Specification-Title: ActiveMQ :: All JAR bundle Implementation-Vendor-Id: org.apache.activemq Implementation-Vendor: The Apache Software Foundation Main-Class: org.apache.activemq.console.command.ShellCommand Created-By: Apache Maven 3.5.0 Build-Jdk: 1.8.0_112 Specification-Version: 5.15.0
示例Java手动连接ActiveMQ
先导入activemq相关依赖包 用maven仓库的 不要用安装包中的activemq.jar!!!
// QUeue模式
@Test
public void testQueue() throws Exception {
// 1 创建连接工厂对象
ConnectionFactory factory = new ActiveMQConnectionFactory("tcp://192.168.25.133:61616");
// 2 使用工厂创建连接
Connection connection = factory.createConnection();
// 3 开启连接
connection.start();
// 4 用连接获取一个Session 第一个参数 是是否使用分布式缓存 一般不用 保证事务最终一致,使用ActiveMQ可以实现
// 第二个参数是应答模式 一般设置自动应答 如果第一个参数为true 第二个参数可以忽略
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
// 5 使用session对象创建一个Destination 这个有两种形式 就是queue和topic
Queue queue = session.createQueue("test1"); // 消息的名称
// 6 使用session创建一个Producer对象
MessageProducer producer = session.createProducer(queue);
// 7 创建TextMessage对象和消息体
TextMessage message = session.createTextMessage("nihao queue");
// 8 发送消息
producer.send(message);
// 9 关闭资源
session.close();
producer.close();
connection.close();
}
// 接收Queue消息 Consumer
@Test
public void reciveQueue() throws Exception {
// 创建一个工厂
ConnectionFactory factory = new ActiveMQConnectionFactory("tcp://192.168.25.133:61616");
// 从工厂获取connection
Connection connection = factory.createConnection();
// 开启连接
connection.start();
// 创建一个session对象
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
// 使用session创建一个Destination
Queue queue = session.createQueue("test1"); // 指定监听的消息名称
// 使用session创建一个Consumer
MessageConsumer consumer = session.createConsumer(queue);
// 给consumer添加监听
consumer.setMessageListener(new MessageListener() {
@Override
public void onMessage(Message arg0) {
// TODO Auto-generated method stub
// 如果此消息是TextMessage类型 直接强转
if (arg0 instanceof TextMessage) {
TextMessage msg = (TextMessage) arg0;
try {
String text = msg.getText();
System.out.println(text);
} catch (JMSException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
});
// 让其一直监听 不停止程序
System.in.read();
// 关闭连接
consumer.close();
session.close();
connection.close();
}
整合Spring
我这里示例的是XML方式 现在都是springboot+注解+配置的方式 一切都简化了 下面这种方式只是了解整合spring的过程 其实springboot在初始化JMS以及后续注解上都是下面这些流程。
发送方
<!-- 创建Activemq的工厂类 -->
<bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<constructor-arg name="brokerURL" value="tcp://192.168.25.133:61616"></constructor-arg>
</bean>
<!-- 使用Spring引用(这是真正的工厂) -->
<bean id="connectionFactory"
class="org.springframework.jms.connection.SingleConnectionFactory">
<property name="targetConnectionFactory" ref="targetConnectionFactory"></property>
</bean>
<!-- 创建JMSTEMplate -->
<bean id="jmsTemplete" class="org.springframework.jms.core.JmsTemplate">
<constructor-arg name="connectionFactory" ref="connectionFactory"></constructor-arg>
</bean>
<!-- 创建Destination目标 指定队列名称 -->
<bean id="queue" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg name="name" value="test-queue"></constructor-arg>
</bean>
<bean id="itemadd-topic" class="org.apache.activemq.command.ActiveMQTopic">
<constructor-arg name="name" value="itemadd-topic"></constructor-arg>
</bean>
==================
// 注入一个JMStemplate发送消息
@Autowired
private JmsTemplate jmsTemplete;
// 根据id注入一个Destination 由于这里有两个一样的类型的Destination 所以使用名称注入
@Resource(name = "itemadd-topic")
private Destination topic;
// 添加成功 使用ActiveMQ发送消息到服务器
jmsTemplete.send(topic, new MessageCreator() {
@Override
public Message createMessage(Session session) throws JMSException {
// TODO Auto-generated method stub
TextMessage message = session.createTextMessage(itemId + "");
return message;
}
});
=====================================================================================
接收方
<!-- 创建Activemq的工厂类 -->
<bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<constructor-arg name="brokerURL" value="tcp://192.168.25.133:61616"></constructor-arg>
</bean>
<!-- 使用Spring引用(这是真正的工厂) -->
<bean id="connectionFactory"
class="org.springframework.jms.connection.SingleConnectionFactory">
<property name="targetConnectionFactory" ref="targetConnectionFactory"></property>
</bean>
<!-- 创建Destination目标 指定队列名称 -->
<bean id="test-queue" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg name="name" value="test-queue"></constructor-arg>
</bean>
<bean id="itemadd-topic" class="org.apache.activemq.command.ActiveMQTopic">
<constructor-arg name="name" value="itemadd-topic"></constructor-arg>
</bean>
<!-- 配置消息接收 -->
<!-- <bean id="messageListener" class="com.taotao.search.mqlistener.MessageListener"></bean> -->
<!-- 处理消息的Listenter -->
<bean id="itemAddMessageListener" class="com.taotao.search.mqlistener.ItemAddMessageListener"></bean>
<bean
class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactory"></property>
<property name="destination" ref="itemadd-topic"></property>
<property name="messageListener" ref="itemAddMessageListener"></property>
</bean>
接收到信息的业务逻辑写在Listener内