0
点赞
收藏
分享

微信扫一扫

Pycharm2023.1安装及其破解(含安装包)

胡桑_b06e 2024-08-08 阅读 38

文章目录

瑞&3l




1 初识MQ

  微服务一旦拆分,必然涉及到服务之间的相互调用,目前我们服务之间调用采用的都是基于 OpenFeign 的调用。这种调用中,调用者发起请求后需要等待服务提供者执行业务返回结果后,才能继续执行后面的业务。也就是说调用者在调用过程中处于阻塞状态,因此我们成这种调用方式为同步调用,也可以叫同步通讯。但在很多场景下,我们可能需要采用异步通讯的方式,为什么呢?

  我们先来看看什么是同步通讯和异步通讯。如图

image.png

【解读】
  • 同步通讯:就如同打视频电话,双方的交互都是实时的。因此同一时刻你只能跟一个人打视频电话。
  • 异步通讯:就如同发微信聊天,双方的交互不是实时的,你不需要立刻给对方回应。因此你可以多线操作,同时跟多人聊天。

  两种方式各有优劣,打电话可以立即得到响应,但是你却不能跟多个人同时通话。发微信可以同时与多个人收发微信,但是往往对方回复不及时导致响应延迟。

  所以

  • 如果我们的业务需要实时得到服务提供方的响应,则应该选择同步通讯(同步调用)
  • 如果我们追求更高的效率,并且不需要实时响应,则应该选择异步通讯(异步调用)

1.1 同步调用

1.1.1 同步调用的优势
  • 时效性强
      等待到结果才返回
1.1.2 同步调用的缺点
  • 拓展性差
      一旦有功能变更,需要修改业务代码

  • 性能下降
      调用链路越长,那同步阻塞等待就会导致性能变差,微服务调用越多,性能越差

  • 级联失败问题
      一个服务挂了,这个链路上的服务全部会出现问题


  基于 OpenFeign 的调用属于是同步调用,这种方式存在的问题如【余额支付功能

  首先看下整个流程,如下图所示⬇️

  以上流程采用的是基于 OpenFeign 的同步调用,业务执行流程如下⬇️

  1️⃣ 支付服务需要先调用用户服务完成余额扣减

  2️⃣ 然后支付服务自己要更新支付流水单的状态

  3️⃣ 然后支付服务调用交易服务,更新业务订单状态为已支付

  三个步骤依次同步执行,这样就存在3个问题

  第一拓展性差

  目前上述的业务相对简单,但是随着业务规模扩大,产品的功能也在不断完善。在大多数电商业务中,用户支付成功后都会以短信或者其它方式通知用户,告知支付成功。假如后期产品经理提出这样新的需求,你怎么办?是不是要在上述业务中再加入通知用户的业务?

  某些电商项目中,还会有积分或金币的概念。假如产品经理提出需求,用户支付成功后,给用户以积分奖励或者返还金币,你怎么办?是不是要在上述业务中再加入积分业务、返还金币业务?

  最终你的支付业务会越来越臃肿,如下⬇️

  每当有新需求时,现有支付逻辑都要跟着变化,代码需要改动,不符合开闭原则(对扩展开放,对修改关闭),拓展性不好。

  第二性能下降

  由于我们采用了同步调用,调用者需要等待服务提供者执行完返回结果后,才能继续向下执行,也就是说每次远程调用,调用者都是阻塞等待状态。最终整个业务的响应时长就是每次远程调用的执行时长之和

  假如每个微服务的执行时长都是 50ms,则最终整个业务的耗时可能高达 300ms,性能太差了。

  第三,级联失败

  由于我们是基于 OpenFeign 调用交易服务、通知服务。当交易服务、通知服务出现故障时,整个事务都会回滚,交易失败。这其实就是同步调用的级联失败问题。

  总不能因为短信通知、更新订单状态失败、积分增长失败等后续的业务逻辑执行失败而回滚整个事务

  综上,同步调用的方式存在下列问题

  • 拓展性差
  • 性能下降
  • 级联失败

  而要解决这些问题,我们就必须用异步调用的方式来代替同步调用

1.2 异步调用

