RabbitMQ从入门到精通

RabbitMQ学习

遵循tcp/ip协议,互通性

跨平台

介绍

为什么需要使用消息中间件

具体地说,中间件屏蔽了底层操作系统的复杂性,使程序开发人员面对一个简单而统一的开发环境,减少程序设计的复杂性,将注意力集中在自己的业务上,不必再为程序在不同系统软件上的移植而重复工作,从而大大减少了技术上的负担。中间件带给应用系统的,不只是开发的简便、开发周期的缩短,也减少了系统的维护、运行和管理的工作量,还减少了计算机总体费用的投入。

中间件特点

为解决分布异构问题,人们提出了中间件(middleware)的概念。中间件是位于平台(硬件和操作系统)和应用之间的通用服务,如下图所示,这些服务具有标准的程序接口和协议。针对不同的操作系统和硬件平台,它们可以有符合接口和协议规范的多种实现。

安装RabbitMQ

官网:https://www.rabbitmq.com/

什么是RabbitMQ,官方给出来这样的解释

RabbitMQ是部署最广泛的开源消息代理。
RabbitMQ拥有成千上万的用户,是最受欢迎的开源消息代理之一。从T-Mobile 到Runtastic,RabbitMQ在全球范围内的小型初创企业和大型企业中都得到使用。
RabbitMQ轻巧,易于在内部和云中部署。它支持多种消息传递协议。RabbitMQ可以部署在分布式和联合配置中,以满足大规模,高可用性的要求。
RabbitMQ可在许多操作系统和云环境上运行,并为大多数流行语言提供了广泛的开发人员工具。

简单概述:
RabbitMQ是一个开源的遵循AMQP协议实现的基于Erlang语言编写,支持多种客户端(语言)。用于在分布式系统中存储消息,转发消息,具有高可用,高可扩性,易用性等特征。

https://www.erlang.org/


什么是消息中间件

消息中间件基于队列模型实现异步/同步传输数据

作用:可以实现支撑高并发、异步解耦、流量削峰、降低耦合度。

传统的http请求存在那些缺点

1.Http请求基于请求与响应的模型,在高并发的情况下,客户端发送大量的请求达到

服务器端有可能会导致我们服务器端处理请求堆积。

2.Tomcat服务器处理每个请求都有自己独立的线程,如果超过最大线程数会将该请求缓存到队列中,如果请求堆积过多的情况下,有可能会导致tomcat服务器崩溃的问题。

所以一般都会在nginx入口实现限流,整合服务保护框架。

3.http请求处理业务逻辑如果比较耗时的情况下,容易造成客户端一直等待,阻塞等待

过程中会导致客户端超时发生重试策略,有可能会引发幂等性问题。

注意事项:接口是为http协议的情况下,最好不要处理比较耗时的业务逻辑,耗时的业务逻辑应该单独交给多线程或者是mq处理。


MQ应用场景

  1. 异步发送短信

  2. 异步发送新人优惠券

  3. 处理一些比较耗时的操作

MQ与多线程之间的关系

  • MQ可以实现异步/解耦/流量削峰问题;
  • 多线程也可以实现异步,但是消耗到cpu资源,没有实现解耦。

MQ消息中间件名词

  • Producer 生产者:投递消息到MQ服务器端;
  • Consumer 消费者:从MQ服务器端获取消息处理业务逻辑;
  • Broker MQ服务器端
  • Topic 主题:分类业务逻辑发送短信主题、发送优惠券主题
  • Queue 存放消息模型 队列 先进先出 后进后出原则 数组/链表
  • Message 生产者投递消息报文:json
docker run -d --restart=always --hostname rabbit-host --name rabbitmq001 -e RABBITMQ_DEFAULT_USER=user -e RABBITMQ_DEFAULT_PASS=password -p 15672:15672 -p 5672:5672 rabbitmq:3.7.7-management
user/password

