RabbitMQ入门概念

目录

一、RabbitMQ入门

1.1 rabbitmq是啥?

1.2 应用场景

1.3 AMQP协议与RabbitMQ工作流程

1.4 Docker安装部署RabbitMQ

二、SpringBoot连接MQ配置

2.1 示例1

 2.1 示例2 —— 发送实体


一、RabbitMQ入门

1.1 rabbitmq是啥?

MQ(Message queue 释义):消息队列,本质上就是一个队列。

  • 服务之间最常见的通信方式是直接调用彼此来通信,消息从一端发出后立即就可以达到另一端,称为即时消息通讯(同步通信)
  • 消息从某一端发出后,首先进入一个容器进行临时存储,当达到某种条件后,再由这个容器发送给另一端,称为延迟消息通讯(异步通信)

        而消息队列(Message Queue)是在消息的传输过程中保存消息的容器。在消息队列中,通常有生产者和消费者两个角色。生产者只负责发送数据到消息队列,谁从消息队列中取出数据处理,他不管。消费者只负责从消息队列中取出数据处理,他不管这是谁发送的数据。

RabbitMQ入门概念_第1张图片

1.2 应用场景

        RabbitMQ是一个消息代理 - 一个消息系统的媒介。它可以为你的应用提供一个通用的消息发送和接收平台,并且保证消息在传输过程中的安全。

ribbitmq主要解决异步处理、应用解耦、流量削锋等问题,实现高性能,高可用,可伸缩和最终一致性架构

  • 异步处理

如图所示:当一个用户购买了商品,订单开始发送发货通知——>刷新商品推荐(重新计算用户的喜好)——>增加会员积分,这些时间加一起就要150ms。而使用的RabbitMQ之后,将订单的求情放到rabbitmq容器中,不需要等待其他服务处理完再返回结果,让他们自己去rabbitmq排队处理。

RabbitMQ入门概念_第2张图片

  • 解耦 

如图所示:假设有系统B、C、D都需要系统A的数据,于是系统A调用三个方法发送数据到B、C、D。这时,系统D不需要了,那就需要在系统A把相关的代码删掉。假设这时有个新的系统E需要数据,这时系统A又要增加调用系统E的代码。为了降低这种强耦合,就可以使用MQ,系统A只需要把数据发送到MQ,其他系统如果需要数据,则从MQ中获取即可。 

RabbitMQ入门概念_第3张图片

  • 削峰 

应用场景:秒杀活动,一般会因为流量过大,导致流量暴增,应用挂掉。为解决这个问题,一般需要在应用前端加入消息队列

  1. 可以控制活动的人数
  2. 可以缓解短时间内高流量压垮应用 

如图所示:这其实是MQ一个很重要的应用。假设用户在某一段时间请求数暴增,有5000个请求发送过来,系统这时就会发送5000条SQL进入MySQL进行执行,MySQL对于如此庞大的请求当然处理不过来,MySQL就会崩溃,导致系统瘫痪。如果使用MQ,系统不再是直接发送SQL到数据库,而是把数据发送到MQ,MQ短时间积压数据,然后由消费者每次拉取2000条进行处理,防止在请求峰值时期大量的请求直接发送到MySQL导致系统崩溃

RabbitMQ入门概念_第4张图片

1.3 AMQP协议与RabbitMQ工作流程

        AMQP:一个提供统一消息服务的应用层标准高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计。基于此协议的客户端与消息中间件可传递消息,并不受客户端/中间件不同产品,不同的开发语言等条件的限制。

像RabbitMQ这样的消息队列实现是基于AMQP协议的,如果先了解一条消息从投递到消息队列到被消费者消费的生命周期,再来深入了解RabbitMQ的使用那就很easy。

RabbitMQ入门概念_第5张图片

  • 消息(Message):即客户端与消息中间件传送的数据。
  • 生产者(Publisher):消息发起人。
  • 消费者(Consumer):消息消费者。
  • 交换机(Exchange):接收消息,并将消息路由转发给消息队列。
  • 虚拟主机(Virtual Host):进行逻辑隔离,一个虚拟主机可以创建若干个交换机和队列。
  • 绑定(Binding):交换机和队列之间的虚拟连接。
  • 路由键(Routing Key):路由规则,虚拟机可以用来确定如何路由一个特定的消息。
  • 队列(Queue):存储即将被消费者消费掉的消息。
  • 中间件(Broker ):实现AMQP实体服务,比如常见的RabbitMQ、Azure Service Bus等。
  • 信道(Channel):网络信道,是建立在Connection连接之上的一种轻量级的连接,可以创建多个信道。
  • 连接(Connection):一个网络连接,比如TCP/IP连接。AMQP连接通常是长连接,当一个应用不再需要连接到AMQP代理的时候,需要释放掉 AMQP 连接,而不是直接将TCP连接关闭。

工作过程:

1.生产者发布消息,经由交换机。
2.交换机根据路由规则将收到的消息分发给与该交换机绑定的队列。
3.最后消息中间件会将消息投递给订阅了此队列的消费者,或者消费者按照需求自行获取。

4.消费者在成功处理消息后向 RabbitMQ 发送确认(ACK)。这告诉 RabbitMQ 可以安全地从队列中删除该消息。如果消费者在处理消息时发生错误,RabbitMQ 可以将消息重新分发给其他消费者。

