RabbitMQ基础概念及工作模式的简单介绍

本文介绍了RabbitMQ中的MQ基础概念,分析了MQ在解耦、异步处理和流量控制等方面的优势,同时指出其可能带来的系统可用性、复杂性和一致性挑战。文章还探讨了使用MQ的条件,并详细讲解了RabbitMQ的六种工作模式:简单模式、Work Queues、Pub/Sub、Routing、Topics,最后进行了总结。
摘要由CSDN通过智能技术生成

RabbitMQ中的MQ是什么?

MQ全称Message Queue(消息队列),是在消息的传输过程中保存消息的容器。多用于分布式系统之间的通信。发送方称为生产者,接收方称为消费者。
请添加图片描述

MQ的优势和劣势

请添加图片描述

优势:

1.应用解耦

在这里插入图片描述
在这里插入图片描述

2.异步提速

在这里插入图片描述
在这里插入图片描述

3.削峰填谷

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
使用了MQ之后,限制消费消息的速度为1000,这样一来,高峰期产生的数据势必会被积压在MQ中,高峰就被“削”掉了,但是因为消息积压,在高峰期过后的一段时间内,消费消息的速度还是会维持在1000,直到消费完积压的消息,这就叫做“填谷”。
使用MQ后,可以提高系统稳定性。

劣势:

在这里插入图片描述

1.系统可用性降低

系统引入的外部依赖越多,系统稳定性越差。一旦MQ宕机,就会对业务造成影响。如何保证MQ的高可用?

2.系统复杂度提高

MQ的加入大大增加了系统的复杂度,以前系统间是同步的远程调用,现在是通过MQ进行异步调用。如何保证消息没有被重复消费?怎么处理消息丢失情况?那么保证消息传递的顺序性?

3.一致性问题

A系统处理完业务,通过MQ给B、C、D三个系统发消息数据,如果B系统、C系统处理成功,D系统处理失败。如何保证消息数据处理的一致性?

使用MQ的满足条件

1.生产者不需要从消费者处获得反馈。引入消息队列之前的直接调用,其接口的返回值应该为空,这才让明明下层的动作还没做,上层却当成动作做完了继续往后走,即所谓异步成为了可能。

2.容许短暂的不一致性。

3.确实是用了有效果。即解耦、提速、削峰这些方面的收益,超过加入MQ,管理MQ这些成本。

常见的MQ

在这里插入图片描述

RabbitMQ简介

发展史

AMQP,即 Advanced Message Queuing Protocol(高级消息队列协议),是一个网络协议,是应用层协议的一个开放标准,为面向消息的中间件设计。基于此协议的客户端与消息中间件可传递消息,并不受客户端/中间件不同产品,不同的开发语言等条件的限制。2006年,AMQP规范发布。类比HTTP。

2007年,Rabbit 技术公司基于AMQP标准开发的RabbitMQ 1.0发布。RabbitMQ采用Erlang 语言开发。Erlang 语言由Ericson设计,专门为开发高并发和分布式系统的一种语言,在电信领域使用广泛。

RabbitMQ架构图
在这里插入图片描述

JMS的概念

JMS即Java消息服务(JavaMessage Service)应用程序接口,是一个Java平台中关于面向消息中间件的API
JMS是 JavaEE规范中的一种,类比JDBC
很多消息中间件都实现了JMS规范,例如:ActiveMQ。RabbitMQ官方没有提供JMS的实现包,但是开源社区有

RabbitMQ相关概念

Broker:
接收和分发消息的应用,RabbitMQ Server就是 Message Broker

Virtual host:
出于多租户和安全因素设计的,把AMQP的基本组件划分到一个虚拟的分组中,类似于网络中的namespace概念。当多个不同的用户使用同一个RabbitMQ server提供的服务时,可以划分出多个vhost,每个用户在自己的vhost创建exchange / queue等

Connection:
publisher / consumer和broker之间的TCP连接

Channel:
如果每一次访问RabbitMQ都建立一个Connection,在消息量大的时候建立TCP Connection的开销将是巨大的,效率也较低。Channel是在connection内部建立的逻辑连接,如果应用程序支持多线程,通常每个thread创建单独的channel进行通讯,AMQP method包含了channel id帮助客户端和message broker识别 channel,所以channel之间是完全隔离的。Channel作为轻量级的Connection极大减少了操作系统建立TCP connection的开销

Exchange:
message到达 broker的第一站,根据分发规则,匹配查询表中的routing key,分发消息到queue 中去。常用的类型有: direct(point-to-point), topic (publish-subscribe) and fanout (multicast)

Queue:
消息最终被送到这里等待consumer取走