1.2.1 异步调用的角色

  异步调用方式其实就是基于消息通知的方式,一般包含以下三个角色

  1️⃣ 消息发送者:投递消息的人,就是原来同步服务的调用方(生产者)

  2️⃣ 消息 Broker:管理、暂存、转发消息,你可以把它理解成微信服务器(消息代理)

  3️⃣ 消息接收者:接收和处理消息的人,就是原来的同步服务的提供方(消费者)

  在异步调用中,发送者不再直接同步调用接收者的业务接口,而是发送一条消息投递给消息 Broker。然后接收者根据自己的需求从消息 Broker 那里订阅消息。每当发送方发送消息后,接受者都能获取消息并处理。

  这样,发送消息的人和接收消息的人就完全解耦了


  还是以余额支付业务为例,除了扣减余额、更新支付流水单状态以外,其它同步调用逻辑全部取消。而是改为发送一条消息到 Broker。而相关的微服务都可以订阅消息通知,一旦消息到达 Broker,则会分发给每一个订阅了的微服务,处理各自的业务。

  假如产品经理冒出了新的想法,给你提出了新的需求,比如要添加积分系统,即要在支付成功后更新用户积分。此时支付代码完全不用变更,而仅仅是让积分服务也订阅消息即可,如下⬇️

  不管后期增加了多少消息订阅者,作为支付服务来讲,执行问扣减余额、更新支付流水状态后,发送消息即可。业务耗时仅仅是这三部分业务耗时,仅仅 100ms,大大提高了业务性能。

  另外,不管是交易服务、通知服务,还是积分服务,他们的业务与支付关联度低。现在采用了异步调用,解除了耦合,他们即便执行过程中出现了故障,也不会影响到支付服务,只要保证最终一致性就行。

1.2.2 异步调用的优势

  综上,异步调用的优势如下

  • 解除耦合,拓展性强
      只需要发消息到 Broker,后续如果要添加业务,其它业务只需要自行订阅相关消息即可

  • 无需等待,性能好
      发完消息,直接服务结束,无需等待异步调用服务的执行时间

  • 故障隔离,避免级联失败
      异步调用服务失败抛异常不影响消息发送者

  • 缓存消息,流量削峰填谷
      流量削峰填谷是在高并发场景下平滑系统负载,避免因瞬间高流量导致系统崩溃的技术策略。这种策略广泛应用于电商秒杀、大规模促销活动等场景,能够有效平衡上下游系统的负载差异,提高系统的稳定性和可靠性。

在这里插入图片描述

1.2.3 异步调用的缺点

  当然,异步通信也并非完美无缺,存在下列缺点⬇️

  • 不能立即得到调用结果,时效性差
  • 不确定下游业务执行是否成功
  • 业务完全依赖于 Broker 的可靠性、安全性和性能
  • 架构复杂,后期维护和调试麻烦
1.2.4 异步调用的场景
  • 对异步调用的结果不关心,如发送通知、记录日志、执行后台任务等操作。
  • 调用链非常长的业务中,一般会改造成异步调用的方式

1.3 MQ技术选型

  MQ(MessageQueue),中文是消息队列,如同字面上的意思就是存放消息的队列。也就是异步调用中的 Broker 角色,目比较常见的 MQ 实现如下

  • ActiveMQ
  • RabbitMQ
  • RocketMQ
  • Kafka

  以上 MQ 的对比

RabbitMQActiveMQRocketMQKafka
公司/社区RabbitApache阿里Apache
开发语言ErlangJavaJavaScala&Java
协议支持AMQP,XMPP,SMTP,STOMPOpenWire,STOMP,REST,XMPP,AMQP自定义协议自定义协议
可用性高(主从架构)高(主从架构)非常高(分布式架构)非常高(分布式架构)
单机吞吐量一般(万级)差 (万级)高 (十万级)非常高(百万级)
消息延迟微秒级(us级)毫秒级(ms级)毫秒级(ms级)毫秒以内(ms级以内)
消息可靠性一般一般
功能特性基于Erlang开发,所以并发能力很强,性能极其好,延时很低;管理界面较丰富成熟的产品,在很多公司得到应用,有较多的文档;各种协议支持较好MQ功能比较完备,扩展性佳只支持主要的MQ功能,像一些消息查询、消息回溯等功能没有提供,是为大数据准备的,在大数据领域应用广
  • 追求可用性:Kafka、 RocketMQ 、RabbitMQ
  • 追求可靠性:RabbitMQ、RocketMQ
  • 追求吞吐能力:RocketMQ、Kafka
  • 追求消息低延迟:RabbitMQ、Kafka

  RabbitMQ 是基于 Erlang 语言开发的开源消息通信中间件,性能好,Erlang 语言是面向并发的语言;协议支持丰富,符合微服务理念,Spring 官方默认支持 RabbitMQ ;支持集群,可用性高;单机吞吐量(并发能力)十万二十万左右的样子,但已经满足大多数企业级应用需求;消息延迟在毫秒级;需要消息确认,消息可靠性高。

  Kafka 适用于吞吐量需求很高的场景中,如日志搜集,但由于其消息不可靠,可能存在数据丢失的情况。

  据统计,大厂基本上是使用自研,而中小型企业消息队列使用最多的是 RabbitMQ,因为其各方面都比较均衡,稳定性也好。至于 RocketMQ 由于是阿里的产品,而阿里每年向外输出大量的人才,这些人才流入到中小型企业中,会优先选择去使用 RocketMQ ,但具数据统计 RabbitMQ 在国内还是更受欢迎。

