AMQP[RabbitMQ]小结

消息队列:

组成:

交换器,队列,绑定

作用:异步处理,削峰,服务解耦

交换器

RabbitMQ常见的exchange(交换器)类型:

  • direct--路由键完全匹配才可以

  • fanout--广播

  • topic --主题,模糊匹配路由键

队列

messagequeue:

组成:

  • 路由键 routine-key---决定消息发给谁

  • 优先级priority--决定消息发送的优先级

  • 分发模式deliver-mode--决定消息的发送方式--持久化等

绑定

binding:

依赖

复制代码
 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
            <version>2.6.4</version>
        </dependency>

配置文件:

复制代码
spring:
  rabbitmq:
    username: zzy
    password: 1234
    host: 172.24.232.166

注册队列:

复制代码
@Configuration
public class RabbitConfig {
    @Bean
    protected Queue queue(){

        Queue queue= new Queue("zzy");
        return  queue;
    }
}

生产者发送消息

复制代码
//作为信息的发布者
@SpringBootTest(classes = ApplicationRabbitMq.class)
public class RabbitTest {
    //Amqp模板类
    @Autowired
    private AmqpTemplate amqpTemplate;

    @Test
    void RabbitTest(){
        amqpTemplate.convertAndSend("zzy","hello world");
        System.out.println("success");
    }
}

消费者消费消息:

复制代码
@Component  //加注解,不然无法解析
public class RabbitMqConsumer {

    @RabbitListener(queues = "zzy")//订阅的队列
    public void Listened1(String msg){

        System.out.println("取出的消息1----"+msg);
    }
    @RabbitListener(queues = "zzy")
    public void Listened2(String msg){

        System.out.println("取出的消息2----"+msg);
    }
}

默认使用direct队列,如果要使用广播队列:

复制代码
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.FanoutExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RabbitFanoutConfig {

    //准备两个队列

    @Bean
    protected Queue queue() {

        return new Queue("gavin");
    }


    @Bean
    protected Queue queue2() {

        return new Queue("zzy");
    }

//内置fanout交换器名称amq.fanout

    @Bean
    protected FanoutExchange fanoutExchange() {

        return new FanoutExchange("amq.fanout");
    }

 //将交换器和队列绑定

    @Bean
    protected Binding fanoutBinding(Queue queue, FanoutExchange fanoutExchange) {

        return BindingBuilder.bind(queue).to(fanoutExchange);
    }

    @Bean
    protected Binding fanoutBinding2(Queue queue2, FanoutExchange fanoutExchange) {

        return BindingBuilder.bind(queue2).to(fanoutExchange);
    }
}

一个交换器可以绑定多个队列;

几个重要的注解/Bean

复制代码
import org.springframework.amqp.core.AmqpTemplate;
@Bean
AmqpTemplate amqpTemplate 
//此模板中有发送消息的方法

-------------------------------------
import org.springframework.amqp.core.Queue;
//注册一个队列direct
  @Bean
    protected Queue queue() {

        return new Queue("gavin");
    }

//注册一个广播交换器
 @Bean
    protected FanoutExchange fanoutExchange() {

        return new FanoutExchange("amq.fanout");
    }
//交换器绑定队列
 //将交换器和队列绑定

    @Bean
    protected Binding fanoutBinding(Queue queue, FanoutExchange fanoutExchange) {

        return BindingBuilder.bind(queue).to(fanoutExchange);
    }
//注册一个topic交换器
 @Bean
    protected TopicExchange topicExchange() {

        return new TopicExchange("amq.topic");
    }
//绑定队列
 //将交换器和队列绑定

    @Bean
    protected Binding TopicBind1(Queue queue, TopicExchange topicExchange) {

        return BindingBuilder.bind(queue).to(topicExchange).with("com.gavin.*");//匹配路由规则
    }

消费者:

复制代码
 @RabbitListener(queues = "gavin")
 该方法从对列中消费消息

消息重复消费原因:

消费完毕后本该向broker发送ack,但是由于网路延迟较高过了broker等待的时间,于是broker会把消息再次投递到consumer

解决方案:

数据库---处理消息前,使用消息主键在表中带有约束的字段中insert,插入成功则消费成功,插入失败则已经消费过了,不再进行消费

Map--单机版的使用ConrrentHashMap ->putifAbsent

Redis --分布式锁

保证消息队列的消费顺序

同一个topic,同一个queue,发的时候让一个线程去发,消费的时候让一个线程去消费,如果多线程暂时无法保证消费的有序性

怎么保证消息发送到同一个queue?

RocketMQ 提供了一个MessageQueueSelector 接口,重写接口方法

RocketMQ如何保证消息不丢失

Producer端:

采用send()同步发消息,发送结果是同步感知的;

Broker端:

设置数显策略为同步刷新策略

集群部署,配置主从,高可用模式

Consumer端:

消费正常后再进行手动ACK确认

相关推荐
这个昵称不容易8 小时前
SpringBoot「衣依」服装销售平台:144个Java文件180个接口,从挑衣服到收货评价整条链路都在
java·springboot·毕设
计算机毕设定制辅导-无忧学长9 小时前
《基于微信小程序的居家医疗陪护预约系统设计与实现》
java·spring boot·微信小程序·uniapp·居家医疗陪护预约系统
文丑颜不良啊10 小时前
LeetCode2221~2240题目解析
java·leetcode
秋饼10 小时前
Computer Use Agent Java 落地实战:感知-行动循环、执行器与安全围栏生产级实现
java·ai·技术分享·后端开发
文丑颜不良啊12 小时前
LeetCode2161~2180题目解析
java·leetcode
文丑颜不良啊14 小时前
LeetCode2141~2160题目解析
java·leetcode
LabVIEW开发14 小时前
LabVIEW 连接板:28 个端子怎么排,优先级怎么定
java·算法·labview
天天被压力14 小时前
【A股分钟级高频数据完全手册 #07】北交所历史分钟K线接口:京市Pro版分时批量
java·人工智能·python
天天被压力15 小时前
【A股分钟级高频数据完全手册 #08】股票日、分时数据接口对比:普通分时与Pro版差异实测
java·人工智能·python
特立独行的猫A15 小时前
AI 时代,我为什么推荐用 cj-tauri 开发桌面应用
java·后端·python