特性ActiveMQRabbitMQRocketMQkafka
开发语言javaerlangjavascala
单机吞吐量万级万级10万级10万级
时效性ms级us级ms级ms级以内
可用性高(主从架构)高(主从架构)非常高(分布式架构)非常高(分布式架构)
功能特性成熟的产品,在很多公司得到应用;有较多的文档;各种协议支持较好基于erlang开发,所以并发能力很强,性能极其好,延时很低管理界面较丰富MQ功能比较完备,扩展性佳只支持主要的MQ功能,像一些消息查询,消息回溯等功能没有提供,毕竟是为大数据准备的,在大数据领域应用广。

生产者投递消息给MQ服务器端,MQ服务器端需要缓存该消息

如果mq服务器端宕机之后,消息如何保证不丢失

  1. 持久化机制

如果mq接收到生产者投递消息,如果消费者不在的情况下,该消息是否会丢失?

不会丢失,消息确认机制 必须要消费者消费该消息成功之后,在通知给mq服务器端

删除该消息。

Mq服务器端将该消息推送消费者:

消费者已经和mq服务器保持长连接。

消费者主动拉取消息:

消费者第一次刚启动的时候

Mq如何实现抗高并发思想

Mq消费者根据自身能力情况 ,拉取mq服务器端消息消费。

默认的情况下是取出一条消息。

缺点:存在延迟的问题

需要考虑mq消费者提高速率的问题:

如何消费者提高速率:消费者实现集群、消费者批量获取消息即可。


什么是netty

就是将客户端和服务器端进行通讯


RabbitMQ

基本介绍

RabbitMQ是实现了高级消息队列协议(AMQP)的开源消息代理软件(亦称面向消息的中间件),RabbitMQ服务器是用Erlang语言编写的。

RabitMQ官方网站:

https://www.rabbitmq.com/

  1. 点对点(简单)的队列
  2. 工作(公平性)队列模式
  3. 发布订阅模式
  4. 路由模式Routing
  5. 通配符模式Topics
  6. RPC

https://www.rabbitmq.com/getstarted.html

RabbitMQ环境的基本安装

1.下载并安装erlang,下载地址:http://www.erlang.org/download

2.配置erlang环境变量信息

 新增环境变量ERLANG_HOME=erlang的安装地址

 将%ERLANG_HOME%\bin加入到path中

3.下载并安装RabbitMQ,下载地址:http://www.rabbitmq.com/download.html

注意: RabbitMQ 它依赖于Erlang,需要先安装Erlang。

https://www.rabbitmq.com/install-windows.html

net start RabbitMQ

启动Rabbitmq常见问题

如果rabbitmq 启动成功无法访问 管理平台页面 

进入到F:\path\rabbitmq\rabbitmq\rabbitmq_server-3.6.9\sbin>

执行

rabbitmq-plugins enable rabbitmq_management

rabbitmqctl start_app


Windows控制台指令

netstat -ano:查看端口占用情况
netstat -ano | findstr xxxx:查看某个端口被占用情况        //xxxx为查询的端口号
tasklist | findstr xxxx:查看使用指定端口的应用程序   //xxxx指的是pid
taskkill /pid xxxx -t -f    //xxxx指的是pid
或者:taskkill /f /t /im QQ.exe:结束指定进程

Rabbitmq管理平台中心

RabbitMQ 管理平台地址 http://127.0.0.1:15672

默认账号:guest/guest 用户可以自己创建新的账号

Virtual Hosts:

像mysql有数据库的概念并且可以指定用户对库和表等操作的权限。那RabbitMQ呢?

RabbitMQ也有类似的权限管理。在RabbitMQ中可以虚拟消息服务器VirtualHost,每

个VirtualHost相当月一个相对独立的RabbitMQ服务器,每个VirtualHost之间是相互

隔离的。exchange、queue、message不能互通。

默认的端口15672:rabbitmq管理平台端口号

默认的端口5672: rabbitmq消息中间内部通讯的端口
默认的端口号25672 rabbitmq集群的端口号

RabbitMQ常见名词

/Virtual Hosts—分类

/队列 存放我们消息

Exchange 分派我们消息在那个队列存放起来 类似于nginx

15672—rabbitmq控制台管理平台 http协议

25672rabbitmq 集群通信端口号

Amqp 5672 rabbitmq内部通信的一个端口号


使用RabbitMq需要导入的依赖

<dependencies>
    <dependency>
        <groupId>com.rabbitmq</groupId>
        <artifactId>amqp-client</artifactId>
        <version>3.6.5 </version>
    </dependency>
