面试篇:SpringCloud

 一、SpringCloud常见的组件有什么?

1、常见微服务功能架构图

2、阿里巴巴SpringCloud常用组件 

  • 注册中心/配置中心:Nacos
  • 负载均衡:Ribbon
  • 服务调用:Feign
  • 服务保护:Sentinel
  • 服务网关:Gateway

二、服务注册和发现是什么意思? Spring Cloud 如何实现服务注册发现? 

1、Eureka的作用

如上图,order-service为服务的消费者,user-service为服务的提供者,那么user-service需要将自己的信息如ip地址以及端口号上传的eureka-server注册中心,注册中心保存着user-service的ip和端口信息。

因为order-service也可能被其他服务调用,所以也会上传到注册中心。这样注册中心就保存了两个微服务的IP和端口号。

order-service会定期的从注册中心拉取信息,将其保存到自己服务的本地中,这样就可以通过feign和使用Ribbon利用负载均衡实现对某一实例的远程调用。

user-service会30秒发送一次心跳给注册中心,当user-service中的某一台服务宕机的时候,并且注册中心90秒内未收到心跳,那么就会认为某一台实例宕机了,就会从注册中心中删除宕机的实例。并且user-service会定期从注册中心拉取服务信息,更新自己的本地信息表。

2、服务注册和发现是什么意思? Spring Cloud 如何实现服务注册发现?

  • 我们当时项目采用的eureka作为注册中心,这个也是spring cloud体系中的一个核心组件
  • 服务注册:服务提供者需要把自己的信息注册到eureka,由eureka来保存这些信息,比如服务名称、ip、端口等等
  • 服务发现:消费者向eureka拉取服务列表信息,如果服务提供者有集群,则消费者会利用负载均衡算法,选择一个发起调用
  • 服务监控:服务提供者会每隔30秒向eureka发送心跳,报告健康状态,如果eureka服务90秒没接收到心跳,从eureka中剔除

 3、nacos与eureka的区别?

首先是nacos的流程:

  • 服务分为服务的消费者和服务的提供者,服务的提供者和服务的消费者通过心跳监测机制将当前服务的IP和端口号上传到nacos注册中心,这样nacos就拥有了各服务的IP和端口号。
  • 服务消费者会定期从注册中心拉取服务信息,如IP和端口号。注册中心会根据心跳来进行健康监测,并且维护注册中心给的信息。
  • 因此在设置ephemeral:false之前,和eureka一模一样。当设置的ephemeral:false就会有所不同。

不同:

  • 当设置了ephemeral:false那么注册中心就会主动查询服务的提供者,看有没有实例宕机。
  • 如果有实例宕机那么就会将实例宕机的信息主动推送给调用这个服务的服务消费者,服务消费者立马就可以更新自己的本地信息。这样就可以更加的及时。

4、 我看你之前也用过nacos、你能说下nacos与eureka的区别?

Nacos与eureka的共同点 (注册中心)

  • 都支持服务注册和服务拉取
  • 都支持服务提供者心跳方式做健康检测

Nacos与Eureka的区别 (注册中心)

  • Nacos支持服务端主动检测提供者状态:临时实例采用心跳模式,非临时实例采用主动检测模式
  • 临时实例心跳不正常会被剔除,非临时实例则不会被剔除
  • Nacos支持服务列表变更的消息推送模式,服务列表更新更及时
  • Nacos集群默认采用AP方式,当集群中存在非临时实例时,采用CP模式Eureka采用AP方式

Nacos还支持了配置中心,eureka则只有注册中心,也是选择使用nacos的一个重要原因

三、 你们项目负载均衡如何实现的?

1、Ribbon负载均衡流程

首先是order-service调用user-service。那么就会通过url地址发起请求,在这个请求的中间会调用Feign这个组件(内置Ribbon),Feign会从注册中心拉取user-service的IP地址和端口号,然后注册中心会将user-service的IP地址和端口号返回给Feign,这样Feign就知道了user-service的IP地址和端口号。Feign里面内置了Ribbon,因此根据不同的策略进行对user-service的远程调用。Ribbon默认为轮询策略。