可靠性与持久性:RabbitMQ 提供了消息的持久性选项,允许将消息和队列标记为持久的。这确保即使 RabbitMQ 服务器重启,消息和队列也不会丢失。

技术选型:

RabbitMQ入门概念_第6张图片

1.4 Docker安装部署RabbitMQ

  •  拉取镜像
docker pull rabbitmq:management

注意获取镜像的时候要获取management版本的,不要获取last版本的,management版本的才带有管理界面。

  •  创建容器

1、创建宿主机目录

RabbitMQ入门概念_第7张图片

防火墙开放端口:

firewall-cmd --zone=public --add-port=5672(15672)/tcp --permanent

docker run -itd \
--name my-rabbitmq \
-p 5672:5672 -p 15672:15672 \
-v /home/rabbitmq:/var/lib/rabbitmq \
--hostname my-rabbitmq-host \
-e RABBITMQ_DEFAULT_VHOST=my_vhost \
-e RABBITMQ_DEFAULT_USER=ycxw \
-e RABBITMQ_DEFAULT_PASS=123 \
--restart=always \
rabbitmq:management

--hostname:主机名(RabbitMQ的一个重要注意事项是它根据所谓的 “节点名称” 存储数据,默认为主机名)

-e:指定环境变量:

  • RABBITMQ_DEFAULT_VHOST:默认虚拟机名
  • RABBITMQ_DEFAULT_USER:默认的用户名
  • RABBITMQ_DEFAULT_PASS:默认用户名的密码
  • 访问RabbitMQ管理平台

RabbitMQ入门概念_第8张图片

 登录进入之后就可看到一些用户数据、所管理的虚拟主机、队列等等。。。这里不做详细讲解,简单了解请看目录:1.3RabbitMQ入门概念_第9张图片

二、SpringBoot连接MQ配置

2.1 示例1

1、创建项目:publisher 生成者 , consumer 消费者

RabbitMQ入门概念_第10张图片RabbitMQ入门概念_第11张图片

rabbitmq需要导入amqp依赖

        
        
            org.springframework.boot
            spring-boot-starter-amqp
        

 2、rabbitmq连接配置

生产者端口:8888        消费者端口:6666

注意!!!

        需等生产者创建队列后并发送过一次信息被rabbitmq接受,消费者才能启动项目,不然会报错找不到连接的队列名

server:
  port: 8888
spring:
  rabbitmq:
    #虚拟机地址
    host: 192.168.83.129
    port: 5672
    #rabbitmq注册用户与密码
    username: ycxw
    password: 123
    virtual-host: my_vhost
  • 生产者(publisher) 

3、创建Rabbit配置类RabbitConfig,配置类主要用来配置队列、交换器、路由等高级信息

package com.ycxw.publisher.demos;

import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@SuppressWarnings("all")
public class RabbitConfig {
    @Bean
    public Queue firstQueue() {
        return new Queue("firstQueue");
    }
}

4、创建消息产生者类

package com.ycxw.publisher.demos;

import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class Sender {
    @Autowired
    private AmqpTemplate rabbitTemplate;

    @RequestMapping("/send1")
    public String sendFirst() {
        /*向消息队列发送消息 converAndSend(队列名,发送的信息)*/
        rabbitTemplate.convertAndSend("firstQueue", "Hello World");
        return "";
    }
}

  • 消费者

5、编写接受队列的消息方法

package com.ycxw.consumer.demos;

import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

@Component
@SuppressWarnings("all")
@Slf4j
@RabbitListener(queues = "firstQueue") //监听消息队列
public class Receiver {

    //处理接受的信息
    @RabbitHandler
    public void process(String msg) {
        log.warn("接收到:" + msg);
    }
}

 6、测试

生产者发起请求:

RabbitMQ入门概念_第12张图片

rabbitmq管理界面查看数据:

RabbitMQ入门概念_第13张图片

消费者接受信息:

RabbitMQ入门概念_第14张图片

 2.1 示例2 —— 发送实体

注意!!!

  1. 处理不同请求许再创建一个队列
  2. 实体需进行序列化才可发送
  3. 发送实体,需要两个模块的实体必须同名同包下         

1、创建实体类

package com.ycxw.publisher.demos;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

//实现spring自带序列化接口
@SuppressWarnings("all")
@AllArgsConstructor
@NoArgsConstructor
@Data
public class User implements Serializable {
    private String username;
    private String userpwd;
}

 RabbitMQ入门概念_第15张图片

 2、创建队列(生产者)

RabbitMQ入门概念_第16张图片

3、 编写发送信息方法

注入ObjectMapper类将实体装换成json格式的数据进行发送 

RabbitMQ入门概念_第17张图片

 4、接受信息(消费者)

package com.ycxw.consumer.demos;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
@SuppressWarnings("all")
@Slf4j
@RabbitListener(queues = "secondQueue") //监听消息队列
public class Receiver2 {

    @Autowired
    private ObjectMapper objectMapper;

    //处理接受的信息
    @RabbitHandler
    public void process(String json) throws JsonProcessingException {
        //将接受的json数据转换成实体
        User ycxw = objectMapper.readValue(json, User.class);
        log.warn("接收到:" + ycxw);
    }
}

5、测试

消费者接受的信息

你可能感兴趣的:(RabbitMQ,+,Redis,rabbitmq,分布式,java,docker,spring,boot)