SpringBoot JMS(ActiveMQ) 使用实践

ActiveMQ

1. 下载windows办的activeMQ后,在以下目录可以启动:

2. 启动后会有以下提示

3. 所以我们可以通过http://localhost:8161访问管理页面,通过tcp://localhost:61616来连接消息服务器,用到的用户名和密码都在以下文件中(默认为admin=admin)

springboot连接ActiveMQ

1. 加入依赖:

            spring-boot-starter-activemq

2. 配置连接属性:

spring.activemq.broker-url=tcp://localhost:61616
spring.activemq.user=admin
spring.activemq.password=admin
spring.activemq.pool.enabled=false

消息的发送和接收

生产者/消费者模式

    1. 创建生产者

package com.example.demo8activemq.jms;

import org.apache.activemq.command.ActiveMQQueue;
import org.springframework.jms.core.JmsMessagingTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.jms.Destination;

/**
 * @author Created by yawn on 2017-10-26 16:15
 */
@Service
public class Producer {

    @Resource
    private JmsMessagingTemplate jmsMessagingTemplate;

    public void sendMsg(String destinationName, String message) {
        System.out.println("============>>>>> 发送queue消息 " + message);
        Destination destination = new ActiveMQQueue(destinationName);
        jmsMessagingTemplate.convertAndSend(destination, message);
    }
}

    2. 创建消费者

package com.example.demo8activemq.jms;

import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Service;

/**
 * @author Created by yawn on 2017-10-26 16:15
 */
@Service
public class Consumer {

    @JmsListener(destination = "test.queue")
    public void receiveMsg(String text) {
        System.out.println("<<<<<<============ 收到消息: " + text);
    }
}

    注意: @JmsListener是一个可重复的注解,在java7及以下版本jdk中,可以使用@JmsListeners代替它。

    3. 测试类

@RunWith(SpringRunner.class)
@SpringBootTest
public class Demo8ActivemqApplicationTests {

	@Resource
	private Producer producer;

	@Test
	public void contextLoads() {
		for (int i = 0; i < 10; i++) {
			producer.sendMsg("test.queue", "Queue Message " + i);
		}
	}
}

    4. 运行测试

发布/订阅模式

    1. 发布话题

package com.example.demo8activemq.jms;

import org.apache.activemq.command.ActiveMQTopic;
import org.springframework.jms.core.JmsMessagingTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.jms.Destination;

/**
 * @author Created by yawn on 2017-10-28 17:09
 */
@Service
public class Publisher {

    @Resource
    private JmsMessagingTemplate jmsMessagingTemplate;

    public void publish(String destinationName, String message) {
        Destination destination = new ActiveMQTopic(destinationName);
        System.out.println("============>>>>> 发布topic消息 " + message);
        jmsMessagingTemplate.convertAndSend(destination, message);
    }
}

    2. 订阅话题

package com.example.demo8activemq.jms;

import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Service;

/**
 * @author Created by yawn on 2017-10-28 17:15
 */
@Service
public class Subscriber {

    @JmsListener(destination = "test.topic", containerFactory = "myJmsContainerFactory")
    public void subscribe(String text) {
        System.out.println("===========<<<<<<<<收到订阅的消息" + text);
    }
}

    注意: 在pub/sub模式中,对消息的监听需要对containerFactory进行以下配置

    @Bean
    JmsListenerContainerFactory<?> myJmsContainerFactory(ConnectionFactory connectionFactory){
        SimpleJmsListenerContainerFactory factory = new SimpleJmsListenerContainerFactory();
        factory.setConnectionFactory(connectionFactory);
        factory.setPubSubDomain(true);
        return factory;
    }

    3. 测试

    @Test
	public void test() {
		for (int i = 0; i < 10; i++) {
			publisher.publish("test.topic", "Topic Message " + i);
		}
	}

应用

    按照以上步骤,在springboot中很容易就实现类两种模式的消息发送和接收。但是jms具体的应用场景是在不同的应用程序之间,生产者和消费者往往是在不同的应用中的。此外,以上例子中的消息我们只发送字符串,其实还可以发送Object类型的消息,甚至可以使用messageCreator自定义消息的转换,而不使用convertAndSend方法默认转换。

多个应用程序之间发送消息

1. 先使用一个只有发送者,没有消费者或订阅者的应用发送两类消息各十条

2. 我们打开localhost:8161,可以看到

    两类都曾有十条消息入队,但只有queues中还存留10条消息。

3. 现在我们启动包含消费者和订阅者的应用程序

    果然,只有消费者收到了queues中的消息。

    这说明订阅者接收topic是需要在topic发布之前订阅;而生产/消费模式下,消息发出后会存放在队列中,等待消费者消费。

    4. 我们先启动两个包含订阅者和消费者的程序,再发布消息

    两个订阅者都收到 topic message 1~9, 而消费者中,一个收到消息 1、3、5、7、9,另一个收到0、2、4、6、8。

    这说明有多个消息接收者时,生产/消费模式下多个消费者会轮流消费队列中的消息,而pub/sub模式下所有订阅者都会得到所有的消息。

    以上就是在多个应用程序之间验证了发布/订阅模式和生产/消费模式的不同特点。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏顶级程序员

5个强大的Java分布式缓存框架推荐

在开发中大型Java软件项目时,很多Java架构师都会遇到数据库读写瓶颈,如果你在系统架构时并没有将缓存策略考虑进去,或者并没有选择更优的缓存策略,那么到时候重...

3234
来自专栏DT乱“码”

activeMQ

activeMQ 是学习java消息队列的实现项目,使用jfinal + jfinal-ext + activeMQ + quartz快速构建。 1.消息队列 ...

19110
来自专栏JMCui

Spring消息之JMS.

1335
来自专栏搜云库

Spring Boot 中使用 Kafka

Kafka 是一种高吞吐的分布式发布订阅消息系统,能够替代传统的消息队列用于解耦合数据处理,缓存未处理消息等,同时具有更高的吞吐率,支持分区、多副本、冗余,因此...

3806
来自专栏LinkedBear的个人空间

ActiveMQ入门,ActiveMQ与RocketMQ的对比

ActiveMQ是Apache下的开源项目,完全支持JMS1.1和J2EE1.4规范的JMS Provider实现。

682
来自专栏软件工程师成长笔记

springboot集成ActiveMQ

522
来自专栏芋道源码1024

【消息队列 MQ 专栏】消息队列之 RocketMQ

RocketMQ 是阿里巴巴在2012年开源的分布式消息中间件,目前已经捐赠给 Apache 软件基金会,并于2017年9月25日成为 Apache 的顶级项目...

2090
来自专栏中国白客联盟

Phpshell Bypass Safedog

(php的function介绍可以看这里:http://www.php.net/manual/zh/functions.user-defined.php)

913
来自专栏吴伟祥

activeMQ 原

693
来自专栏YG小书屋

ES集群状态详细信息

1282

扫码关注云+社区