SpringAMQP入门之基本消息队列与工作消息队列

SpringAMQP基础入门

SpringAMQP是基于RabbitMQ封装的一套模板,并且还利用SpringBoot对其实现了自动装配,使用起来非常方便。

SpringAmqp的官方地址:Spring AMQP

HelloWorld中的基础消息队列功能

案例:利用SpringAMQP实现HelloWorld中的基础消息队列功能

publisher服务:消息发送者

consumer服务:消息接收者

流程如下:

发送消息

1.在父工程中引入spring-amqp的依赖

<!--AMQP依赖,包含RabbitMQ-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

2.在publisher服务中利用RebbitTemplate发送消息队列simple.queue这个队列

  • 在publisher服务中编写application.yml。添加mq连接信息

  • spring:
      rabbitmq:
        host: 192.168.171.171 # 虚拟机ip地址
        port: 5672 # 端口
        virtual-host: / # 虚拟主机
        username: root # 用户名
        password: 123321 # 密码
  • 在publisher服务中新建一个测试类,编写测试方法

  • @RunWith(SpringRunner.class)
    @SpringBootTest
    public class SpringAmqpText {
        @Autowired
        private RabbitTemplate rabbitTemplate;
        @Test
        public void testSendMessage2SimpleQueue(){
            String queueName = "simple.queue";
            String message = "hellow chouchou!!!!!";
            rabbitTemplate.convertAndSend(queueName,message);
        }
    }

注:本方法不会创建队列,只会沿用以前创建的队列(simple.queue)

想要创建队列可见我的另外一篇博客(89条消息) RibbitMQ基于SpringAMQP创建消息队列以及完成交换机的创建与绑定的两种方法_小白紬的博客-CSDN博客

接收消息

1.在consumer服务中编写消费逻辑,绑定simple.queue这个队列

  • 在consumer服务中编写application.yml。添加mq连接信息

  • spring:
      rabbitmq:
        host: 192.168.171.171 # 虚拟机ip地址
        port: 5672 # 端口
        virtual-host: / # 虚拟主机
        username: root # 用户名
        password: 123321 # 密码

在consumer服务中新建一个类,编写消费逻辑:

@Component
public class SpringRabbitListener {
    @RabbitListener(queues = "simple.queue")
    public void listenSimpleQueue(String msg){
        System.out.println("欢迎紬紬到来(simple.queue): " + msg);
    }
}

注:消息一旦消费就会从队列删除,RabbitMQ没有消息回溯功能(即阅后即焚)

Work Queue 工作队列

Work queues,也被称为(Task queues),任务模型。简单来说就是让多个消费者绑定到一个队列,共同消费队列中的消息

Work Queue,工作队列,可以提高消息处理速度,避免队列消息堆积

 

案例 模拟WorkQueue,实现一个队列绑定多个消费者

基本思路如下:

1.在publisher服务中测试方法,每秒产生50条消息,发送到simple.queue

@Test
    public void testSendMessage2WorkQueue() throws InterruptedException {
        String queueName = "simple.queue";
        String message = "hellow chouchou__";
        for (int i = 1;i <= 50 ;i++){
            rabbitTemplate.convertAndSend(queueName,message + i);
            Thread.sleep(20);//休眠0.02秒
        }
    }

2.在consumer服务中定义两个消息监听者,都监听simple.queue队列

3.消费者1每秒处理50条消息,消费者2每秒处理10条消息

@RabbitListener(queues = "simple.queue")
    public void WorkQueue1(String msg) throws InterruptedException {
        System.out.println("欢迎一号紬紬到来(simple.queue): " + msg + "耗时: " + LocalTime.now());
        Thread.sleep(20);//休眠0.02秒
    }
​
    @RabbitListener(queues = "simple.queue")
    public void WorkQueue2(String msg) throws InterruptedException {
        System.err.println("欢迎二号紬紬到来66666(simple.queue): " + msg + "耗时: " + LocalTime.now());
        Thread.sleep(200);//休眠0.2秒
    }

 

然而事实结果是,消费者1与消费者2以奇数偶数的形式平均分配了发送者发送的50条消息 。。。

原因就是出在了springAMQP的消费预取机制

消费预取

消费者获取消息队列的消息时,默认是直接全部获取(或平均获取),不做处理,等消息获取完在处理

比如队列有10条消息,两个消费者各自直接先预取5个消息,如果一个消费者接受消息的速度慢,一个快,就会导致一个消费者已经完成工作,另一个还在慢慢处理,会造成消息堆积消费者身上,要解决这个问题需要在yml文件配置相关配置

消费预取限制

修改消费者application.yml文件,设置prefetch这个值,可以控制预取消息的上限:

spring:
  rabbitmq:
    host: 192.168.171.171 # 虚拟机ip地址
    port: 5672 # 端口
    virtual-host: / # 虚拟主机
    username: root # 用户名
    password: 123321 # 密码
    listener:
      simple:
        prefetch: 1 # 每次只能获取一条消息,处理完成才能获取下一条消息

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值