2、Ribbon负载均衡策略有哪些?

  • RoundRobinRule: 简单轮询服务列表来选择服务器
  • WeightedResponseTimeRule: 按照权重来选择服务器,响应时间越长,权重越小
  • RandomRule: 随机选择一个可用的服务器
  • ZoneAvoidanceRule: 以区域可用的服务器为基础进行服务器的选择。使用Zone对服务器进行分类,这个Zone可以理解为一个机房、一个机架等。而后再对Zone内的多个服务做轮询

3、如果想自定义负载均衡策略如何实现?

可以自己创建类实现IRule接口,然后再通过配置类或者配置文件配置即可,通过定义IRule实现可以修改负载均衡规则,有两种方式:

  • 全局生效:对于order-service远程调用的所有服务都是用的是RandomRule。被调用方使用
  • 局部生效:对于调用user-service的服务使用的是RandomRule。调用方使用

四、服务雪崩,熔断降级

1、什么是服务雪崩,怎么解决这个问题?

如果在某一时刻,服务B出现故障(可能就卡在那里了),而这时服务A依然有大量的请求,在调用服务B,那么,由于服务A没办法再短时间内完成处理,新来的请求就会导致线程数不断地增加,这样,CPU的资源很快就会被耗尽。那么就会出现服务雪崩。

2、服务的降级

部分服务不可以

如上图,如果正常调用失败的话,那么就会采用备用的回答来返回结果。

3、Sentinel的熔断

所有服务不可以

如上图,为服务熔断的流程。根据熔断策略,当服务调用失败到一定的次数,就会触发熔断机制,首先打开熔断器,所有请求全部降级处理。当熔断时间结束(Sentinel和Hystrix相同),会尝试进行放行一次请求查看是否成功,如果失败就继续全部降级处理,直到成功后关闭熔断。

4、Sentinel的熔断策略

慢调用比例

判定为慢调用条件:一次请求的响应时间超过最大RT值,那么就是慢调用。

即:在一个统计时长内,如果请求数目大于最小请求数目,并且被判定为慢调用的请求比例已经超过阈值,将触发熔断

如上图,如果在1000ms内,当请求超过1次请求,并且请求时间超过500ms占每1次请求的100%就会触发5秒熔断 

异常比例

如上图,在1秒内当每2次请求中异常比例达到1的时候 ,那么就会触发5秒熔断时间。

异常数

如上图,在1秒内当每2次请求中异常数为1的时候 ,那么就会触发5秒熔断时间。

5、概括

什么是服务雪崩,怎么解决这个问题?

  • 服务雪崩:一个服务失败,导致整条链路的服务都失败的情形
  • 服务降级:服务自我保护的一种方式,或者保护下游服务的一种方式,用于确保服务不会受请求突增影响变得不可用,确保服务不会崩溃,一般在实际开发中与feign接口整合,编写降级逻辑
  • 服务熔断:默认关闭,需要手动打开,如果检测到 10 秒内请求的失败率超过 50%,就触发熔断机制。之后每隔5 秒重新尝试请求微服务,如果微服务不能响应,继续走熔断机制。如果微服务可达,则关闭熔断机制,恢复正常请求

五、微服务的监控SkyWalking 

六、RabbitMQ如何保证消息不丢失

1、RabbitMQ消息丢失的三种情况

  • 第一种:生产者弄丢了数据。生产者将数据发送到 RabbitMQ 的时候,可能数据就在半路给搞丢了,因为网络问题啥的,都有可能。
  • 第二种:RabbitMQ 弄丢了数据。MQ还没有持久化自己挂了
  • 第三种:消费端弄丢了数据。刚消费到,还没处理,结果进程挂了,比如重启了。

 2、RabbitMQ消息丢失解决方法

3、生产者方案: 使用confirm机制  

事务机制和 confirm 机制最大的不同在于,事务机制是同步的,你提交一个事务之后会阻塞在那儿,但是 confirm 机制是异步的。

RabbitMQ支持消费者确认机制,即: 消费者处理消息后可以向MQ发送ack回执,MQ收到ack回执后才会删除该消息,而SpringAMQP则允许配置三种确认模式:

  • manual:手动ack,需要在业务代码结束后,调用api发送ack。
  • auto: 自动ack;由spring监测listener代码是否出现异常,没有异常则返回ack;抛出异常则返回。
  • nacknone: 关闭ack,MQ假定消费者获取消息后会成功处理,因此消息投递后立即被删除。

