java使用RabbitMQ(一)

1、简介

①RabbitMQ是一个消息中间件,各种微服务需要统一的往一个地方存储以及获取数据进行消费,这个业务场景就需要一个消息中间件,大部分应用中,可以通过引入消息中间件来提升系统的异步通信、扩展解耦能力
②消息服务中两个重要的概念
消息代理(message broker):代我们发送接受消息,安装了消息中间件的服务器
目的地(destination):队列(queue:点对点消息通信point-to-point)主题(topic:发布publish、订阅subscribe消息通信)
当消息发送者发送消息后,将由消息代理接管,消息代理保证消息传递到指定的目的地
③点对点式
消息发送者发送消息,消息代理将其放入一个队列中,消息接收者从队列中获取消息内容,消息读取后被移出队列
消息有唯一的发送者和接收者,接收者可以有一个也可以有多个
④发布订阅式
发送者(发布者)发送消息到主题,多个接收者(订阅者)监听(订阅)这个主题,那么就会在消息到达时同时收到消息
⑤JMS(java message service)java消息服务
基于jvm消息代理的规范。activeMQ、HornetMQ是JMS的实现
⑥AMQP(advanced message queuing protocol)高级消息队列协议
也是一个消息代理的规范兼容JMS,RabbitMQ是AMQP的实现

JMS(java message serive)AMQP(advanced message queuing protocol)
定义java api网络线级协议
跨语言
跨平台
Model提供两种消息模型①Peer-2-Peer②pub/sub提供了五种消息模型①direct exchange ②fanout exchange ③topic exchange ④headers exchange ⑤system exchange,本质来讲后四种和JMS的pub/sub模型没有太大区别,只是在路由机制上做了更详细的划分
支持消息类型多种消息类型①TextMessage②MapMessage③BytesMessage④StreamMessage⑤ObjectMessage⑥Message(只有消息头和属性)byte[ ],在实际应用时,有复杂的消息,可以将消息序列化后发送
综合评价JMS定义了java api层面的标准,在java体系中,多个client均可以通过JMS进行交互,不需要应用修改代码,但是其对跨平台的支持较差AMQP定义了wire-level层的协议标准,天然具有跨平台、跨语言的特性

1.1整合简介

1.1.1与spring整合

spring-jms提供了对jms的支持
spring-rabbit提供了对AMQP的支持
需要ConnectionFactory的实现来连接消息代理
提供了JmsTemplate、RabbitTemplate来发送消息
@JmsListener(JMS)、@RabbitListener(AMQP)注解在方法上监听消息代理发布的消息
@EnableJms、@EnableRabbit开启支持

1.1.2springboot开启

springboot是自动装配的只需引入相关的场景启动器即可stater
JmsAutoConfiguration、RabbitAutoConfiguration
市面上相关的MQ产品有ActiveMQ、RabbitMQ、RocketMQ、Kafka

1.2使用场景

①异步处理
在这里插入图片描述
②应用解耦
在这里插入图片描述
③流量控制,流量削峰
在这里插入图片描述

2、RabbitMQ的初步使用

2.1核心概念

①message:消息,由消息头和消息体组成,消息体是不透明的,而消息头则由一系列的可选属性组成,这些属性包括routing-key(路由键)、priority(相对于其他消息的优先权)、delivery-mode(指出该消息可能需要持久化存储)等
②publisher:消息的生产者,也是一个向交换器发布消息的客户端应用程序
③exchange:交换器,用来接受生产者发送的消息并将这些消息路由给服务器中的队列。exchange有4中类型:direct(默认)、fanout、topic和headers,不同类型的exchange转发消息的策略有所区别
④queue:消息队列,用来保存消息直到啊发送给消费者。他是消息的容器,也是消息的终点,一个消息可投入一个或多个队列,消息一直在队列中,等待消费者连接到这个队列将其取走
⑤binding:绑定,用于消息队列和交换器之间的关联。一个绑定就是基于路由键将交换器和消息队列连接起来的路由规则,所以可以将交换器理解成一个由绑定构成的路由表,exchange和queue的绑定可以是多对多的关系
⑥connection:网络连接,比如一个tcp连接
⑦channe:信道,多路复用连接中的一条独立的双向数据流通道,信道是建立在真实的TCP连接内的虚拟连接,AMQP命令都是通过信道发出去的,不管是发布消息、订阅消息、接收消息,这些动作都是通过信道完成的,因为对于操作系统来说建立和销毁TCP都是昂贵的开销,所以引入了信道的概念,以复用一条TCP连接
⑧consumer:消息的消费者,标识一个从消息队列中取消息的客户端应用程序
⑨virtual host:虚拟主机,表示一批交换器、消息队列和相关对象,虚拟主机是共享相同的身份认证和加密环境的独立服务器域,每个vhost本质上就是一个mini的rabbitMQ服务器,拥有自己的队列、交换器、绑定和权限机制。vhost是AMQP概念的基础,必须在连接时指定,RabbitMQ迷人的vhost时/
⑩表示消息队列服务器的实体

