SpringBoot2.1.X 整合 ActiveMQ点对点消息队列(一)

一、什么是消息队列?

    它是分布式应用间交换信息的重要组件。消息队列可驻留在内存或磁盘上, 队列可以存储消息直到它们被应用程序读走。通过消息队列,应用程序可以在不知道彼此位置的情况下独立处理消息,或者在处理消息前不需要等待接收此消息。所以消息队列可以解决应用解耦、异步消息、流量削锋等问题,是实现高性能、高可用、可伸缩和最终一致性架构中不可以或缺的一环。

简单的来说,消息队列就是独立于客户端与服务端,将消息(请求)以队列的形式存储起来,等待服务端进行读取;

二、消息队列的原理分析

        用户1、2、3同时向服务端系统发送请求,三个请求会先被分配到队列中存储起来,服务端会监听队列中的消息,一旦系统空闲,并且监听到队列中有消息,系统就会从队列中取出消息,并进行处理。如此设计,系统可以按照自己的节奏去处理请求,从而减轻服务端的压力,保证业务处理的流畅;即使系统由于某些原因停止运行,由于未处理的请求仍保存在队列中,这些请求也不会丢失。

 

三、消息队列的架构

   消息队列主要分为点对点(Queue)模式和订阅(Topic)模式两种

  主要角色有生产者、消息、队列、消费者

   如图所示点对点模式: 生产者Producer将生产出来的消息塞入到队列Queue中,消费者Consumer从队列中取出消息并消费,被消费完的消息不会存在在队列中,一条消息只会被一个消费者消费一次;

四、实战操作

1、先启动ActiveMQ服务

2、在pom.xml添加相应的包

   <!-- 整合消息队列ActiveMQ -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-activemq</artifactId>
        </dependency>

        <!-- 如果配置线程池则加入 -->
        <dependency>
            <groupId>org.messaginghub</groupId>
            <artifactId>pooled-jms</artifactId>
        </dependency>

3.配置文件application.properties

#整合jms测试,安装在别的机器,防火墙和端口号记得开放
spring.activemq.broker-url=tcp://127.0.0.1:61616

#集群配置
#spring.activemq.broker-url=failover:(tcp://localhost:61616,tcp://localhost:61617)

spring.activemq.user=admin
spring.activemq.password=admin
#下列配置要增加依赖
spring.activemq.pool.enabled=true
spring.activemq.pool.max-connections=100

4、springboot启动类中启用JMS


import org.apache.activemq.command.ActiveMQQueue;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.jms.annotation.EnableJms;
import javax.jms.Queue;

@SpringBootApplication
@EnableJms  //启用JMS
public class MqDemoApplication {

    @Bean  //交给spring来管理,注入哦!
    public Queue queue(){
        return new ActiveMQQueue("common.queue");
    }



    public static void main(String[] args) {
        SpringApplication.run(MqDemoApplication.class, args);
    }

}

5、生产消息接口

/**
 * 消息生产
 */
public interface ProducerService {
    //指定消息队列,还有消息
    public void sendMessage(Destination destination, final String msg);

    //使用默认消息队列, 发送消息
    public void sendMessage(final String msg);

}

6、实现生产消息接口

/**
 * 实现消息信息类
 */
@Service
public class ProducerServiceImpl  implements ProducerService {
//    用来发送消息到broker的对象
    @Autowired
    private JmsMessagingTemplate jmsTemplate;


    //注入指定消息队列  (在启动类中有注入哦!)
    @Autowired
    private Queue queue;


    @Override
    public void sendMessage(Destination destination, String msg) {
       // System.out.println("jmsTemplate="+jmsTemplate+"\t"+destination+"\t"+msg);
        jmsTemplate.convertAndSend(destination, msg);
        System.out.println("发送信息指定目标:"+msg);
    }

    @Override
    public void sendMessage(String msg) {
        jmsTemplate.convertAndSend(this.queue,msg);   //指定消息队列哦!!!
        System.out.println("发送信息默认目标:"+msg);
    }
}

7、控制类访问

@RestController
@RequestMapping("/activemq/my")
public class OrderController {


    @Autowired  //注入消息生产者
    private ProducerService service;
    /**
     * 微信支付回调接口
     */
    @GetMapping("order")
    public Object order(String msg){

        //目的地:生成消息队列地址
        Destination destination =new ActiveMQQueue("order.queue");

        //调用方法
        service.sendMessage(destination,msg);

        return JsonData.buildSuccess();
    }

    @GetMapping("comm")
    public Object comm(String msg) {
        //调用方法
        service.sendMessage(msg);

        return JsonData.buildSuccess();
    }

}

8、启动运行

 可以发多个信息哦!    http://localhost:8080/activemq/my/order?msg=116

再查看ActiveMQ服务

 3个请求入队后:此时队列中有3条入队(未被处理)的消息;

9、消费者消费类

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

/**
 *消费者
 */
@Component
public class OrderConsumer {

    //实时监听器监听order.queue这个消息队列
    @JmsListener(destination = "order.queue")
    public void receiveQueue(String text){
        System.out.println("OrderConsumer收到的消息为:"+text);
    }
}

 10、重新运行 监听到刚才发的信息了

11、重新发信息,实时监听。

12、消费者使用默认队列(common.queue)来消费 

/**
 *消费者
 */
@Component
public class CommConsumer {

    //实时监听器监听order.queue这个消息队列
    @JmsListener(destination = "common.queue")
    public void receiveQueue(String text){
        System.out.println("CommConsumer收到的消息为:"+text);
    }
}

 

 请求被服务端取走后:队列中再无其他消息,两条消息均已出列;

 

   总之: 消息队列并不能提高系统的运行速度(如果想提高速度,还是需要用到多线程等方式),消息队列作为中间件的作用是降低应用间的耦合,在高并发、高流量的情况下保证服务端的稳定,保证业务流程的顺畅和数据的完整(请求不丢失)。 

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值