在生产者开启了confirm模式之后,每次写的消息都会分配一个唯一的id,然后如果写入了rabbitmq之中,rabbitmq会给你回传一个ack消息,告诉你这个消息发送OK了;如果rabbitmq没能处理这个消息,会回调你一个nack接口,告诉你这个消息失败了,你可以进行重试。而且你可以结合这个机制知道自己在内存里维护每个消息的id,如果超过一定时间还没接收到这个消息的回调,那么你可以进行重发。

对于如何重发消息有以下方法:

  • 回调方法即时重发
  • 保存到数据库然后定时重发,成功发送后即刻删除表中的数据

4、MQ方案

使用消息持久化来解决RabbitMQ弄丢了数据这个问题。

要想做到消息持久化,必须满足以下三个条件,缺一不可:

  • 交换机(Exchange) 设置持久化。
  • 队列(Queue) 设置持久化。
  • 消息(Message)持久化发送:发送消息设置发送模式deliveryMode=2,代表持久化消息。

5、消费者方案:ACK确认机制

多个消费者同时收取消息,比如消息接收到一半的时候,一个消费者死掉了(逻辑复杂时间太长,超时了或者消费被停机或者网络断开链接),如何保证消息不丢?

有三种确认方式:

  • 自动确认:acknowledge=“none” 默认方式
  • 手动确认:acknowledge=“manual”
  • 根据异常情况确认:acknowledge=“auto”

其中自动确认是指,当消息一旦被Consumer接收到,则自动确认收到,并将相应 message 从 RabbitMQ 的消息缓存中移除。

但是在实际业务处理中,很可能消息接收到,业务处理出现异常,那么该消息就会丢失。如果设置了手动确认方式,则需要在业务处理成功后,调用channel.basicAck(),手动签收,如果出现异常,则调用channel.basicNack()方法,让其自动重新发送消息。

七、RabbitMQ消息的重复消费问题如何解决的?

造成重复消费的原因:

  • 网络抖动
  • 消费者挂了

如上图,当consumer将队列中的消息并处理以后准备发送确认ACK的时候,突然宕机了,导致队列没有收到ACK,消费过的消息没有在队列中删除。但是由于有重试机制,导致consumer再次从队列中获取消息,这样就会导致重复消费。

解决方法:

  • 每个消息设置一个唯一的ID标识,如支付id,订单id等。
    • 当consumer将队列中的消息并处理以后准备发送确认ACK的时候,突然宕机了,导致队列没有收到ACK,消费过的消息没有在队列中删除。但是由于有重试机制,导致consumer再次从队列中获取消息。但是由于有唯一标识,当恢复宕机以后,就重新获取队列消费过的消息,拿到消息以后然后在数据库中进行判断,比如订单id,如果数据库有该订单id就返回ACK,删除队列中的消息,如果没有就进行处理。
  • 幂等方案:分布式锁、数据库锁(悲观锁、乐观锁)

八、RabbitMQ中死信交换机?RabbitMQ延迟队列?

延迟队列=死信交换机+TTL 

延迟队列:进入队列的消息会被延迟消费的队列

场景:超时订单、限时优惠、定时发布

 

如上图,应用场景为超时订单,这个时候可以使用延时队列来处理。当下完订单以后,然后将消息发送给延时队列,30分钟以后该消息才可以被支付系统获取去检查是否成功支付。

1、私信交换机

当一个队列中的消息满足下列情况之一时,可以成为死信 (dead letter)

  • 消费者使用basicreject或 basic.nack声明消费失败,并且消息的requeue参数设置为false
  • 消息是一个过期消息,超时无人消费
  • 要投递的队列消息堆积满了,最早的消息可能成为死信

如果该队列配置了dead-leter-exchange属性,指定了一个交换机,那么队列中的死信就会投递到这个交换机中,而这个交换机称为死信交换机(Dead Letter Exchange,简称DLX)。

 

如上图,当生产者发布一条消息给交换机并路由到另一个队列的时候,由于消费者拒绝了该消息,就会导致该消息成为死信不能被消费只能进入私信交换机路由到死信队列让其他消费者消费该消息。 

2、TTL存活时间

TTL,也就是Time-To-Live。如果一个队列中的消息TTL结束仍未消费,则会变为死信,tl超对分为两种情况:

  • 消息所在的队列设置了存活时间。
  • 消息本身设置了存活时间。

 

