RabbitMQ 搭建和工作模式

news2024/11/14 23:19:31

MQ基本概念

1. MQ概述

MQ全称 Message Queue([kjuː])(消息队列),是在消息的传输过程中保存消息的容器。多用于分布式系统之间进行通信。

(队列是一种容器,用于存放数据的都是容器,存放消息的就是消息队列)

分布式系统的调用:

方式一:直接调用

order

product

account

方式二:间接调用

A将数据存放到中间一个系统,通过中间的系统发送到B

中间系统可以成为中间件MQ

生产者-》中间件《--消费者

MQ是用于存放消息的中间件

被调用者叫生产者 调用者是消费者(微服务中说过)

2. MQ的优势和劣势

1 优势

应用解耦:提高系统容错性和可维护性。

异步提速:提升用户体验和系统吞吐量。

削峰填谷:提高系统稳定性。

应用解耦

系统的耦合性越高,容错性就越低,可维护性就越低。

例:订单系统 的时候 依赖于库存系统 支付系统 物流系统 当库存系统发生异常,就有可能导致订单系统发生异常 下单失败

追加系统 x 就只能修改订单系统更改代码 导致维护性比较低

使用 MQ 使得应用间解耦,提升容错性和可维护性

库存系统宕机订单系统影响不大,因为消息已经发送到mq了当库存系统恢复的时候就可以正常使用了。

追加系统的时候跟订单系统无关

已将数据发送到MQ了,直接从MQ中拿就行了,无需更改订单中的代码,可维护性提高

异步提速

一个下单操作耗时:20 + 300 + 300 + 300 = 920ms

用户点击完下单按钮后,需要等待920ms才能得到下单响应,太慢!

用户点击完下单按钮后,只需等待25ms就能得到下单响应 (20 + 5 = 25ms)。

提升用户体验和系统吞吐量(单位时间内处理请求的数目)。

以前920ms处理一个请求,现在25ms处理一个请求,系统的吞吐量(单位时间内访问量)增加

削峰填谷(削峰)

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

使用MQ后,可以提高系统稳定性。

2 劣势

系统可用性降低

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

系统复杂度提高

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

一致性问题

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

既然 MQ 有优势也有劣势,那么使用 MQ 需要满足什么条件呢?

消费者--》生产者

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

订单->库存

  1. 容许短暂的不一致性。
  2. 确实是用了有效果。即解耦、提速、削峰这些方面的收益,超过加入MQ,管理MQ这些成本。

3. 常见的MQ产品

目前业界有很多的 MQ 产品,例如 RabbitMQ、RocketMQ、ActiveMQ、Kafka、ZeroMQ、MetaMq等,也有直接使用 Redis 充当消息队列的案例,而这些消息队列产品,各有侧重,在实际选型时,需要结合自身需求及 MQ 产品特征,综合考虑。

RabbitMQ基本介绍

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

消息队列中间件

exchange 交换机 分发消息 分发到不同的容器 queue 通过路由来处理

queue 容器

routes 路由

生产者 发布消息到exchange exchange 通过不同的路由规则发布/路由 给不同的queue 进行存储 cunsumer通过队列去监听拿到消息进行消费

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

1. RabbitMQ 基础架构

Broker 中间者 服务

procedure 和consumer都是客户端

客户端通过链接和服务端进行通信 所以需要建立起来连接 然后进行通信a

使用channel(管道)节省资源

一个rabbitmq里面有很多的虚拟机 相当于mysql里面有很多数据库,数据库里面有很多表,都是独立的。

每个虚拟机里面有很多的exchange和queue 独立分区的作用

2. 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)

fanout (multicast)

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

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

3. RabbitMQ的6 种工作模式

RabbitMQ 提供了 6 种工作模式:

简单模式、work queues、Publish/Subscribe 发布与订阅模式、Routing 路由模式、Topics 主题模式、RPC 远程调用模式(远程调用,不太算 MQ;暂不作介绍)。==

官网对应模式介绍:RabbitMQ Tutorials — RabbitMQ

4. AMQP 和 JMS

MQ是消息通信的模型;实现MQ的大致有两种主流方式:AMQP、JMS。

AMQP

AMQP是一种协议,更准确的说是一种binary wire-level protocol(链接协议)。这是其和JMS的本质差别,AMQP不从API层进行限定,而是直接定义网络交换的数据格式。

