ActiveMQ部署和代码尝试(二)
部署和代码尝试
1. 部署在linux 上的acvtiveMQ 要可以通过前台windows 的页面访问,必须把linux 的IP和 windows的 IP 地址配置到同一个网关下 。这种情况一般都是修改 linux 的IP 地址,修改网卡文件对应的IP 地址
修改linux 的ip 地址:
cd /etc/sysconfig/network-scripts vi ifcfg-eth0
这是修改之后的网卡文件配置,IP 地址为:192.168.17.3 (因为我的windows 的IP 地址为192.168.17.1,将他们配置在了同一个网关下)
配置成功后 ,可以用 windows ping linux , linux ping windows ,当全部ping 通后,可以使用图形化界面访问activeMQ
// ActiveMQ 的前台端口为 8161 , 提供控制台服务 后台端口为61616 ,提供 JMS 服务
// 192.168.17.3 为 linux 的IP 地址, 使用 IP+端口 访问了ActiveMQ , 登陆之后的样子如上。(能访问成功首先得在linux 上启动activeMQ 的服务),首次登录的默认账户密码为 账号:admin 密码:admin
访问不到的坑: 1. 可能是你的linux 和 windows 没有在一个网关下
2.可能你windows 的防火墙或者 linux 的防火墙没有关掉(是的,先得关掉防火墙)
3.你忘记启动activemq 的服务了
4.你启动失败了,可能是你得java 环境没配好,必须是jdk 8 或者以上
JMS : Java 消息中间件的服务接口规范,activemq 之上是 mq , 而 mq 之上是JMS 定义的消息规范 。 activemq 是mq 技术的一种理论实现(与之相类似的实现还有 Kafka RabbitMQ RockitMQ ),而 JMS 是更上一级的规范。
在点对点的消息传递时,目的地称为 队列 queue
在发布订阅消息传递中,目的地称为 主题 topic
2. demo 初试 一个简单的生产者消费者
生产者:
public class JmsProduce { // linux 上部署的activemq 的 IP 地址 + activemq 的端口号 public static final String ACTIVEMQ_URL = "tcp://192.168.17.3:61616"; public static final String QUEUE_NAME = "queue01"; public static void main(String[] args) throws Exception{ // 1 按照给定的url创建连接工程,这个构造器采用默认的用户名密码 ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(ACTIVEMQ_URL); // 2 通过连接工厂连接 connection 和 启动 javax.jms.Connection connection = activeMQConnectionFactory.createConnection(); // 启动 connection.start(); // 3 创建回话 session // 两个参数,第一个事务, 第二个签收 Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); // 4 创建目的地 (两种 : 队列/主题 这里用队列) Queue queue = session.createQueue(QUEUE_NAME); // 5 创建消息的生产者 MessageProducer messageProducer = session.createProducer(queue); // 6 通过messageProducer 生产 3 条 消息发送到消息队列中 for (int i = 1; i < 4 ; i++) { // 7 创建字消息 TextMessage textMessage = session.createTextMessage("msg--" + i); // 8 通过messageProducer发布消息 messageProducer.send(textMessage); } // 9 关闭资源 messageProducer.close(); session.close(); connection.close(); System.out.println(" **** 消息发送到MQ完成 ****"); } }
以及在页面上的显示:
与之相对应的消息消费者(处理消息的系统)代码及运行
public class JmsConsumer { public static final String ACTIVEMQ_URL = "tcp://192.168.17.3:61616"; public static final String QUEUE_NAME = "queue01"; // 1对1 的队列 public static void main(String[] args) throws Exception{ // 1 按照给定的url创建连接工程,这个构造器采用默认的用户名密码 ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(ACTIVEMQ_URL); // 2 通过连接工厂连接 connection 和 启动 javax.jms.Connection connection = activeMQConnectionFactory.createConnection(); // 启动 connection.start(); // 3 创建回话 session // 两个参数,第一个事务, 第二个签收 Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); // 4 创建目的地 (两种 : 队列/主题 这里用队列) Queue queue = session.createQueue(QUEUE_NAME); // 5 创建消息的消费者 MessageConsumer messageConsumer = session.createConsumer(queue); while(true){ // 这里是 TextMessage 是因为消息发送者是 TextMessage , 接受处理的 // 也应该是这个类型的消息 TextMessage message = (TextMessage)messageConsumer.receive(); if (null != message){ System.out.println("****消费者的消息:"+message.getText()); }else { break; } } messageConsumer.close(); session.close();
connection.close();
}
}
这个代表有一个消息消费者处理消息,并且处理了三条消息
// 通过监听的方式来消费消息 // 通过异步非阻塞的方式消费消息 // 通过messageConsumer 的setMessageListener 注册一个监听器, // 当有消息发送来时,系统自动调用MessageListener 的 onMessage 方法处理消息 messageConsumer.setMessageListener(new MessageListener() { // 可以用监听器替换之前的同步receive 方法 public void onMessage(Message message) { if (null != message && message instanceof TextMessage){ TextMessage textMessage = (TextMessage)message; try { System.out.println("****消费者的消息:"+textMessage.getText()); }catch (JMSException e) { e.printStackTrace(); } } } });
这里的一点经验: activemq 好像自带负载均衡,当先启动两个队列(Queue)的消费者时,在启动生产者发出消息,此时的消息平均的被两个消费者消费。 并且消费者不会消费已经被消费的消息(即为已经出队的消息)
但是当有多个主题(Topic)订阅者时,发布者发布的消息,每个订阅者都会接收所有的消息。topic 更像是被广播的消息,但是缺点是不能接受已经发送过的消息。
先要有订阅者,生产者才有意义。