如上图,生产者发布了一条消息,这个消息的存活时间为5000ms,但是消息队列也设置了存活时间为10000ms,由于RabbitMQ规定二者谁的存活时间短就以谁为准。当TTL到期以后,然后消息回进入死信交换机路由到死信队列,与死信队列绑定的消费者就会消费这条消息。

九、RabbitMQ如果有100万消息堆积在MQ,如何解决(消息堆积怎么解决) ?

如上图,当生产者发送消息的速度超过了消费者处理消息的速度,就会导致队列中的消息堆积,直到队列存储消息达到上限。之后发送的消息就会成为死信,可能会被丢弃,这就是消息堆积问题。

1、解决消息堆积有三种种思路

  • 增加更多消费者,提高消费速度
  • 在消费者内开启线程池加快消息处理速度(受CPU的限制)
  • 扩大队列容积,提高堆积上限(受磁盘的限制)

对于扩大队列的容积,使用的是惰性队列

2、惰性队列的特征

  • 接收到消息后直接存入磁盘而非内存
  • 消费者要消费消息时才会从磁盘中读取并加载到内存
  • 支持数百万条的消息存储 

 十、RabbitMQ的高可用机制

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Compose Desktop 实战 宝可梦图鉴

Compose Desktop 实战 宝可梦图鉴 前言 阅读本文需要一定compose基础,如果没有请移步Jetpack Compose入门详解(实时更新) 接口数据来源于pokeapi 项目源代码 如果你觉得不错,请给我一个star,THKS 实现效果 闲话不…

php通过cURL爬取数据(3):CURLINFO_HTTP_CODE返回0的排查和解决方案

CURLINFO_HTTP_CODE返回0的排查和解决方案 一、curl本地服务器需要DNS解析域名二、如何排查错误原因三、无法解析 DNS的程序升级方案四、宝塔配置DNS的操作方法1.etc/resolv.conf2.通过GUI界面 一、curl本地服务器需要DNS解析域名 在使用 curl 命令发送请求到域名地址&#xf…

测试(二)

1.软件测试的生命周期 需求分析→测试计划→ 测试设计→ 测试开发→ 测试执行→ 测试评估 2.如何描述一个Bug 3.Bug的优先级 1、Blocker(崩溃): 阻碍开发或测试工作的问题;造成系统崩溃、死机、死循环,导致数据库数…

Unity基础 视频组件VideoPlayer,视频的播放与控制

在Unity中,视频播放功能具有广泛的应用,以下是一些视频播放在Unity中的常见用途: 游戏引入和过场动画:使用视频播放可以在游戏开始或过场动画中添加引人注目的视频,为游戏制造氛围和引起玩家的兴趣。这种方式可以通过播…

CSS基础学习--11 padding(填充)

一、定义 CSS padding(填充)是一个简写属性,定义元素边框与元素内容之间的空间,即上下左右的内边距。 当元素的 padding(填充)内边距被清除时,所释放的区域将会受到元素背景颜色的填充。 单独使…

Linux运维监控学习笔记1

1. 监控系统的概念: 监控系统,将所有需要监控的服务器及其各种各种需要的状态数据都实时地收集,并图形化地展示,并可以进行报警,让机器主动及时地与人沟通。 2. 为什么要监控? 答:实时地收集数…

kubernetes(k8s)理论篇

注意:kubeadm与docker是有版本要求的。 如果版本不兼容,初始化 kubeadm是会出现以下问题。 学习k8s掌握知识 基础概念 什么是 Pod 控制器类型 K8S 网络通讯模式 Kubernetes 构建 K8S 集群 资源清单 资源 掌握资源清单的语法 编写 Pod 掌握 Pod 的…

JVM知识点整理

JVM 回收哪个区域?关联面试题:fullgc会回收方法区(元空间)吗? 怎么判断对象可以被回收了关联面试题:哪些对象可以作为 GC Root (两栈两方法) JVM GC什么时候执行?分代回收机制思考&…

docker容器启动的问题 - docker容器和虚拟机的比较 - docker的底层隔离机制

目录 一、docker容器启动的问题? 二、什么是docker仓库? 三、虚拟机和docker容器的区别: docker的优势: docker的缺点: 对比: 四、docker的底层隔离机制 参考文献:LXC linux容器简介——…

