代码编织梦想

(这是黑马微服务篇最后一个作业,以下所有总结都是照搬大佬的,可以给学完微服务想要过一遍知识点的朋友借鉴借鉴,大家如果还有觉得比较总要的知识点也可以分享到评论区)

- SpringCloud有哪些常用组件?分别是什么作用?

答:Nacos, OpenFeign, Sentinel,Seata,RabbitMQ,Gateway

Nacos: 服务注册中心,提供服务注册和发现功能

OpenFeign: 实现远程调用

Sentinel: 提供服务容错保护

Seata: 实现分布式事务管理

RabbitMQ: 实现异步通知

Gateway:(API网关服务):作用:安全,路由,限流,监控

- 服务注册发现的基本流程是怎样的?

答: - 服务启动时就会注册自己的服务信息(服务名、IP、端口)到注册中心

- 调用者可以从注册中心订阅想要的服务,获取服务对应的实例列表(1个服务可能多实例部署)

- Eureka和Nacos有哪些区别?

答: Nacos与Eureka的区别

1.Nacos支持服务端主动检测提供者状态: 临时实例采用心跳模式,非临时实例采用主动检测模式

2.临时实例心跳不正常会被剔除,非临时实例则不会被剔除

3.Nacos支持服务列表变更的消息推送模式,服务列表更新更及时

4.Nacos集群默认采用AP方式,但也支持CP;Eureka采用AP方式

- Nacos的分级存储模型是什么意思?

答:

任何一个微服务的实例在注册到Nacos时,都会生成以下几个信息,用来确认当前实例的身份,从外到内依次是:

namespace:命名空间

group:分组

service:服务名

cluster:集群

instance:实例,包含ip和端口

这就是nacos中的服务分级模型。

- OpenFeign是如何实现负载均衡的?

答:

Spring在整合OpenFeign的时候,实现org.springframework.cloud.openfeign.loadbalancer.FeignBlockingLoadBalancerClient类,其中定义了OpenFeign发起远程调用的核心流程。也就是四步:

- 获取请求中的serviceId

- 根据serviceId负载均衡,找出一个可用的服务实例

- 利用服务实例的ip和port信息重构url

- 向真正的url发起请求

而具体的负载均衡则是不是由OpenFeign组件负责。而是分成了负载均衡的接口规范,以及负载均衡的具体实现两部分。

负载均衡的接口规范是定义在Spring-Cloud-Common模块中,包含下面的接口:

- LoadBalancerClient:负载均衡客户端,职责是根据serviceId最终负载均衡,选出一个服务实例

- ReactiveLoadBalancer:负载均衡器,负责具体的负载均衡算法

OpenFeign的负载均衡是基于Spring-Cloud-Common模块中的负载均衡规则接口,并没有写死具体实现。这就意味着以后还可以拓展其它各种负载均衡的实现。

不过目前SpringCloud中只有Spring-Cloud-Loadbalancer这一种实现。

Spring-Cloud-Loadbalancer模块中,实现了Spring-Cloud-Common模块的相关接口,具体如下:

- BlockingLoadBalancerClient:实现了LoadBalancerClient,会根据serviceId选出负载均衡器并调用其算法实现负载均衡。

- RoundRobinLoadBalancer:基于轮询算法实现了ReactiveLoadBalancer

- RandomLoadBalancer:基于随机算法实现了ReactiveLoadBalancer,

- 什么是服务雪崩,常见的解决方案有哪些?

答:

- 线程池隔离:给每个服务调用业务分配一个线程池,利用线程池本身实现隔离效果

- 信号量隔离:不创建线程池,而是计数器模式,记录业务使用的线程数量,达到信号量上限时,禁止新的请求

- Hystix和Sentinel有什么区别和联系?

答:

无论是Hystix还是Sentinel都支持线程隔离。不过其实现方式不同。

Hystix默认是基于线程池实现的线程隔离,每一个被隔离的业务都要创建一个独立的线程池,线程过多会带来额外的CPU开销,性能一般,但是隔离性更强.支持主动超时和异步调用,适用场景为低扇出

Sentinel则是基于信号量隔离的原理,这种方式不用创建线程池,性能较好,但是隔离性一般.不支持主动超时和异步调用,使用场景为高频调用和高扇出

Sentinel的线程隔离就是基于信号量隔离实现的,而Hystix两种都支持,但默认是基于线程池隔离。

- 限流的常见算法有哪些?

答:

固定窗口计算器算法

固定窗口计数器算法概念如下

将时间划分为多个窗口,窗口时间跨度称为Interval,本例中为1000ms

每个窗口分别计数统计,每有一次请求就将计数器加一,限流就是设置计数器阈值,本例为3

如果计数器超过了限流阈值,则超出阈值的请求都被丢弃

滑动窗口算法(默认区间数量是2,区间数越多,计数器越多,压力越大)Sentinel

滑动窗口计数器算法会将一个窗口划分为n个更小的区间,例如

窗口时间跨度Interval为1秒;区间数量n=2,则每个小区间时间跨度为500ms,每个区间都有计数器

限流阈值依然为3,时间窗口(1秒)内请求超过阈值时,超出的请求被限流

窗口会根据当前请求所在时间(currentTime)移动,窗口范围是从(currentTime-Interval)之后的第一个时区开始,到currentTime

限流之后(滑动窗口算法后,默认方案是快速拒绝:抛出异常,失败)

其他方案:

漏桶算法

将每个请求视作"水滴"放入"漏桶"进行存储

"漏桶"以固定速率向外"漏"出请求来执行,如果"漏桶"空了则停止"漏水"

如果"漏桶"满了则多余的"水滴"会被直接丢弃

可以理解成请求在桶内排队等

令牌桶算法

以固定的速率生成令牌,存入令牌桶中,如果令牌桶满了以后,停止生成

请求进入后,必须先尝试从桶中获取令牌,获取到令牌后才可以被处理

如果令牌桶中没有令牌,则请求等待或丢弃

- 什么是CAP理论和BASE思想?

答:

1998年,加州大学的计算机科学家Eric Brewer提出,分布式系统有三个指标:

Consistency(一致性): 用户访问分布式系统中的任意节点,得到的数据必须一致

Availability(可用性): 用户访问分布式系统时,读或写操作总能成功.只能读不能写,或者只能写不能读,或者两者都不执行,就说明系统弱可用或不可用

Partition tolerance(分区容错性): 因为网络故障或其他原因导致分布式系统中的部分节点与其它节点失去连接,形成独立分区, 系统要能容忍网络分区现象,出现分区时,整个系统也要持续对外提供服务

他说,分布式系统无法同时满足这三个指标

这个结论就叫做CAP定理

BASE理论是对CAP的一种解决思路,包含三个思想:

Basically Available(基本可用): 分布式系统在出现故障时,允许算是部分可用性,即保证核心可用

Soft State(软状态): 在一定时间内,允许出现中间状态,比如临时的不一致状态

Eventually Consistent(最终一致性): 虽然无法保证强一致性,但是在软状态结束后,最终达到数据一致

- 项目中碰到过分布式事务问题吗?怎么解决的?

答:

分布式事务最大的问题是各个子事务的一致性问题,因此可以借鉴CAP定理和BASE理论:

CP模式: 各个子事务执行后互相等待,同时提交,同时回滚,达成强一致.但事务等待过程中,处于弱可用状态

AP模式: 各个事务分别执行和提交,允许出现结果不一致,然后采用弥补措施恢复数据即可,实现最终一致.

- AT模式如何解决脏读和脏写问题的?

答:

AT模式也分为两个阶段

第一阶段是记录数据快照,执行并提交事务

第二阶段根据阶段一的结果来判断:

- 如果每一个分支事务都成功,则事务已经结束(因为阶段一已经提交),因此删除阶段一的快照即可

- 如果有任意分支事务失败,则需要根据快照恢复到更新前数据。然后删除快照

这种模式在大多数情况下(99%)并不会有什么问题,不过在极端情况下,特别是多线程并发访问AT模式的分布式事务时,有可能出现脏写问题

解决思路就是引入了全局锁的概念。在释放DB锁之前,先拿到全局锁。避免同一时刻有另外一个事务来操作当前数据。

- TCC模式与AT模式对比,有哪些优缺点

答:

TCC模式的每个阶段是做什么的?

Try: 资源检查和预留

Confirm: 业务执行和提交

Cancel: 预留资源的释放

TCC的优点是什么?

一阶段完成直接提交事务,释放数据库资源,性能好

相比AT模型,无需生成快照,无需使用全局锁,性能最强

不依赖数据库,而是依赖补偿操作,可以用于非事务型数据库

TCC的缺点是什么?

有代码侵入,需要人为编写try,Confirm和Cancel接口,太麻烦

软状态,事务是最终一致