JMS

JMS即Java消息服务(Java Message Service)应用程序接口,是一个Java平台中关于面向消息中间件(MOM)的API,用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信。

(规定了消息客户端的一套api的东西,rabbitmq没有遵循规则)

JMS 是 JavaEE 规范中的一种,类比JDBC。

AMQP与 JMS 区别

JMS是定义了统一的接口,来对消息操作进行统一;AMQP是通过规定协议来统一数据交互的格式。

JMS限定了必须使用Java语言;AMQP只是协议,不规定实现方式,因此是跨语言的。

JMS规定了两种消息模式;而AMQP的消息模式更加丰富

再谈市场上常见的消息队列

ActiveMQ:基于JMS

ZeroMQ:基于C语言开发

RabbitMQ:基于AMQP协议,erlang语言开发,稳定性好

RocketMQ:基于JMS,阿里巴巴产品

Kafka:类似MQ的产品;分布式消息系统,高吞吐量。

RabbitMQ的安装和配置

安装依赖环境

在线安装依赖环境:

yum -y install build-essential openssl openssl-devel unixODBC unixODBC-devel make gcc gcc-c++ kernel-devel m4 ncurses-devel tk tc xz

安装Erlang

rpm -ivh erlang-22.0.7-1.el7.x86_64.rpm

安装RabbitMQ

rpm -ivh socat-1.7.3.2-2.el7.x86_64.rpm

安装rabbitmq

rpm -ivh rabbitmq-server-3.7.18-1.el7.noarch.rpm

启动RabbitMQ

systemctl start rabbitmq-server # 启动服务

systemctl stop rabbitmq-server # 停止服务

systemctl restart rabbitmq-server # 重启服务

systemctl status rabbitmq-server #查看状态

配置RabbitMQ

开启管理界面

rabbitmq-plugins enable rabbitmq_management

修改默认配置信息

vim /usr/lib/rabbitmq/lib/rabbitmq_server-3.7.18/ebin/rabbit.app 

修改后重启

打开客户端

192.168.221.37:15672

使用guest/guest登录之后出现如下即为安装成功

操作RabbitMQ

1)添加虚拟主机

2)添加用户

3)给用户分配虚拟主机

先清除

再分配

查看结果

分配成功

重新使用新用户登录

4)在MQ中添加发布消息

发送成功后

消费信息

搭建工程

添加jar包

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

添加消费者

public class MyTest {
    @Test
    public void aaa() throws IOException, TimeoutException {
        ConnectionFactory connectionFactory = new ConnectionFactory();
        //连接mq
        connectionFactory.setUsername("账号");
        connectionFactory.setPassword("密码");
        connectionFactory.setHost("IP地址");
        connectionFactory.setPort(端口号);
        connectionFactory.setVirtualHost("/***");
        //建立连接
        Connection connection = connectionFactory.newConnection();
        Channel channel = connection.createChannel();
      Consumer consumer = new DefaultConsumer(channel){
          @Override
          public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
              String s = new String(body);
              System.out.println("mq:"+s);
          }
      };
        channel.basicConsume("test",true,consumer);
    }
}

结果

添加生产者

public class MyTest {
    @Test
    public void bbb() throws IOException, TimeoutException {
        ConnectionFactory connectionFactory = new ConnectionFactory();
        //连接mq
        connectionFactory.setUsername("账号"); 
        connectionFactory.setPassword("密码");
        connectionFactory.setHost("IP地址");
        connectionFactory.setPort(端口号); 
        connectionFactory.setVirtualHost("/***");
        //建立连接
        Connection connection = connectionFactory.newConnection();
        Channel channel = connection.createChannel();
        /**
         * String queue, 队列的名称
         * boolean durable, 持久化
         * boolean exclusive, 是否独占
         * boolean autoDelete,  受否自动删除
         * Map<String, Object> arguments  参数
         */
        channel.queueDeclare("test",false,false,false,null);// 创建队列
        channel.basicPublish("","test",null,"hello mq1".getBytes());
    }
   }

发消息

RabbitMQ工作模式

官网对应模式介绍:RabbitMQ Tutorials — RabbitMQ

Work queues工作队列模式

 模式说明

Work Queues与入门程序的简单模式相比,多了一个或一些消费端,多个消费端共同消费同一个队列中的消息。