</dependencies>

创建RabbitMQ的步骤

  1. 在RabbitMQ平台创建一个队列
  2. 编写生产者代码
  3. 编写消费者代码

点对点通信


创建连接

public class RabbitMQConection {
    //获取连接
    public static Connection getConnection() throws IOException, TimeoutException {
        ConnectionFactory connectionFactory = new ConnectionFactory();
        //1.设置连接 virtualHost 分类
        connectionFactory.setVirtualHost("/chenVirtualHost");
        //2.设置账号和密码
        connectionFactory.setUsername("guest");
        connectionFactory.setPassword("guest");
        //3.MQ连接消息地址
        connectionFactory.setHost("127.0.0.1");
        connectionFactory.setPort(5672);
        return connectionFactory.newConnection();
    }

}

创建生产者

public class Producer {
    private static final String QUEUE_NAME="chen-queues";
    public static void main(String[] args) throws IOException, TimeoutException {
        //获取到连接
        Connection connection = RabbitMQConection.getConnection();
        //创建通道
        Channel channel = connection.createChannel();
        //创建要发送的信息
        String msg="你好,小七";
        //通过通道发送消息  投放信息到哪一个队列中
        channel.basicPublish("",QUEUE_NAME,null,msg.getBytes());
        //3.关闭通道和连接 先开后关
        channel.close();
        connection.close();
    }
}

创建消费者

public class Consumer {
    private static final String QUEUE_NAME = "chen-queues";

    public static void main(String[] args) throws IOException, TimeoutException {
        // 1.创建连接
       Connection connection = RabbitMQConection.getConnection();
        // 2.设置通道
        Channel channel = connection.createChannel();
        DefaultConsumer defaultConsumer = new DefaultConsumer(channel) {
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                String msg = new String(body, "UTF-8");
                System.out.println("消费者获取消息:" + msg);
            }
        };
        // 3.监听队列  自动签收  手动签收模式
        channel.basicConsume(QUEUE_NAME, true, defaultConsumer);

    }
}


RabbitMQ如何保证信息不丢失

Mq如何保证消息不丢失:

1.生产者角色

确保生产者投递消息到MQ服务器端成功。

Ack 消息确认机制

同步或者异步的形式

方式1:Confirms

方式2:事务消息

2.消费者角色

在rabbitmq情况下:

必须要将消息消费成功之后,才会将该消息从mq服务器端中移除。

在kafka中的情况下:

不管是消费成功还是消费失败,该消息都不会立即从mq服务器端移除。

3.Mq服务器端 在默认的情况下 都会对队列中的消息实现持久化

 持久化硬盘。

1.使用消息确认机制+持久技术

A.消费者确认收到消息机制 

channel.basicConsume(QUEUE_NAME, false, defaultConsumer);

注:第二个参数值为false代表关闭RabbitMQ的自动应答机制,改为手动应答。

在处理完消息时,返回应答状态,true表示为自动应答模式。

channel.basicAck(envelope.getDeliveryTag(), false);

B.生产者确认投递消息成功 使用Confirm机制 或者事务消息



RabbitMQ交换机类型

Direct exchange(直连交换机)

Fanout exchange(扇型交换机)

Topic exchange(主题交换机)

Headers exchange(头交换机)

/Virtual Hosts—区分不同的团队

----队列 存放消息

----交换机 路由消息存放在那个队列中 类似于nginx

—路由key 分发规则

RabbitMQ Fanout发布订阅

生产者发送一条消息,经过交换机转发到多个不同的队列,多个不同的队列就多个不同的消费者。

原理:

  1. 需要创建两个队列 ,每个队列对应一个消费者;

  2. 队列需要绑定我们交换机

  3. 生产者投递消息到交换机中,交换机在将消息分配给两个队列中都存放起来;

  4. 消费者从队列中获取这个消息。

Direct路由模式

当交换机类型为direct类型时,根据队列绑定的路由建转发到具体的队列中存放消息

Topic主题模式

当交换机类型为topic类型时,根据队列绑定的路由建模糊转发到具体的队列中存放。

#号表示支持匹配多个词

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值