2 RabbitMQ

  RabbitMQ的官网地址:Messaging that just works — RabbitMQ

2.1 安装

  本文是基于 Docker 来安装 RabbitMQ

2.1.1 资源准备

  如果是内网中开发或拉取镜像困难,请准备好以下资源,如果您的设备可以连接互联网,则可以直接开始安装

链接:https://pan.baidu.com/s/1tBRud60ExkPXcOBsr7R_rA?pwd=sm4u 
提取码:sm4u

  将mq.tar上传至root目录下,执行以下命令加载镜像

cd /root
docker load -i mq.tar

在这里插入图片描述

2.1.2 安装步骤

  执行以下命令进行安装

docker run \
 -e RABBITMQ_DEFAULT_USER=ray \
 -e RABBITMQ_DEFAULT_PASS=123456 \
 -v mq-plugins:/plugins \
 --name mq \
 --hostname mq \
 -p 15672:15672 \
 -p 5672:5672 \
 -d \
 rabbitmq:3.8-management
【命令解读】
  • -e RABBITMQ_DEFAULT_USER=ray
      设置 RabbitMQ 用户名为:ray

  • -e RABBITMQ_DEFAULT_PASS=123456
      设置 RabbitMQ 密码为:123456

  • -v mq-plugins:/plugins
      挂载数据卷 mq-plugins 对应容器内目录 plugins

  • --name mq
      容器名为:mq

  • --hostname mq
      主机名为:mq

  • -p 15672:15672
      端口映射,表示将本机的 15672 端口映射到 RabbitMQ 镜像的 15672 端口

  • -p 5672:5672
      端口映射,表示将本机的 5672 端口映射到 RabbitMQ 镜像的 5672 端口

  • docker run -d
      创建并运行一个容器,-d则是让容器以后台进程运行

  在安装命令中有两个映射的端口

  • 15672:RabbitMQ 提供的管理控制台的端口
  • 5672:RabbitMQ 的消息发送处理接口

在这里插入图片描述

  如上图所示,安装完成后,访问 http://192.168.133.131:15672即可看到管理控制台(记得 IP 要替换为你虚拟机的 IP)

  首次访问需要登录,默认的用户名和密码在 docker run 中指定了,博主的用户名为:ray,密码为:123456

  登录成功后即可看到管理控制台总览页面

在这里插入图片描述


RabbitMQ 安装完成

2.2 RabbitMQ架构

  RabbitMQ 对应的架构如下图所示

image.png

  其中包含几个概念:

  • publisher:生产者,也就是发送消息的一方
  • consumer:消费者,也就是消费消息的一方
  • queue:队列,存储消息。生产者投递的消息会暂存在消息队列中,等待消费者处理
  • exchange:交换机,负责消息路由。生产者发送的消息由交换机决定投递到哪个队列。
  • virtual host:虚拟主机,起到数据隔离的作用。每个虚拟主机相互独立,有各自的exchange、queue

  上述这些东西都可以在 RabbitMQ 的管理控制台来管理。

2.3 RabbitMQ管理控制台收发消息


RabbitMQ 的管理控制台入门小案例——收发消息

  【需求】在 RabbitMQ 的控制台完成下列操作

2.3.1 创建队列
  • 新建队列 hello.queue1 和 hello.queue2

  1️⃣ 点击导航栏中的Queues,选择Add a new queue,在Name中输入 hello.queue1,点击Add queue即可添加队列,hello.queue2 同理添加

在这里插入图片描述

  2️⃣ 添加成功后如下图