需要考虑Confirm和Cancel的失败情况,做好幂等处理

- RabbitMQ是如何确保消息的可靠性的?

答:

1.首先第一种情况,就是生产者发送消息时,出现了网络故障,导致与MQ的连接中断。

生产者重试机制:

为了解决这个问题,SpringAMQP提供的消息发送时的重试机制。即:当RabbitTemplate与MQ连接超时后,多次重试。

2.在少数情况下,也会出现消息发送到MQ之后丢失的现象

生产者确认机制:

RabbitMQ提供了生产者消息确认机制,包括Publisher Confirm和Publisher Return两种。在开启确认机制的情况下,当生产者发送消息给MQ后,MQ会根据消息处理的情况返回不同的回执。

3.消息到达MQ以后,如果MQ不能及时保存,也会导致消息丢失,所以MQ的可靠性也非常重要。

数据持久化:

为了提升性能,默认情况下MQ的数据都是在内存存储的临时数据,重启后就会消失。为了保证数据的可靠性,必须配置数据持久化,包括:- 交换机持久化 - 队列持久化 - 消息持久化

4.为了确认消费者是否成功处理消息,RabbitMQ提供了消费者确认机制(Consumer Acknowledgement)。即:当消费者处理消息结束后,应该向RabbitMQ发送一个回执,告知RabbitMQ自己消息处理状态。回执有三种可选值:

- ack:成功处理消息,RabbitMQ从队列中删除该消息

- nack:消息处理失败,RabbitMQ需要再次投递消息

- reject:消息处理失败并拒绝该消息,RabbitMQ从队列中删除该消息

5.当消费者出现异常后,消息会不断requeue(重入队)到队列,再重新发送给消费者。如果消费者再次执行依然出错,消息会再次requeue到队列,再次投递,直到消息处理成功为止.

失败重试机制:在消费者出现异常时利用本地重试,而不是无限制的requeue到mq队列。

在yml文件上配置retry:enabled: true

- 开启本地重试时,消息处理过程中抛出异常,不会requeue到队列,而是在消费者本地重试

- 重试达到最大次数后,Spring会返回reject,消息会被丢弃

6.本地测试达到最大重试次数后,消息会被丢弃。这在某些对于消息可靠性要求较高的业务场景下,显然不太合适了。

失败处理策略:

因此Spring允许我们自定义重试次数耗尽后的消息处理策略,这个策略是由MessageRecovery接口来定义的,它有3个不同 实现:

- RejectAndDontRequeueRecoverer:重试耗尽后,直接reject,丢弃消息。默认就是这种方式

- ImmediateRequeueMessageRecoverer:重试耗尽后,返回nack,消息重新入队

- RepublishMessageRecoverer:重试耗尽后,将失败消息投递到指定的交换机

- RabbitMQ是如何解决消息堆积问题的?

答:

在默认情况下,RabbitMQ会将接收到的信息保存在内存中以降低消息收发的延迟。但在某些特殊情况下,这会导致消息积压,比如:

- 消费者宕机或出现网络故障

- 消息发送量激增,超过了消费者处理速度

- 消费者处理业务发生阻塞

一旦出现消息堆积问题,RabbitMQ的内存占用就会越来越高,直到触发内存预警上限。此时RabbitMQ会将内存消息刷到磁盘上,这个行为成为PageOut. PageOut会耗费一段时间,并且会阻塞队列进程。因此在这个过程中RabbitMQ不会再处理新的消息,生产者的所有请求都会被阻塞。

为了解决这个问题,从RabbitMQ的3.6.0版本开始,就增加了Lazy Queues的模式,也就是惰性队列。惰性队列的特征如下:

- 接收到消息后直接存入磁盘而非内存

- 消费者要消费消息时才会从磁盘中读取并加载到内存(也就是懒加载)

- 支持数百万条的消息存储

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/kt2002011/article/details/141950012

为java程序员金三银四精心准备的面试题及答案(基础篇)_icardi9的博客-爱代码爱编程

关注我们VXGZ号获取更多免费的面试资料,学习视频 1、面向对象的特征有哪些方面? 【基础】 答:面向对象的特征主要有以下几个方面: 1)抽象:抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面。抽象并不打算了解全部问题,而只是选择其中的一部分,暂时不用部分细节。抽象包括两个方面,一是过程抽象,二是数据

膨胀!有了这份P9架构师推的2800页Java面试大礼包,金九银十稳了-爱代码爱编程

