一、ActiveMQ简介、安装
MQ英文名MessageQueue,中文名即消息队列,干嘛用的呢,说白了就是一个消息的接受和转发的容器,可用于消息推送。
ActiveMQ是由Apache出品的,一款流行的,能力强劲的开源消息中间件。
二、什么情况下使用ActiveMQ?
1.多个项目之间集成
(1) 跨平台
(2) 多语言
(3) 多项目
2.降低系统间模块的耦合度,解耦
软件扩展性
3.系统前后端隔离
前后端隔离,屏蔽高安全区
三、安装
1.jdk
2.解压
从webapps可以看出他自带容器,无需关联tomcat、jetty等。
3.启动
cd ${activemq}/bin
日志打印至控制台:./activemq console
静默启动:./activemq start | status |stop |restart
访问控制台:http://ip:8161/admin 用户名密码:admin/admin
四、ActiveMQ发送、接收消息
1.两种模式
1.1 点对点
大家接收到的消息都不一样,是瓜分的,瓜分消息队列中的数据,也就是,所有消费端合起来的消费的消息集合,就是消息队列中生产者所发布的所有消息。
如果我们下订单,肯定是点对点模式,正常的,我们的消费端有多个,一个订单被一个消费端消费就可以了,然后正常保存到数据库中。
1.2发布者/订阅者
大家接收到的消息是一样的,共享队列中的数据。
比如领导发送10封邮件给3个人,这三个人肯定是共享这10封邮件,使用点对点瓜分这10封邮件显然不合理,所以用发布者/订阅者模式。
2.实现
依赖
<dependency> <groupId>org.apache.activemq</groupId> <artifactId>activemq-all</artifactId> <version>5.14.5</version> </dependency> |
2.1 点对点
如何实现点对点模式?
首先我们使用的是Maven项目,在项目的POM.xml添加ActiveMQ的依赖,依赖来自Maven的万能网站mvnresitory.com。5.14.5,哪个下载得多,就选哪个。
添加好依赖后,服务发布的时候,创建相应的连接工厂类。
默认我们去连接是不需要用户名和密码的,可以写成null。
连接的url默认是,其中IP是MQ所在服务器的IP。端口号是看源码得来的,不过配置文件中可以改。
然后用工厂类创建连接对象
连接对象启动连接
和我们的服务器交互会有会话的概念,比如我们的MyBatis和数据库交互有会话的概念。
创建会话对象
第一个参数为true,参数2给个null,或者其他的随便,因为不生效。
假设为false,第二个参数有4个取值。
分别是
:自动提交,我们什么都不管。
:表示由我的客户端来确定,什么时候我们的事务进行提交。比如我们去删除消息,因为消息不能一直存在,得到之后,我们要去删除,删除就可以通过配置这个参数来做。
:支持副本模式,我们支持多个副本,多个客户端来进行确认。
:交给SqlSession对象来管理咱们的事务。
消息发送到哪?通过session创建目的地,比如说咱们要发送的MQ的名称标识,咱们称之为mq-test-01。就是一个字符串,怎么制定都可以。(创建一个消息队列,指定他的名称标识)
发送的消息内容是什么?比如发送一个文本消息。
创建消息对象
通过消息对象指定内容
创建发送者
发送消息
发送完成之后,提交会话(上面创建会话对象时,第一个参数为true,则不用写,因为自动提交)
然后关闭连接
如果是10个发送者,每个发一条消息,共发送十条消息呢?(留下一个思考,如何发送对象)
那么如何接受消息?
接受者前面五步和发送者一样,目的地都一样。
创建接受消息对象,如果目的地写错了,就接受不到消息
通过监听器接受消息
创建多个接受者,看消息是否是瓜分的。
复制粘贴接受者就行。
Producer.java
public class Producer {
private static final String userName = ActiveMQXAConnectionFactory.DEFAULT_USER; private static final String password = ActiveMQXAConnectionFactory.DEFAULT_PASSWORD; private static final String brokerURL = "tcp://192.168.129.10:61616";
public static void main(String[] args) throws JMSException { //1.创建连接工厂类 ConnectionFactory factory = new ActiveMQXAConnectionFactory(userName, password, brokerURL); //2.创建连接 Connection connection = factory.createConnection(); //3.启动连接 connection.start();
//4.创建会话对象session(事务transacted为true,参数2不生效) //acknowledgeMode: Session session = connection.createSession(true,Session.AUTO_ACKNOWLEDGE);
//5.目的地 Queue queue = session.createQueue("mq-test-01"); //7.创建发送者 MessageProducer producer = session.createProducer(queue); for(int i=1;i<=10;i++) { //6.消息对象 TextMessage message = session.createTextMessage(); message.setText("消息"+i); //8.发送消息 producer.send(message); } //9.会话提交 // session.commit();
//10.关闭连接 connection.close(); } } |
Consumer1.java
public class Consumer1 {
private static final String userName = ActiveMQXAConnectionFactory.DEFAULT_USER; private static final String password = ActiveMQXAConnectionFactory.DEFAULT_PASSWORD; private static final String brokerURL = "tcp://192.168.129.10:61616";
public static void main(String[] args) throws JMSException { //1.创建连接工厂类 ConnectionFactory factory = new ActiveMQXAConnectionFactory(userName, password, brokerURL); //2.创建连接 Connection connection = factory.createConnection(); //3.启动连接 connection.start();
//4.创建会话对象session(事务transacted为true,参数2不生效) //acknowledgeMode: Session session = connection.createSession(true,Session.AUTO_ACKNOWLEDGE);
//5.目的地 Queue queue = session.createQueue("mq-test-01");
//6.接收消息对象 MessageConsumer consumer = session.createConsumer(queue);
//7.通过监听器接收消息 consumer.setMessageListener(new MessageListener() { public void onMessage(Message message) { TextMessage textMessage = (TextMessage)message; //获取消息 try { String msg = textMessage.getText(); System.out.println(msg); } catch (JMSException e) { } } });
} } |
2.2 发布者/订阅者
前面4步创建会话都一样的。
发布者:
目的地改了,不在用queue了,而是用Topic
由于我们需要每一个订阅者都要得到相同的消息,这个消息是不是要存储到我们的MQ里?不能丢了,要进行持久化。这个持久化意味着,当我们的MQ意外宕机,或者说关闭了,这个消息还在,这就是持久化的作用。
订阅者
目的地也改为Topic。
程序启动顺序:先订阅、再发布