图像 检测 - CenterNet: Objects as Points (arXiv 2019)

CenterNet: Objects as Points - 目标作为点(arXiv 2019) 摘要1. 引言2. 相关工作3. 准备工作4. 目标作为点4.1 3D 检测4.2 人体姿态估计 5. 实施细节6. 实验6.1 目标检测6.1.1 附加实验 6.2 3D 检测6.3 姿态估计 7. 结论References附录A:模型…

【C数据结构】动态顺序表_SeqList

目录 【1】数据结构概述 【1.1】什么是数据结构? 【1.2】数据结构分类 【1.3】数据结构术语 【2】数据结构特点 【2】动态顺序表 【2.1】动态顺序表定义数据结构和接口 【2.1】动态顺序表创建初始化 【2.2】动态顺序表初始化 【2.3】动态顺序表内存释放 【…

mac电脑储存内存越来越小如何清理释放空间?

如果你是一位Mac系统的用户,可能会发现你的电脑储存空间越来越小。虽然Mac系统设计得非常优秀,但是系统数据和垃圾文件也会占据大量的储存空间。在这篇文章中,我们将探讨mac系统数据怎么这么大,以及mac清理系统数据怎么清理。 一…

万字详解常用设计模式

本文是博主在工作中对常用设计模式的使用经验总结归纳而来分享给大家。 设计模式一共有23种,本文讲解涉及如下: 责任链模式 模板方法模式 发布订阅模式 策略模式 三大分类 业界一般将设计模式分为三大类: 创建型模式:对类的实…

5、产品经理的工作职责OR主要工作技能和工具

1、产品经理的工作职责 我们通过一个案例来了解产品经理的工作职责。 老板让你给他点餐,你应该怎么做?你需要考虑哪一些方面的问题? 例如:你预算多少,预算是十块钱还是100块还是1000块。有没有忌口,口味…

Kafka详解(一)

第1章 Kafka概述 1.1 定义 1.2 消息队列 目前企业中比较常见的消息队列产品主要有Kafka、ActiveMQ、RabbitMQ、RocketMQ等。Message Queue ② 在大数据场景主要采用Kafka作为消息队列 ② 在JavaEE开发中主要采用ActiveMQ、RabbitMQ、RocketMQ Kafka存储数据,且保证…

「网络编程」第一讲:初识网络_网络基础1

「前言」文章是关于网络编程方面的,今天内容大致是网络基础,讲解下面开始! 「归属专栏」网络编程 「笔者」枫叶先生(fy) 「座右铭」前行路上修真我 「枫叶先生有点文青病」 「每篇一句」 青山不改,绿水长流 ——白居易 目录 一、…

新手快速搭建springboot项目

一、创建项目 1.1、创建项目 1.2、配置编码 1.3、取消无用提示 1.4、取消无用参数提示 二、添加POM父依赖 <!-- 两种方式添加父依赖或者import方式 --> <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-p…

微信小程序触底加载scroll-view

微信小程序触底加载 scroll-view 了解什么是触底加载&#xff1f; 需求&#xff1a;有个固定高度的容器&#xff0c;实现容器里面的内容触底加载 1、内容盒子的高度 2、盒子里内容的总高度 3、滚动条的scrollTop 触底加载的原理就是 当里面的容器触底的时候进行分页&#xff0…

Ansible-playbook-roles安装lnmp

使用roles安装lnmp 1、准备四台主机 192.168.142.10 192.168.142.20 192.168.142.30 192.168.142.40 2、10作为ansible管理端 首先ssh连接剩下三台主机 3、vim/etc/ansible/hosts 添加[nginxservers]配置nginx ip,[phpservers]php ip,[mysqlservers]mysql ip 4、cd /etc/ansibl…

0基础学习VR全景平台篇第42篇:编辑器底部菜单-分组管理

大家好&#xff0c;欢迎观看蛙色VR官方系列——后台使用课程&#xff01; 本期为大家带来蛙色VR平台&#xff0c;底部菜单—分组管理功能操作。 功能位置示意 一、本功能将用在哪里&#xff1f; 分组管理&#xff0c;指观看者可点击不同分组&#xff0c;查看不同类型全景内容…