mq(message queue)消息队列
Linux安装activemq
进入官网,下载Linux版本的apache-acitvemq-···.tar.gz文件,上传至Linux系统的/opt 文件夹下并使用tar -zxvf ···.tar.gz命令解压文件并进入bin目录下普通启动activemq
./activemq start > ../logs/activemq-run.log
运行并记录log日志
运行完成之后查看系统进程
ps -ef|grep activemq|grep -v grep
注意:有些朋友可能启动完成之后网页访问控制台8161端口访问不了,这个时候我们需要先关闭虚拟机防火墙,如果还不行则修改一下conf
目录下的jetty.xml
文件,将jettyPort
节点的host属性127.0.0.1改为主机端口或者改为0.0.0.0放过所有端口
mq能干什么?使用mq跟不使用mq的区别
mq常用的具体实现有哪些?他们有什么区别
使用JMS方式连接到mq 队列queue
使用消息提供者发送消息到目的地 queue/topic
private static final String ACTIVEMQ_URL = "tcp://192.168.174.134:61616"; private static final String USERNAME = "admin"; private static final String PASSWORD = "admin"; private static final String QUEUE_NAME = "user-queue"; public static void main(String[] args) { //1.通过用户名密码url创建连接工厂 ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory(USERNAME,PASSWORD,ACTIVEMQ_URL); try { //2.通过连接工厂创建连接并启动访问 Connection connection = factory.createConnection(); connection.start(); //3.创建session回话 参数transacted 事务/acknowledgeMode签收 Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); //4.创建目的地 目的地是队列queue还是主题topic Queue queue = session.createQueue(QUEUE_NAME); //5.创建消息生产者 通过生产者往队列里面发送消息 MessageProducer producer = session.createProducer(queue); //6.创建消息 TextMessage textMessage = session.createTextMessage("hello activemq"); //7.通过提供者往队列里面发送消息 producer.send(textMessage); //8.发送完成 释放资源 producer.close(); session.close(); connection.close(); System.out.println("消息发送完成,发送到"+QUEUE_NAME+"队列"); } catch (JMSException e) { e.printStackTrace(); } }
使用消息消费者从目的地得到消息 queue/topic
private static final String ACTIVEMQ_URL = "tcp://192.168.174.134:61616"; private static final String USERNAME = "admin"; private static final String PASSWORD = "admin"; private static final String QUEUE_NAME = "user-queue"; public static void main(String[] args) { //1.通过用户名密码url创建连接工厂 连接默认才用admin用户名 admin密码 ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory(USERNAME,PASSWORD,ACTIVEMQ_URL); try { //2.建立连接并开启访问连接 Connection connection = factory.createConnection(); connection.start(); //3.创建连接session会话 Session session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE); //4.通过会话创建目的地 是队列还是主题 Queue queue = session.createQueue(QUEUE_NAME); //5.创建消息消费者 消费消息 MessageConsumer consumer = session.createConsumer(queue); //6.从队列获取消息 while (true){ TextMessage message = (TextMessage) consumer.receive(); if (message!=null){ System.out.println("得到的消息为:"+message.getText()); }else { break; } } //7.得到消息之后关闭连接 consumer.close(); session.close(); connection.close(); } catch (JMSException e) { e.printStackTrace(); } }
tips 消息消费者在得到消息的时候有几种方式:
-
使用
receive()
方法得到消息,线程是同步阻塞的,如果不告知等待时间在没有得到消息之前消费者会一直等待使用
receive(3000)
方法,等待3s,如果没有得到消息则放弃等待 -
使用
MessageListener
消息监听者的方式来得到消息,线程是异步非阻塞的,不能直接关闭连接,因为连接到activemq是ftp通信,不确定什么时间能连接上,所以可以采用System.in.read()
方法使线程阻塞//创建目的地 Queue queue = session.createQueue(QUEUE_NAME); //创建消息消费者 MessageConsumer consumer = session.createConsumer(queue); //创建消息监听者 //给消息消费者设置监听者 通过监听器的方式来拿是异步非阻塞方式 consumer.setMessageListener(new MessageListener() { @Override public void onMessage(Message message) { if (message instanceof TextMessage) { TextMessage textMessage = (TextMessage) message; try { System.out.println(textMessage.getText()); } catch (JMSException e) { e.printStackTrace(); } } } }); //因为连接到activemq是ftp通信 所以连接需要时间 如果直接关闭连接会存在还没连接上就已经关闭了 System.in.read(); //释放资源 consumer.close(); session.close(); connection.close();
-
消息消费者每次从队列里面得到消息,都会将这条消息出队,消费者不会消费已经消费过的消息
-
如果同时有多个消息消费者监听同一个队列,此时在往队列里面发送消息,则多个消息消费者会默认使用轮询的方式得到消息