应用场景:对于 任务过重或任务较多情况使用工作队列可以提高任务处理的速度。

创建两个消费者

使用生产者发布消息

结果

订阅模式

添加交换机

创建队列

交换机绑定队列

在交换机中发布消息

关联队列都会发布

修改消费者监听不同队列 测试

创建两个消费者

创建交换机生产者
public class MyTestEx {
    @Test
    public void bbb() throws IOException, TimeoutException {
        ConnectionFactory connectionFactory = new ConnectionFactory();
        //连接mq
       connectionFactory.setUsername("账号");
       connectionFactory.setPassword("密码");
       connectionFactory.setHost("IP地址");
       connectionFactory.setPort(端口号);
       connectionFactory.setVirtualHost("/***");
        //建立连接
        Connection connection = connectionFactory.newConnection();
        Channel channel = connection.createChannel();
        //创建交换机
        channel.exchangeDeclare("myex1", BuiltinExchangeType.FANOUT,false);
        //创建队列
        /**
         * String queue, 队列的名称
         * boolean durable, 持久化
         * boolean exclusive, 是否独占
         * boolean autoDelete,  受否自动删除
         * Map<String, Object> arguments  参数
         */
        channel.queueBind("testmyex1",false,false,false,null);
        channel.queueBind("testmyex2",false,false,false,null);
        //绑定交换机
        channel.exchangeBind("testmyex1","myex1","");
        channel.exchangeBind("testmyex2","myex1","");
        channel.basicPublish("myex1","",null,"testex".getBytes());
    }
}

测试

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1243462.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【分布式】小白看Ring算法 - 03

相关系列 【分布式】NCCL部署与测试 - 01 【分布式】入门级NCCL多机并行实践 - 02 【分布式】小白看Ring算法 - 03 【分布式】大模型分布式训练入门与实践 - 04 概述 NCCL&#xff08;NVIDIA Collective Communications Library&#xff09;是由NVIDIA开发的一种用于多GPU间…

SQL进阶学习

1.[NISACTF 2022]join-us sql报错注入和联合注入 过滤&#xff1a; as IF rand() LEFT by updatesubstring handler union floor benchmark COLUMN UPDATE & sys.schema_auto_increment_columns && 11 database case AND right CAST FLOOR left updatexml DATABA…

CLion安装与配置教程

目录 一、下载并安装CLion1、下载1、官网&#xff1a;2、注意&#xff1a; 2、安装1、下载完成后&#xff0c;直接点击安装包安装&#xff0c;即可。2、开始安装&#xff0c;然后下一步3、可以在此处自定义地址&#xff0c;然后下一步4、根据系统版本选择&#xff0c;然后下一步…

Linux:虚拟机安装Ubuntu系统

一、下载Ubuntu 地址&#xff1a;https://cn.ubuntu.com/download/desktop 二、安装 以上配置完成后&#xff0c;点击完成按钮&#xff0c;接下来就是一段较长时间的等待安装过程。 安装完成后&#xff0c;还有一些系统性配置。 系统配置非常简单&#xff0c;全部next即可。…

开源 GPU池化软件 | (AI人工智能训练平台、AI人工智能推理平台)

GPU池化软件 | (AI人工智能训练平台、AI人工智能推理平台) 讨论群v:&#x1f680;18601938676 一、AI人工智能开发-------------面临的问题和挑战 1. GPU管理难题 1.1 资源管理难&#xff1a;算力资源昂贵&#xff0c;但是缺乏有效管理&#xff0c;闲置情况严重。 1.2 用户…

【uniapp】uniapp开发小程序定制uni-collapse(折叠面板)

需求 最近在做小程序&#xff0c;有一个类似折叠面板的ui控件&#xff0c;效果大概是这样 代码 因为项目使用的是uniapp&#xff0c;所以打算去找uniapp的扩展组件&#xff0c;果然给我找到了这个叫uni-collapse的组件&#xff08;链接&#xff1a;uni-collapse&#xff09…

Django 入门学习总结4

视图是Django应用程序在Python语言中提供特定的方法并对应于有特定的模板的网页。网页的页面通过视图的方式进行跳转。 在投票系统中&#xff0c;有四个视图&#xff1a; 首页视图&#xff0c;显示最新的问题列表。细节视图&#xff0c;显示问题文本&#xff0c;通过表单可以…

