文章目录
srpingcloud中文官方文档: https://www.springcloud.cc/spring-cloud-dalston.html
一、Eureka:服务注册与发现中心
【问】为什么需要服务注册与发现中心:
1.服务动态上下线的感知
2.服务地址统一维护
1.八大概念:
1.1.服务注册
理解:eureka客户端向服务端注册服务,eureka客户端可能是服务调用着,也可能是服务消费者,或者两者都是
1.2.服务续约
理解:eureka客户端默认每隔30s向服务端发送心跳
1.3.服务获取
理解:eureka客户端向服务端获取注册表信息
1.4.服务下线
理解:eureka客户端shutdown申请服务下线
1.5.服务调用
理解:eureka客户端A根据拿到的注册表信息向eureka客户端B发送调用请求
1.6.服务同步
理解:eureka服务端C接受新的客户端后,会向其他eureka服务端同步信息,告知其他服务端有新的客户端接入
1.7.失效剔除
理解:eureka服务端90s内没有接收到eureka客户端A的心跳时,会考虑剔除服务提供者A
例子:如服务提供者A,被剔除,如果服务调用者B有A的注册表信息那么还是可以继续调用,否则就调用不到服务A了
1.8.自我保护
指的是:eureka server的自我保护
由来:网络分区发生故障时,微服务与eureka server通讯异常,而微服务本身是正常运行的,此时不应该剔除此服务,所以引入了自我保护机制。
工作机制:如果在15分钟内只有低于85%的客户端节点有正常心跳,那么eureka server就会认为客户端与注册中心出现了网络故障,并进入自我保护机制
进入自我保护后:
a.eureka server不再移除注册表中因长时间没有收到心跳的服务
b.eureka server仍然能够接受新服务的注册和查询请求,但不会同步到其他节点,保证当前节点的可用
c.网络稳定时,eureka server新的注册信息会同步到其他节点中
自我保护机制失效:默认情况下不要更改eureka的心跳时间和,如果改动了可能会导致,服务端仍然计算这个预期值比例和实际值比例是一样的(如心跳时间改为10秒,而server统计是30秒作为基准,统计时内同一服务发送了3次心跳包),那么此时自我保护机制不会触发(即失效)
2.eureka工作原理图
在进入读写缓存后,会stw一会(神操作)
注册表内存已经设计为ConcurrentHashMap了,为什么还需要设计三级缓存?
持续并发的情况下,读写竞争激烈严重影响eureka server服务性能
大致原理:后续准确的会更新上来
eureka工作原理:
1.client-A向server发起服务注册请求
2.client-A默认每个30s向server发送心跳
3.server每个90s检查一次 剔除下线的服务
4.client-B向server发起注册请求,初次全量拉去
5.先到从server的只读缓存中获取(一级),如果获取不到,再去读写缓存中获取(二级),如果获取不到再去注册表缓存中读取(三级)
6.client-B默认每个30s向server增量拉去注册表
7.同时读写注册表缓存中数据发生变化,会是读写缓存失效,30s同步到只读缓存
3.eureka与zookeeper区别
CAP原则
RDBMS :(Mysql、Oracle、sqlServer) ⇒ ACID
NoSQL:(redis、mongoDB)⇒ CAP
ACID是什么?
- A (Atomicity) 原子性
- C(Consistency) 一致性
- I (Isolation) 隔离性
- D(Durability) 持久性
CAP是什么?
- C (Consistency) 强一致性
- A(Avalibility)可用性
- P(Partition tolerance)分区容错性
CAP原则只能三进二,即:CA、AP、CP
CAP理论的核心:
-
一个分布式系统不可能同时很好地满足一致性、可用性和分区容错性这三个需求
-
根据CAP原理,将NoSQL数据库分成了满足CA原则、满足CP原则和满足AP原则三大类
- CA:单点集群,满足一致性、可用性的系统,通常可扩展性很差 - CP:满足一致性、分区容错性的系统,通常性能不是特别高 - AP:满足可用性、分区容错性的系统,通常对一致性要求低一些
-
作为注册中心,Eureka比Zookeeper好在哪里?
CAP理论指出,一个分布式系统不可能同时满足C(强一致性)、A(可用性)、P(分区容错性)
由于分区容错性P在分布式系统中是必须保证的,因此只能在A和C之间进行权衡- Zookeeper 保证的是CP; - Eureka 保证的是AP;
-
Zookeeper保证的是CP
现状及问题:当向注册中心查询服务列表时,我们可以容忍注册中心返回的是几分钟前的注册信息,但不能接受服务直 接down掉而不可用。也就是说服务注册功能对可用性的要求要高于一致性。 但zk会出现这样一种情况,当master节点因为网络故障与其他节点失去联系时,剩余节点会进行leader 选举。问题在于leader选举时间太长,30-120s,且期间整个zk集群是不可用的,就会导致在选举期间注册服 务是瘫痪状态。在云部署的环境下,因为网络问题是的zk集群失去master节点是较大概率事件,虽然最终都能 恢复,但漫长的选举导致注册长期不可用是不能容忍的。
-
Eureka保证的是AP
Eureka看明白了这点,因此再设计的时优先保证可用性。Eureka的各个节点都是平等的,几个节点挂掉不 会影响其他节点的工作,剩余节点依然可以提供服务注册和查询。 Eureka clinet在向server注册时,如果发现连接失败,则会自动切换至其他节点,只要有一台server还 在,就能保证服务的可用性,只不过查到的信息可能不是最新的;除此之外,Eureka 还有一种自我保护机制, 如果再15分钟之内超过85%的节点都没有心跳,那么Eureka server就会认为客户端与注册中心出现了网络故障, 此时会出现以下几种情况: 1、Eureka不再从注册中心移除因为长时间没有收到而应该过期的服务 2、Eureka仍然能够接受新服务的注册和查询请求,但是不会同步到其他节点上(即保证当前节点可用) 3、当网络稳定时,当前节点新的注册信息会自动同步到其他节点
因此:Eureka可以很好的应对因为网络故障导致部分节点失去联系的情况,而不会像zk那样使整个注册中心瘫痪。
4.eureka与nacos同为注册中心区别
4.1 nacos原理图:
红色圆圈部分:
4.2 CAP原理区别:
eureka:AP
nacos:AP(默认) 与 CP
4.2 服务感知上区别:
在对服务上下线感知时,nacos做了更细微的处理,nacos会主动将服务列表通过udp方式广播(push)出去,而eureka只是客户端到服务端拉取(pull)
4.3 AP与CP如何切换:
通过PUT请求就能切换:
curl -X PUT ‘$NACOS_SERVER:8848/nacos/v1/ns/operator/switches?entry=serverMode&value=CP’
4.4 nacos的优势
1.nacos支持主动检查client的心跳
2.nacos支持主动推送注册表
3.nacos采用ap(默认)或cp的模式
4.自带分布式配置中心
二、Ribbon :客户端负载均衡工具
1. Ribbon概念 :
主要功能提供客户端的软件负载均衡算法,将netflix的中间层连接在一起。
Ribbon的客户端组件提供了一套完整的配置项:如连接超时、重试等,客户端将列出所有服务端的所有机器,会按照相应的负载均衡算法进行对服务端的访问,也可以自定义负载均衡算法。
2. Ribbon作用:
- LB(Load Balance),在微服务或分布始终经常用的一种应用
- 负载均衡:将用户请求平摊分配到多个服务上,从而达到系统的HA(高可用)
- 常见的负载均衡软件有nginx、LVS等
- dubbo、springcloud中均给我们提供了负载均衡,springcloud的负载均衡算法可以自己定义
- 负载均衡简单分类:
- 集中式LB
- 即在服务的消费方和提供方之间使用独立的LB设施,如Nginx,由nginx负责把访问请求通过某种策略
转发至服务提供方
-进程式LB
-将LB逻辑集成到消费方,消费方从服务注册中心获取哪些地址可用,然后自己从这些地址中选出一个
合适的服务器(根据特定算法)
-Ribbon就是进程式LB,它只是一个类库,集成与消费方进程,消费方通过他来获取到服务提供方的地址
3. Ribbon工作原理图:
4. Ribbon提供7种负载均衡策略:
4.1.轮询策略:RoundRobinRule
4.2.权重策略:WeightedResponseTimeRule
4.3.随机策略:RandomRule
4.4最小连接数策略:BestAvailableRule
选区最小连接的一个服务,如果存在多个则轮训
4.5.重试策略:RetryRule
按照轮训方式获取,如果获取不到或为null,则不断重试获取
4.6.可用性敏感策略:AvailabilityFilteringRule
过滤非健康的实例,选择较小的服务实例
4.7区域敏感策略:ZoneAvoidanceRule
根据服务所在区域服务的性能和可用性来选择,没有区域环境和轮训类似
4.8 自定义负载均衡:实现Rule接口
三、Feign :远程调用(内置了Ribbon)
1. Feign 理解:
- 远程调用工具,基于RestTemplate,RestTemplate封装http,使得远程调用变得简单易用
2. Feign 访问方式:
- Feign:接口与注解
- Ribbon:微服务名字
3. Feign 作用:
- 旨在使编写java Http客户端变得更加容易
- Ribbon + RestTemplate配合使用,RestTemplate对Http进行封装,行程一套模板化的调用方法,对于需要
调用多个接口时,代码量就会越发复杂,Feign就是为了解决这一点
- Feign在ribbon的基础上进一步封装,来帮助我们定义和实现依赖服务的接口
在Feign的实现下,我们只需要创建一个接口并使用注解方式来配置它(类似于Dao接口上标注mapper注解,现在是一个微服务接口上标注一个Feign注解即可),既可以完成对服务方的接口绑定,也简化了使用Ribbon时,封装调用客户端的代码开发量
4. Feign 与Ribbon区别:
- 利用Ribbon维护了MicroServiceCloud-Dept的服务里表信息,并且通过轮询实现了客户端的负载均衡
- 区别:Feign只需要定义服务绑定接口且以声明式的访问方法,优雅而简单的实现了服务调用
4. Feign 与OpenFeign(ali家族):
四、Hystrix :降级、熔断(熔断器)、限流
1. 服务之间的调用
2. 服务雪崩:需弃车保帅
- 假设微服务A调用B和C,B和C又调用其他微服务,这就是所谓的“扇出”,如果扇出的链路上某个微服务调用的
响应时间过长或不可用,那么就会导致A的调用就会占用越来越多的资源,进而引起系统崩溃,所谓“雪崩效应”
- 对于高流量的应用,单一的后端依赖可能会导致所有服务上的所有资源再几秒内就会饱和,比失败更糟糕的是,
这些应用程序还可能导致服务之间的延迟,备份队列、线程和其他系统资源紧张,导致整个系统发生更多的级联
故障,这些都表示需要对故障和延迟进行隔离和管理,以便单个依赖关系的失败,不能影响其他的应用
3. 理解Hystrix
- Hystrix是一个用于处理分布式系统延迟和容错的开源库,Hystrix能够保证在一个依赖出现问题的情况下,不会
导致整个服务失败,避免级联故障,以提高分布式系统的弹性
- "断路器"本身是一种开关装置,当某个服务单元发生故障之后,通过断路器的故障监控(类似熔断保险丝),
向调用方返回一个服务预期的,可处理的备选相应(Fallback),而不是长时间的等待或抛出无法处理的异常,
这样就可以保证服务调用方的线程不会长时间被占用,从而避免了故障在分布式系统中的蔓延、乃至雪崩
4. Hystrix作用
4.1 服务降级
目的:保核心业务
作用、特点:
- 在客户端做的,与服务端无关
- 从整体网站请求负载考虑,某个服务或关闭后,服务将不再被调用
- 此时在客户端,需要准备一个FallBackFactory,返回一个默认值(缺省值),整体服务水平下降了,但能用
比直接挂掉强
微服务降级以下几点摘录于:https://blog.csdn.net/ityouknow/article/details/81230412
4.1.1自动降级策略(4种)
- 超时降级:主要配置好超时时间、超时重试次数、超时机制,并使用异步机制探测恢复
- 失败次数降级:针对一些不稳定的API,当失败调用次数达到阈值自动降级,同理使用异步机制探测恢复
- 故障降级:如调用的远程服务挂掉了(网络故障、DNS故障、HTTP服务返回错误状态码、RPC服务抛出异常的等),可以直接降级
- 限流降级:当触发了限流超额时,可以使用暂时屏蔽的方式来进行短暂的屏蔽
4.1.2降级处理方案(5种)
当触发降级后,新的交易再次到达时,我们该如何处理这些请求?
- 页面降级:可视化界面禁用点击按钮、调整静态页面
- 延迟服务:如定时任务延迟处理、消息入MQ后延迟处理
- 写降级:直接禁止相关写操作的服务请求
- 读降级:直接禁止相关读的服务请求
- 缓存降级:使用缓存方式来降级部分读频繁的服务接口
针对后端代码层面的降级处理策略,通常使用以下几种方式处理:
- 抛异常
- 返回NULL
- 调用Mock数据
- 调用Fallback处理逻辑
4.1.3服务降级高级特性
以上已经为服务都做好了一个降级开关,也已经在验证通过在线上运行了,感觉完全没有问题了。
场景一:某一天,运营搞了一次活动,突然跑过来说,现在流量已经快涨到上线了,有没有批量降级所有不重要服务的方式?开发此时一脸懵逼的看着,这又不是操作DB,哪里能批量操作?
场景二:某一天,运营又搞事了,说我们等下要搞一个活动,让我们赶紧提前把不重要的服务都降级了,开发又是一脸懵逼,我怎么知道要降级哪些服务啊?
反思:服务降级功能虽然是实现了,可是没考虑实时时的体验。服务太多,不知道该降级哪些服务,单个操作降级速度太慢了…
4.1.3.1分级降级
降级目的:保障核心服务的正常运作
如果等线上服务即将发生故障时,才去追个选择哪些服务该降级、哪些服务不该降级,然而线上有成百上千个服务,则肯定来不及降级就会被拖垮。
同时:在大促或秒杀等活动前才去梳理,也是会有不少的工作量,因此建议在开发期就需要架构师或核心开发人员来提前梳理好,是否能降级的初始评估值,即是否能降级的默认值
为了便于批量操作微服务架构中的服务降级,我们可以从全局角度来建立服务重要程度的评估模型,如果有条件可以使用 **层次分析法(AHP)**的数学模型来进行定性和定量的评估(肯定比架构师直接拍脑袋决定是否降级好很多倍,当然难度和复杂度也会很高,即需要一个会数学建模的人才),而层次分析的基本思路是人对一个复杂的决策问题的思维和判断过程大体是一样的
将微服务架构所有服务进行故障风暴等级分为以下4种:
评估模型:
- 蓝色风暴:表示需要小规模降级非核心业务
- 黄色风暴:表示需要中等规模降级非核心业务
- 橙色风暴:表示需要大规模降级非核心业务
- 红色风暴:表示必须降级所有非核心业务
设计说明:
- 故障严重程度:蓝色 < 黄色 < 橙色 < 红色
- 建议根据二八原则可以将服务划分为:80%的非核心业务 + 20%的核心业务
以上模型只是整体微服务架构的服务降级评估模型,具体大促或秒杀活动时,建议以具体猪蹄为中心进行建立(不同主题的活动依赖的服务不同,需要使用不同的降级方案才更为合理)。当然模型可以使用同一个,但数据需要有所差异。最好能建立一套模型库,然后实施时只需要输入相关服务即可输出最终降级方案、即输出本次大促或秒杀时,当发生蓝色风暴时需要降级的服务清单、发生换个风暴时需要的服清单…
4.1.3.2降级权值
微服务架构中有服务权值的概念,主要用于负载均衡的选择,同样服务降级权值也类似,主要用于服务降级选择时的细粒度优先级选择。所有的服务直接使用以上简单的四级划分方式统一处理,显然粒度太粗,或者说处于同一级的多个服务需要降级时的降级顺序改如何?甚至需要更智能的自动降级,那该如何更细粒度的控制?
4.2 服务熔断
作用:熔断机制是对雪崩效应的一种微服务链路保护机制
- 当扇出链路的某个微服务不可用或响应时间太长时,会进行服务的降级,进而熔断该节点微服务的调用,快速返
回错误信息;
- 当检测到该节点微服务调用响应正常后恢复调用链路。
- Hystirx会健康服务间的调用情况,当失败的调用到一定阈值时,默认是5秒内20次调用失败就会启动熔断机制。
- 熔断机制注解是@HystrixCommand
hystrix熔断器原理:3个状态:close、open、half-open
1.closed-open:正常状态处理close状态;当同一接口调用次数超过设置的阈值并且错误比列设置超过阈值时,熔断器就会打开;级closed->open状态;
2.open->half-open:当处于open状态时,所有的调用都是调用本地的降级方法;为了自动恢复,hystix提供了一种测试策略,即在一定时间内,open时,所有一定时间内请求走本地的降级方法,如果超过了这个时间,会继续调用下游方法,如果还是失败,那么再次变为open状态并重新指定open时时间,重复进行
3.half-open-close: 当处于half-open状态时,如果远程调用成功,则关闭熔断器
作用、特点:
- 在服务端做的,与客户端无关
- 某个服务超时或异常时,触发熔断,类似于保险丝。
4.3 服务限流(4种常见的限流算法)
4.3.1.计数器(固定窗口)算法
原理:使用计数器在一定时间周期内累加访问次数,当达到设定的限流值时,触发限流策略。
下一周期开始,进行清零,重新计数。
实现:在单机或分布式环境下实现非常简单,使用redis的incr原子自增性和线程安全即可轻松实现
图解:
应用场景:通常用于QPS限流和访问量统计
缺点:对于秒级别以上的时间周期来说,会存在非常严重的问题(临界问题)
图解临界问题:
假设:1min内服务器负载能力为100,因此一个周期的访问量限制为100
临界问题触发情况:在第一周期最后5s和第二周期前5秒这段时间内分别涌入100访问量,虽然没有超过周期的限制量,但这10s内访问量已经到达200,远远超出了服务器负载
固定窗口限流缺点:对于计算周期比较长的限流,存在很大的弊端
4.3.2.滑动窗口算法
实现原理:滑动窗口算法是将时间周期分为N个小周期,分别记录每个小周期的访问次数,并根据时间滑动删除过期的小周期。
场景:假设时间周期为1min,将1min分为2个小周期,统计每个小周期的访问数量,则可以看到,在第一个大的时间周期内,访问数量为75,第二个大的时间周期内,访问量为100,超过100的访问则被限流处理掉了
图解场景:
特点:当滑动窗口的各自划分越多,那么滑动窗口滑动的越平滑,限流统计就会越精确
优点:解决了固定窗口限流算法的问题。
4.3.3.漏桶算法
原理:漏铜算法是访问请求到达时直接放入漏桶中,如果当前容量已经到达上限(限流值),则进行丢弃(触发限流策略)。漏桶内以固定的速率对请求进行释放,直到漏桶为空
图解原理:
4.3.4.令牌桶算法
原理:令牌桶算法是程序以r(r=时间周期/限流值)的速度向令牌桶中增增加令牌,直到令牌桶满,请求到达时向令牌桶中请求令牌,如果获取到令牌则通过请求,否则触发限流策略
图解原理:
4.3.5.四种限流算法比较
4.3.6.漏桶算法和令牌桶优缺点
漏桶算法更适合秒杀、抢购等高并发场景
4.4 接近实时的监控
5 hystrix接口隔离策略
1.线程池隔离:使用较多(消耗资源大)
2.信号量隔离
6 Hystrix与Sentinel(ali家族)
sentinel特性:
1.轻量级、高性能
2.限流控制:
直接拒绝模式:超出的请求直接拒绝
慢启动预热模式:当流量激增时,控制流量的速率,让流量缓慢增加,在一定时间内逐渐上升到阈值,给冷系统预热时间,防止被压垮
匀速模式:leaky bukect算法实现
3.系统负载的保护
4.实时监控和控制面板;Sentinel 提供 HTTP API 用于获取实时的监控信息,链路信息,簇点信息,规则信息等
5.生态完善,使用简单
五、zuul :路由网关
1. 作用
Zuul主要是对请求的路由和过滤这两个功能,还有代理功能
路由:路由功能负责将外部请求转发到具体的微服务实例上,是实现外部访问同一入口的基础
过滤:过滤则是负责对请求的处理过程进行干预,是实现请求校验,服务聚合等功能的基础。
2. Zuul工作原理
2.1 Zuul与Eureka工作原理:
Zuul与Eureka进行整合,将zuul自身注册为Eureka服务治理下的应用,同时从Eureka中获取其他微服务消息,外部访问微服务都是通过zuul跳转后获得
注意:Zuul服务最终还是会注册进Eureka
2.2 gateway工作原理(官网):
执行流程:
1.客户端向Springcloud Gateway发出请求
2.网关处理程序Gateway Handler Mapping映射确定与请求相匹配的路由
3.如匹配路由,则将其发送到网关web处理程序GatewayWebHandler,选择对应过滤器链
4.执行过滤器链(pre Filter)
5.发送代理请求到代理服务
6.代理服务处理完发送代理请求
7.执行过滤器链(post Filter)
8.返回。
六、Springcloud Config:分布式配置中心
1. 分布式配置问题:
分布式项目面临的配置文件问题
微服务意味着要将单体应用中的业务拆分成一个个子服务,每个服务的粒度相对较小,因此系统中会出现大量的服务,由于每个服务都需要必要的配置信息才能运行,所以一套集中式的、动态配置管理设施是必不可少的。
2. 作用:
对分布式项目中配置文件集中管理
3. 理解分布式配置中心:
SpringCloud Config为微服务架构中的微服务提供集中化的外部配置支持,配置服务器为各个不同微服务应用的所有环节提供了一个中心化的外部配置
Springcloud Config分为服务端和客户端两部分:
服务端:也是分布式配置中心,它是一个独立的微服务应用,用来连接配置服务器并为客户端提供获取配置信息、加密、解密信息等访问接口
客户端:微服务个体,是通过制定的配置中心来管理资源,以及与业务相关的内容,并在启动的时候从配置中心获取和加载配置信息。配置服务器默认用git来存储配置信息,这样就有助于对环境进行版本管理。并且可以通过git客户端工具来方便的管理和访问配置内容。
Springcloud Config分布式配置中心能做什么?
- 集中式管理配置文件
- 不同环境,不同配置,动态化的配置更新,分环境部署。如/dev /test /prod /beta /release
- 运行期间动态调整配置,不再需要在每个服务部署的机器上编写配置文件,服务会向配置中心统一拉取配置自己的信息
- 当配置发生变动时,服务不需要重启,即可感知到配置文件的变化,并应用新的配置(需要热部署插件)
- 将配置信息以REST接口的形式暴露
Springcloud Config分布式配置中心与github整合
由于springclooudconfig默认才用的是git来存储配置文件(也有其他方式,如SVN/本地文件),但是最推荐的还是git,而且使用的是http/https访问形式
七、nginx与keepalived
1.nginx相关概念
1.1正向代理
客户端浏览器通过配置代理服务器,通过代理服务器的映射关系请求到对应的网址
nginx是如果配置配置正向代理的?
1.2反向代理
1.3负载均衡
1.4动静分离
1.5nginx高可用
通过LVS+keepalived配置实现
2.nginx原理及问题
2.1 nginx原理
master:分配工作
woker:争抢处理任务
nginx底层实现:linux多路复用机制,与redis相似
2.2 nginx问题总结:
1.一个master对应多个worker的好处(争抢机制)
(1)可用使用nginx -s reload 热部署而不需要重启nginx服务
(2)每个worker是个独立进程,如其中一个worker出现问题,其他worker不受影响,可用继续争抢
2.设置多少个worker合适(性能最优)
worker数量=cpu核心数最为适宜(不会造cpu来回切换,影响性能)
3.nginx可以处理多少并发?
理解:1个worker对应多个worker_connection。如worker_connection=1024
分为2种情况:
(1):当nginx处理静态资源时:worker数量worker_connection / 2
(2):当nginx处理操作后台时:worker数量worker_connection / 4
4.nginx异常处理
- 重启nginx报错 端口问题:server的绑定端口不能与本机要映射的端口一致
- 外部访问不到问题:端口开防火墙