在这里插入图片描述

2.3.2 交换机绑定队列★
  • 将刚刚创建的 hello.queue1 和 hello.queue2 队列绑定到默认的 amp.fanout 交换机

  1️⃣ 点击Exchanges,鼠标单击选中amp.fanout交换机

在这里插入图片描述

  2️⃣ 点击Bindings,在To queue中输入或选择 hello.queue1 ,点击Bind进行绑定,hello.queue2 同理绑定

在这里插入图片描述

  3️⃣ 绑定完成后如下图所示

在这里插入图片描述

  4️⃣ 到Queues中查看Bindings中是否绑定了交换机amp.fanout

在这里插入图片描述

2.3.3 交换机发送消息
  • 向默认的 amp.fanout 交换机发送一条消息

  1️⃣ 点击Exchanges,鼠标单击选中amp.fanout交换机进入交换机详情页面,然后点击Publish message,在Payload中输入要发送的消息,如“hello every queue!”,然后点击Publish message,会有提示框提示“Message published”,点击Close即可

在这里插入图片描述

  2️⃣ 在Overview中查看消息发送情况,如下图所示

在这里插入图片描述

2.3.4 查看消息接收
  • 查看消息是否到达 hello.queue1 和 hello.queue2

  1️⃣ 点击导航栏中的Queues,查看队列消息接收情况,如下图所示

在这里插入图片描述

  2️⃣ 选中 hellp.queue1 ,进入队列管理界面,展开Get messages,点击Get Message(s)按钮,查看交换机发送的消息内容

在这里插入图片描述

2.4 数据隔离

  在 RabbitMQ 中存在 virtual host 即虚拟主机的概念,交换机和队列都有自己所属的虚拟主机,以此实现数据隔离的效果。

2.4.1 用户管理

  点击Admin选项卡,会看到 RabbitMQ 控制台的用户管理界面 Users

在这里插入图片描述

  这些用户都是 RabbitMQ 的管理或运维人员。目前只有安装 RabbitMQ 时添加的ray这个用户。用户表格中的字段,如下:

  • Nameray,也就是用户名
  • Tagsadministrator,说明ray用户是超级管理员,拥有所有权限
  • Can access virtual host/,可以访问的virtual host,这里的/是默认的virtual host

  对于小型企业而言,出于成本考虑,通常只会搭建一套 MQ 集群,公司内的多个不同项目同时使用。这个时候为了避免互相干扰, 会利用virtual host的隔离特性,将不同项目隔离。一般会做两件事情:

  • 给每个项目创建独立的运维账号,将管理权限分离。
  • 给每个项目创建不同的virtual host,将每个项目的数据隔离。

  比如给黑马商城项目创建一个新的用户,名为hmall,密码为123456,标签选择adminadministrator超级管理员权限

在这里插入图片描述

  此时会发现 hmall 用户没有任何virtual host的访问权限

在这里插入图片描述

  别急,接下来我们就来为 hmall 进行授权操作

2.4.2 virtual host 用户授权

  1️⃣ 先点击页面右上角的Log out退出登录

在这里插入图片描述

  2️⃣ 切换到刚刚创建的 hmall 用户登录,在Admin标签页中点击Virtual Hosts菜单,进入virtual host管理页

在这里插入图片描述

  可以看到目前只有一个默认的virtual host,名字为 /

  3️⃣ 给黑马商城项目创建一个单独的virtual host,而不是使用默认的/,展开Add a new virtual host

在这里插入图片描述

  4️⃣ 创建完成后如下图所示

在这里插入图片描述

  由于我们是登录hmall账户后创建的virtual host,因此回到users菜单,你会发现当前用户已经具备了对/hmall这个virtual host的访问权限了

在这里插入图片描述

  5️⃣ 点击页面右上角的virtual host下拉菜单,切换virtual host/hmall

在这里插入图片描述

在这里插入图片描述

  6️⃣ 切换virtual host/hmall后,查看Queues选项卡,会发现之前的队列已经看不到了

在这里插入图片描述

  这就是基于virtual host 的隔离效果




本文是博主的粗浅理解,可能存在一些错误或不完善之处,如有遗漏或错误欢迎各位补充,谢谢

  如果觉得这篇文章对您有所帮助的话,请动动小手点波关注💗,你的点赞👍收藏⭐️转发🔗评论📝都是对博主最好的支持~


举报

相关推荐

0 条评论