【标注数据】labelme的安装与使用

这里写目录标题 下载标数据 下载 标数据 打开自动保存 创建矩形

FreeRTOS的并行与并发思考

FreeRTOS的任务触发是由滴答时钟触发SysTick中断来触发调度器执行或阻塞或挂起和切换任务的。 首先是任务的并发能力&#xff0c;FreeRTOS的任务执行是基于全抢占调度机制&#xff0c;任务优先级按在就绪列表中由高到低排布&#xff0c;系统首先执行最高优先级任务&#xff0c;…

【element优化经验】怎么让element-ui中表单多语言切换排版不乱

目录 前言&#xff1a; 痛点&#xff1a; 1.左对齐&#xff0c;右对齐在中文和外语情况下字数不同&#xff0c;固定宽度会使名称换行&#xff0c;不在整行对齐&#xff0c;影响美观。 2.如果名称和输入框不在一行&#xff0c;会使页面越来越长 3.label-width值给变量&#…

Switch的使用及其注意事项

注意第五点要看清&#xff0c;case执行完后匹配没有成功&#xff0c;如过有Default&#xff0c;将会执行Default&#xff0c;如果有case在Default之后&#xff0c;而且Default没有break语句&#xff0c;那么将会继续执行case的语句&#xff0c;此时case中的常量表达式只起语句标…

鸿蒙(HarmonyOS)应用开发——ArkTs学习准备

介绍 前面我们已经介绍了&#xff0c;如何安装HarmonyOS的IDE ,那么现在我们来介绍一下。HarmonyOS 开发的语言——ArkTs. ArkTS 是HarmonyOS的开发语言&#xff0c;他是typescript 的扩展&#xff0c;而typesrcipt是javascript的超集&#xff0c;如果你不太熟悉typescript语法…

fork介绍,返回值问题,写时拷贝,进程切换,子进程开始执行的位置,子进程的用途

目录 fork 介绍 fork的返回值问题 介绍 fork()时,系统要做什么 数据是否要独立 如果共享的话,就会出现问题! 写时拷贝 引入 介绍 举例(fork返回值) fork返回的值是什么 创建失败的原因 子进程执行位置从哪里开始 引入 进程切换 子进程执行的位置 子进程的…

SAP-部分字段变更

在SAP中部分字段是可以自行调整的&#xff0c;例如下图 这个字段是客户组1&#xff0c;已经被改成一级经理&#xff0c;现在来操作改回客户组1 首先选择字段点击F1-技术信息-数据元素&#xff08;双击&#xff09; . . 保存&#xff0c;返回&#xff0c;激活&#xff0c;返…

计算方法 期末总结

思维导图 绪论 算法的性质&#xff1a; 有穷性、确切性、有输入输出、可行性 算法的描述方法&#xff1a; 自然语言、伪代码、流程图、N-S流程图 算法设计思想&#xff1a; 化大为小的缩减技术&#xff1a;二分法化难为易的校正技术&#xff1a;开方法化粗为精的松弛技术&a…

听GPT 讲Rust源代码--src/tools(2)

题图来自AI生成 File: rust/src/tools/rust-installer/src/util.rs 在Rust源代码中&#xff0c;rust/src/tools/rust-installer/src/util.rs文件是安装程序的一个辅助文件&#xff0c;它提供了一些实用函数和结构体来处理安装过程中需要的一些操作。 这个文件中定义了几个结构体…

本地websocket服务端暴露至公网访问【cpolar内网穿透】

本地websocket服务端暴露至公网访问【cpolar内网穿透】 文章目录 本地websocket服务端暴露至公网访问【cpolar内网穿透】1. Java 服务端demo环境2. 在pom文件引入第三包封装的netty框架maven坐标3. 创建服务端,以接口模式调用,方便外部调用4. 启动服务,出现以下信息表示启动成功…

香港科技大学广州|先进材料学域博士招生宣讲会—华中科技大学大学专场!!!(暨全额奖学金政策)

“跨学科融合创新&#xff0c;引领新兴与未来行业的突破与发展——先进材料学域” 世界一流的新型可持续材料创新研究 夯实的先进材料领域国际学术影响力 教授亲临现场&#xff0c;面对面答疑解惑助攻申请&#xff01; 一经录取&#xff0c;享全额奖学金1.5万/月&#xff01; …