程序员一步入中年,不知不觉便会被铺天盖地的“危机感”上身,曾经的那个少年已经不在,时间就是这样公平。就算你能发明Java语言,随着时间的推移,你注定还是要成为慢慢变蔫的茄子,缓缓变黑的葡萄。 看着金九银十马上就要来临的消息,吓得我周末赶紧拿出了面试资料,只读了一小部分我就发现一个事实,果然有很多的知识点都模棱两可,相信很多的人都跟我一样有这样的危机感。怎

2023最新版java面试题及答案整理(建议收藏)-爱代码爱编程

前言 面试,跳槽,每天都在发生,而对程序员来说"金三银四"更是面试和跳槽的高峰期,跳槽,更是很常见的,对于每个人来说,跳槽的意义也各不相同,可能是一个人更向往一个更大的平台,更好的地方,可以通过换一个环境改变自己的现状。而我正是其中一员,投了十多家互联网公司,目前 已收到五个 Offer,其实跳槽是把双刃剑,有好也有坏,要看你是因为什么原因跳槽。如果说你

【java面试题总结 1,程序员进阶_从db中项目a的类型为char(4),dto中的项目b类型为string型,b=123,当a=b时,-爱代码爱编程

startsWith(String str): 判断字符串是否以传递进来的字符串开头; endsWith(String str): 判断字符串是否以传递进来的字符串结尾; isEmpty(): 判断字符串的内容是否为空

【最详细】2024最全java面试题及答案!_2024java面试题和答案-爱代码爱编程

本文分为十九个模块,分别是:「Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafka 面试专题」 , Java 基础 1. JDK 和 JRE 有什么区别? JDK:Java Development Kit 的简称,Java 开发工具包,提供

2024 年最新版 java 面试题及答案整理(纯干货,超详细)_2024java面试提问-爱代码爱编程

程序员一步入中年,不知不觉便会被铺天盖地的“危机感”上身,曾经的那个少年已经不在,时间就是这样公平。就算你能发明 Java 语言,随着时间的推移,你注定还是要成为慢慢变蔫的茄子,缓缓变黑的葡萄。 看着春招就要来临的消息,吓得我周末赶紧拿出了面试资料,只读了一小部分我就发现一个事实,果然有很多的知识点都模棱两可,相信很多的人都跟我一样有这样的危机感。怎么办

题解 | #第二快/慢用时之差大于试卷时长一半的试卷#_面试官:看了你的简历,了解到你有两年半的送外卖经验,可以简单说下平时是怎么-爱代码爱编程

美团暑期实习 推荐算法一面:4.15二面:4.17offer:  4.23   题解 | #纠错4# SELECT cust_name,cust_contact,cust_emailFROM Custo   从“艺术生”到大厂RD,我要开始装逼了 暑期实习已经拿到了自己比较满意的offer,所以稍稍能够闲下来想想一些有的没的事情。正如标题所写

2024java面试题大全(200+道题目)_java面试题2024-爱代码爱编程

一、Java 基础 1.JDK 和 JRE 有什么区别? jdk:java development kit jre:java runtime Environment jdk是面向开发人员的,是开发工具包,包括开发人员需要用到的一些类。 jre是java运行时环境,包括java虚拟机等,是提供给使用java的人用的 2.=

2024年java最新面试题(全网最全、最细、附答案)_2024年java面试题-爱代码爱编程

1、为什么说 Java 语言“编译与解释并存”? 其实这个问题我们讲字节码的时候已经提到过,因为比较重要,所以我们这里再提一下。 我们可以将高级编程语言按照程序的执行方式分为两种: 编译型:编译型语言open in new window 会通过编译器open in new window将源代码一次性翻译成可被该平台执行的机器码。一般情况下,编译语言

2024最新java面试题及答案!( 2024年 1 月最新版,持续更新)_2024java面试题-爱代码爱编程

2024了发现网上很多Java面试题都没有答案,所以花了很长时间搜集整理出来了这套Java面试题大全~ 这套互联网 Java 工程师面试题包括了:Java面试、Spring、JVM、MyBatis、Redis、

2024年最全java面试题,及答案汇总!_java基础面试题-爱代码爱编程

适宜阅读人群 需要面试的初/中/高级 java 程序员想要查漏补缺的人想要不断完善和扩充自己 java 技术栈的人java 面试官 具体面试题 下面一起来看 208 道面试题,具体的内容。 一、Java 基础 1.