Binding:
exchange和queue 之间的虚拟连接,binding 中可以包含 routing key。Binding 信息被保存到exchange 中的查询表中,用于message 的分发依据

RabbitMQ的六种工作模式

RabbitMQ提供了6种工作模式:简单模式、work queues、Publish/Subscribe 发布与订阅模式、Routing路由模式、Topics主题模式、RPC远程调用模式(远程调用,不太算MQ)。

1.简单模式

在这里插入图片描述
P:生产者,也就是要发送消息的程序
C:消费者:消息的接收者,会一直等待消息到来
queue:消息队列,图中红色部分。类似一个邮箱,可以缓存消息;生产者向其中投递消息,消费者从其中取出消息

生产者:

依赖:

    <dependencies>
        <!--rabbit java客户端-->
        <dependency>
            <groupId>com.rabbitmq</groupId>
            <artifactId>amqp-client</artifactId>
            <version>5.6.0</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

生产者代码:

public class ProducerHelloWorld {
   
    public static void main(String[] args) throws IOException, TimeoutException {
   
        //1.创建连接工厂
        ConnectionFactory factory = new ConnectionFactory();

        //2.设置参数
        factory.setHost("106.15.50.230");   //ip,默认localhost
        factory.setPort(5672);  //端口 默认5672
        factory.setVirtualHost("/myvh");    //虚拟机 默认/
        factory.setUsername("hzh"); //用户名 默认guest
        factory.setPassword("hzh"); //密码 默认guest

        //3.创建连接 Connection
        Connection connection = factory.newConnection();

        //4.创建 Channel
        Channel channel = connection.createChannel();

        //5.创建队列
        /**
         * queueDeclare(String queue, boolean durable, boolean exclusive, boolean autoDelete, Map<String, Object> arguments)
         * 参数:
         * 1.queue:队列名称
         * 2.durable:是否持久化,当目前重启后,还在
         * 3.exclusive:
         *      是否独占,即只有一个消费者监听端口
         *      当Connection关闭时,是否删除队列
         * 4.autoDelete:是否自动删除,在没有Consumer时自动删除队列
         * 5.arguments:参数
         */
        //若没有同名的队列,则会创建,否则不会创建
        channel.queueDeclare("hello_world",true,false,false,null);

        //6.发送消息
        String body = "hello rabbitmq~";
        /**
         * basicPublish(String exchange, String routingKey, BasicProperties props, byte[] body)
         * 参数:
         * 1.exchange:交换机名称。简单模式下实参使用""表示使用默认的交换机AMQP
         * 2.routingKey:路由的名称
         * 3.props:配置信息
         * 4.body:发送的消息数据
         */
                            //使用默认的交换机时,routingKey需要和队列的名称一样才能路由到对应的队列
        channel.basicPublish("","hello_world",null,body.getBytes());

        //7.释放资源
        channel.close();
        connection.close();
    }
}

消费者:

依赖:

    <dependencies>
        <!--rabbit java客户端-->
        <dependency>
            <groupId>com.rabbitmq</groupId>
            <artifactId>amqp-client</artifactId>
            <version>5.6.0</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

消费者代码:

public class ConsumerHelloWorld {
   
    public static void main(String[] args) throws IOException, TimeoutException {
   
        //1.创建连接工厂
        ConnectionFactory factory = new ConnectionFactory();

        //2.设置参数
        factory.setHost("106.15.50.230");   //ip,默认localhost
        factory.setPort(5672);  //端口 默认5672
        factory.setVirtualHost("/myvh");    //虚拟机 默认/
        factory.setUsername("hzh"); //用户名 默认guest
        factory.setPassword("hzh"); //密码 默认guest

        //3.创建连接 Connection
        Connection connection = factory.newConnection();

        //4.创建 Channel
        Channel channel = connection.createChannel();

        //5.创建队列
        /**
         * queueDeclare(String queue, boolean durable, boolean exclusive, boolean autoDelete, Map<String, Object> arguments)
         * 参数:
         * 1.queue:队列名称
         * 2.durable:是否持久化,当目前重启后,还在
         * 3.exclusive:
         *      是否独占,即只有一个消费者监听端口
         *      当Connection关闭时,是否删除队列
         * 4.autoDelete:是否自动删除,在没有Consumer时自动删除队列
         * 5.arguments:参数
         */
        //若没有同名的队列,则会创建,否则不会创建
        channel.queueDeclare("hello_world",true,false,false,null);

        //6.消费消息
        Consumer consumer = new DefaultConsumer(channel){
   
            /*
                回调方法,当收到消息后,会自动执行该方法
                参数:
                    consumerTag:标识
                    envelope:通过此参数可以获取一些信息,如交换机,路由key。。。
                    properties:配置文件
                    body:消息数据
             */
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
   
                System
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值