1.Activemq安装
直接到官网下载:记住apache的官网是域名反过来,比如我们找activemq就是activemq.apache.org。
最新版本要求最低的JDK是8,所以最好在电脑装多个版本的JDK,用的时候切换就 可以了。
下载完成是个压缩包,解压目录如下:
1.启动:%activemq%\apache-activemq-5.15.6\bin\win64\activemq.bat启动即可,日志如下:(可以看出是集成就wrapper)
访问:http://localhost:8161/进行测试:
点击上面圈住的地方进入管理界面:(activemq的默认账号和密码都是admin)
补充:
1.activemq内置jetty服务器,后台管理端口在conf\jetty.xml中进行配置;,默认是8161:
2.接收消息的端口在conf\activemq.xml),默认是61616--而且只有openwire有用,其他可以注释掉
2.我们肯定不可能一直开在窗口,所以需要注册为服务:
以管理员方式运行: %activemq%\apache-activemq-5.15.6\bin\win64\InstallService.bat
查看源码发现是以wrapper的方式注册为服务。
2.入门程序
我将上一篇的JMS编程图放在这里便于理解:
依赖的jar包:activemq-all-5.15.6.jar下载的zip包里面带的有
1.队列模型---生产消息的程序:
package cn.qlq.activemq; import javax.jms.Connection; import javax.jms.ConnectionFactory; import javax.jms.JMSException; import javax.jms.MessageProducer; import javax.jms.Queue; import javax.jms.Session; import javax.jms.TextMessage; import org.apache.activemq.ActiveMQConnectionFactory; /** * 生产消息 * * @author QiaoLiQiang * @time 2018年9月18日下午11:04:41 */ public class MsgProducer { // 默认端口61616 private static final String url = "tcp://localhost:61616/"; private static final String queueName = "myQueue"; public static void main(String[] args) throws JMSException { // 1创建ConnectionFactory ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(url); // 2.由connectionFactory创建connection Connection connection = connectionFactory.createConnection(); // 3.启动connection connection.start(); // 4.创建Session===第一个参数是是否事务管理,第二个参数是应答模式 Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); // 5.创建Destination(Queue继承Queue) Queue destination = session.createQueue(queueName); // 6.创建生产者producer MessageProducer producer = session.createProducer(destination); for (int i = 0; i < 100; i++) { // 7.创建Message,有好多类型,这里用最简单的TextMessage TextMessage tms = session.createTextMessage("textMessage:" + i); // 8.生产者发送消息 producer.send(tms); System.out.println("send:" + tms.getText()); } // 9.关闭connection connection.close(); } }
结果:
.....
send:textMessage:93
send:textMessage:94
send:textMessage:95
send:textMessage:96
send:textMessage:97
send:textMessage:98
send:textMessage:99
到activemq的管理界面查看:
2.队列模型---消费者代码:
package cn.qlq.activemq; import javax.jms.Connection; import javax.jms.ConnectionFactory; import javax.jms.JMSException; import javax.jms.Message; import javax.jms.MessageConsumer; import javax.jms.MessageListener; import javax.jms.Queue; import javax.jms.Session; import javax.jms.TextMessage; import org.apache.activemq.ActiveMQConnectionFactory; /** * 消费消息 * * @author QiaoLiQiang * @time 2018年9月18日下午11:26:41 */ public class MsgConsumer { // 默认端口61616 private static final String url = "tcp://localhost:61616/"; private static final String queueName = "myQueue"; public static void main(String[] args) throws JMSException { // 1创建ConnectionFactory ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(url); // 2.由connectionFactory创建connection Connection connection = connectionFactory.createConnection(); // 3.启动connection connection.start(); // 4.创建Session===第一个参数是是否事务管理,第二个参数是应答模式 Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); // 5.创建Destination(Queue继承Queue) Queue destination = session.createQueue(queueName); // 6.创建消费者consumer MessageConsumer consumer = session.createConsumer(destination); // 7.给消费者绑定监听器(消息的监听是一个异步的过程,不可以关闭连接,绑定监听器线程是一直开启的,处于阻塞状态,所以可以在程序退出关闭) consumer.setMessageListener(new MessageListener() { @Override public void onMessage(Message message) { // 7.1由于消费者接受的是TextMessage,所以强转一下 TextMessage tms = (TextMessage) message; try { System.out.println("接收消息:" + tms.getText()); } catch (JMSException e) { e.printStackTrace(); } } }); } }
启动结果:(接受完线程并不关闭,所以是异步接收,线程处于阻塞状态。)
再开一个消费者:再运行一次消费者程序。
后台管理查看:(两个消费者)
在启动生产者生产一百条消息之后查看消费者:(切记切换控制台按钮查看消费信息):两个消费者平均消费信息,满足上一篇介绍的队列模型
第一个消费者:
第二个消费者:
3.主题模型---生产消息的程序:
与队列模式一样,只是Destination是Topic。
package cn.qlq.activemq.topic; import javax.jms.Connection; import javax.jms.ConnectionFactory; import javax.jms.Destination; import javax.jms.JMSException; import javax.jms.MessageProducer; import javax.jms.Session; import javax.jms.TextMessage; import org.apache.activemq.ActiveMQConnectionFactory; /** * 主题模式的消息生产者 * * @author QiaoLiQiang * @time 2018年9月19日下午10:10:36 */ public class MsgProducer { // 默认端口61616 private static final String url = "tcp://localhost:61616/"; private static final String topicName = "myTopic"; public static void main(String[] args) throws JMSException { // 1创建ConnectionFactory ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(url); // 2.由connectionFactory创建connection Connection connection = connectionFactory.createConnection(); // 3.启动connection connection.start(); // 4.创建Session===第一个参数是是否事务管理,第二个参数是应答模式 Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); // 5.创建Destination(Queue继承Queue,Topic也继承Destination==这三个都是接口) Destination destination = session.createTopic(topicName); // 6.创建生产者producer MessageProducer producer = session.createProducer(destination); for (int i = 0; i < 100; i++) { // 7.创建Message,有好多类型,这里用最简单的TextMessage TextMessage tms = session.createTextMessage("textMessage:" + i); // 8.生产者发送消息 producer.send(tms); System.out.println("send:" + tms.getText()); } // 9.关闭connection connection.close(); } }
4.主题模式---消息消费者:
与队列模式一样,只是Destination是Topic。
package cn.qlq.activemq.topic; import javax.jms.Connection; import javax.jms.ConnectionFactory; import javax.jms.Destination; import javax.jms.JMSException; import javax.jms.Message; import javax.jms.MessageConsumer; import javax.jms.MessageListener; import javax.jms.Session; import javax.jms.TextMessage; import org.apache.activemq.ActiveMQConnectionFactory; /** * 主题模式的消费消息 * * @author QiaoLiQiang * @time 2018年9月18日下午11:26:41 */ public class MsgConsumer { // 默认端口61616 private static final String url = "tcp://localhost:61616/"; private static final String topicName = "myTopic"; public static void main(String[] args) throws JMSException { // 1创建ConnectionFactory ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(url); // 2.由connectionFactory创建connection Connection connection = connectionFactory.createConnection(); // 3.启动connection connection.start(); // 4.创建Session===第一个参数是是否事务管理,第二个参数是应答模式 Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); // 5.创建Destination(Queue继承Queue,Topic也继承Destination==这三个都是接口) Destination destination = session.createTopic(topicName); // 6.创建消费者consumer MessageConsumer consumer = session.createConsumer(destination); // 7.给消费者绑定监听器(消息的监听是一个异步的过程,不可以关闭连接,绑定监听器线程是一直开启的,处于阻塞状态,所以可以在程序退出关闭) consumer.setMessageListener(new MessageListener() { @Override public void onMessage(Message message) { // 7.1由于消费者接受的是TextMessage,所以强转一下 TextMessage tms = (TextMessage) message; try { System.out.println("接收消息:" + tms.getText()); } catch (JMSException e) { e.printStackTrace(); } } }); } }
测试:
先启动生产者生成100条消息:
启动两个消费者,不会消费消息,满足消费者不能消费订阅之前就发送到主题中的消息:
再启动生产者发布100条消息,查看后台管理界面和消费者控制台信息:
两个消费者控制台一样:(满足主题中的消息被所有订阅者消费)