2.2简单使用

安装rabbitMQ后打开他的管理页面
①新建一个交换器,交换器名称必填,类型选填,发送消息要根据这个名称找到对应的交换器
type有4中常见的时
1.direct直接交换机,路由键要完全匹配才可以发往指定的队列
2.fanout扇出交换机,只要往这里发了,绑定的所有队列都会有消息
3.topic订阅类型交换机,只会发往符合条件的路由键绑定的队列
Durability是否持久化:transient就是临时的,rabbitMQ服务器一重启就没了
在这里插入图片描述
②新建一个队列,名称必填,发送的消息要指定发往拿个队列需要这个名称

在这里插入图片描述
创建绑定关系,
direct类型的交换机如果不给交换机指定路由键,我的理解相当于指定的时null以后发的任何消息都会根据路由键去路由
如果是扇出类型的交换机不管路由键是啥都会发往绑定的所有队列
在这里插入图片描述
接受消息的模式有4中
在这里插入图片描述

3、springBoot整合rabbitMQ

①引入依赖

       <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
        </dependency>

②给配置文件中配置基本属性,可以通过RabbitAutoConfiguration找到他绑定的配置文件RabbitProperties看一看
配三个基本的ip地址端口和虚拟主机

spring.rabbitmq.host=127.0.0.1
spring.rabbitmq.port=5672
spring.rabbitmq.virtual-host=/

③在启动来添加@EnableRabbit注解使应用整合rabbit
④测试使用


    /**
     * 创建Exchange 交换机
     */
    @Test
    public void testCreateExchange() {
        DirectExchange directExchange = new DirectExchange("hello-exchange", true, false);
        amqpAdmin.declareExchange(directExchange);
        log.info("direct交换机创建成功");
    }

    /**
     * 创建Queue 队列
     * exclusive是否是排他队列,是:一旦有人连上,别的人就无法连上该队列
     */
    @Test
    public void testCreateQueue() {
        Queue queue = new Queue("hello-queue", true, false, false);
        amqpAdmin.declareQueue(queue);
        log.info("queue队列创建成功");
    }

    /**
     * 创建Binding 绑定关系
     * String destination 目的地
     * Binding.DestinationType destinationType 目的地类型(队列还是交换机)
     * String exchange 交换机
     * String routingKey 路由键
     */
    @Test
    public void testCreateBinding() {
        Binding binding = new Binding("hello-queue",
                Binding.DestinationType.QUEUE,
                "hello-exchange",
                "hello-java",
                null);
        amqpAdmin.declareBinding(binding);
        log.info("binding绑定关系创建成功");
    }

发送消息,发现发送的序列化默认使用的java自带的序列化器

    @Test
    public void sendMessageTest() {
        rabbitTemplate.convertAndSend("hello-exchange", "hello-java","hello world!");
        Member member = new Member();
        member.setName("张三");
        // 1. !!! 要想这个对象member能够被发出去,这个member就一定要实现序列化接口,这个member没有实现就会报错 java.lang.IllegalArgumentException: SimpleMessageConverter only supports String, byte[] and Serializable payloads
        CommentDocument commentDocument = new CommentDocument();
        commentDocument.setCommentContent("哈哈哈");
        rabbitTemplate.convertAndSend("hello-exchange", "hello-java",commentDocument);
        // 2. 想要发送的消息
        log.info("消息发送成功");
    }

在这里插入图片描述
下面是分析思路和具体实现
在这里插入图片描述

如何转json
在这里插入图片描述
获得了json类型的数据,contentType也变为了json
在这里插入图片描述
接收消息

    /**
     * @RabbitListener
     *      ①必须开启@EnableRabbit注解,想要监听的队列必须存在
     *      ②该注解必须在容器中才能起作用
     * 接受的消息可以写
     * ①Object他的类型是org.springframework.amqp.core.Message
     * ②Message :原生消息,消息头和消息体
     * ③T 发的是什么类型,接受就什么类型
     * channel 消息传输的通道
     *
     * Queue 可以有很多人来监听,只要收到消息队列就会删除消息,而且只能有一个收到此消息
     * 场景)
     *      1、订单服务启动多个:同一个消息只能有一个客户端收到
     *      2、模拟耗时操作,只有当当前消息完全处理完,我们就可以接收到下一个消息
     * @RabbitHandler只能标注在方法上,可以做重载配合 @RabbitListener使用 用于接受不同的类型
     */
    @RabbitListener(queues = {"hello-java"})
    public void receiveMessage(Message message, CommentDocument commentDocument, Channel channel) {
        // 消息体
        byte[] body = message.getBody();
        // 消息头 属性信息
        MessageProperties messageProperties = message.getMessageProperties();
        System.out.println("接收到了消息" + message + "类型是" + message.getClass());
    }

    @RabbitHandler
    public void receiveMessage( CommentDocument message) {
        System.out.println("接收到了消息" + message + "类型是" + message.getClass());
    }
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值