服务容错和sentinel
服务容错的背景:在微服务中,我们将业务拆分为一个个服务,每个服务都不可避免的会因为各式各样的缘由(包括人为和非人为)出现未知的失败。在某个服务出现问题时,由于当前的在微服务架构中,服务的调用时极为复杂的,如若此时该服务没有隔离措施的话,当前应用服务就有瘫痪的可能。
容错模式
:在某种场景下一类问题及其解决方案的总结归纳,往往可以被重用,在服务容错这个方向,已经有了几个今典的不少实践总结出来的解决方案。
1,仓壁模式(隔离):资源隔离手段。在调用方进行资源隔离,比如使用线程池,保证消耗的资源有上限,避免无限量调用资源占用其他请求的资源。
经典的栗子:
轮船的舱壁设计,轮船的船舱是一个个互相隔离的,单个船舱漏水也并不会影响到其他的船舱。
类比至服务:系统A调用了ServiceB/ServiceC/ServiceD三个远程服务,且部署A的容器一共有120个工作线程,采用线程隔离机制,可以给对ServiceB/ServiceC/ServiceD的调用各分配40个线程。当ServiceB慢了,给ServiceB分配的40个线程因慢而阻塞并最终耗尽,线程隔离可以保证给ServiceC/ServiceD分配的80个线程可以不受影响。如果没有这种隔离机制,当ServiceB慢的时候,120个工作线程会很快全部被对ServiceB的调用吃光,整个系统会全部慢下来,甚至出现系统停止响应的情况。
2,限流:在提供方一端限制进入的流量,保证服务不会因为超负荷流量而崩溃。就和去食堂打饭排队一样,当超出的服务能提供的最大并发量时,其他请求只能进行等待或者换地方了;
流控模式:
1).直接:直接对资源限流
2).关联:
a.创建两个资源A 和B
b.对A设置规则,指定关联B
c.请求B,使其达到频率,访问A发现被流控
3).链路:以调用链路为单位做限流处理,例如:A->B->C 这个链路的总体流量只按入口A的请求量来计算
效果或者说是结果:
1.快速失败:在服务达到阈值时,其他服务会直接被拒绝,拒绝方式为抛出
2.预热:指当流量激增时(活动,热点等等),如果立即将系统的性能给拉到最高的话很有可能会造成系统崩掉,所以会限制流量在一定时间增大,最后到达阈值,保护系统不被突然的激增流量压垮;
3.排队等待,需要设置将阈值模式设置为QPS才能生效。这种方式严格控制了请求通过的间隔时间,也即是让请求以均匀的速度通过,对应的是漏桶算法。
3.熔断器:
通俗些讲,就类似与电路系统中的保险丝,当负载过高时会直接断掉该户人家的电力系统。当然在系统中则不需要人工跟换保险丝的操作。
- 在调用方进行控制,根据策略定义失败情况,失败数字达到阈值时打开熔断器,不再调用底层服务,熔断窗口(一段时间过后)达到时,释放一个请求进入底层,如果请求执行成功则关闭熔断器,正常调用,如果请求失败则继续保持熔断器打开直到下一个熔断窗口达到。
图例:
1.熔断器,监管者开关,和对某服务的服务健康状态的监管(请求失败数/请求总和:可以是比例也可以时数量)
2,当熔断器开关关闭时, 请求被允许通过熔断器. 如果当前健康状况高于设定阈值, 开关继续保持关闭. 如果当前健康状况低于设定阈值, 开关则切换为打开状态.
3,当熔断器开关打开时, 请求被禁止通过.
4,当熔断器开关处于打开状态, 经过一段时间后, 熔断器会自动进入半开状态, 这时熔断器只允许一个请求通过. 当该请求调用成功时, 熔断器恢复到关闭状态. 若该请求失败, 熔断器继续保持打开状态, 接下来的请求被禁止通过.
4,超时:
超时:最简单的容错方式,在调用方为服务调用设置一个超时时间,避免无限制的等待下游系统造成的线程堆积
5,降级:什么是服务降级?当服务器压力剧增的情况下,根据实际业务情况及流量,对一些服务和页面有策略的不处理或换种简单的方式处理,从而释放服务器资源以保证核心交易正常运作或高效运作。
通俗些说:在牺牲不重要的资源情况下,尽力满足主要服务的资源
sentinel
2012 年,Sentinel 诞生,主要功能为入口流量控制。
2013-2017 年,Sentinel 在阿里巴巴集团内部迅速发展,成为基础技术模块,覆盖了所有的核心场景。Sentinel 也因此积累了大量的流量归整场景以及生产实践。
2018 年,Sentinel 开源。
Sentinel :Sentinel 是面向分布式服务架构的轻量级流量控制产品,主要以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度来保护服务的稳定性。
1.添加依赖
2.修改配置,暴露actutor的端点(yml中)
3.下载jar包,启动命令:java -Dserver.port=8840 -Dcsp.sentinel.dashboard.server=localhost:8840 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.7.1.jar
访问 localhost:8840 用户名/密码:sentinel(后台图形化界面)
4. 修改应用配置,让应用连接上sentinel-dashboard(yml)
5. 控制台是懒加载的,需要先发请求,再能看到配置
在应用中开发一个端点 /hello
发请求给hello
在控制台刷新,看到sentineldemo项目的控制台界面
关键词:
-
资源名:唯一名称,默认请求路径
-
针对来源:Sentinel可以针对调用者进行限流,填写微服务名,默认default(不区分来源)
-
阈值类型/单机阈值:
1.QPS(每秒钟的请求数量):当调用该api的QPS达到阈值的时候,进行限流
2.线程数:当调用该api的线程数达到阈值的时候,进行限流 -
流控模式:
1.直接:api达到限流条件时,直接限流
2.关联:当关联的资源达到阈值时,就限流自己
3.链路:只记录指定链路上的流量(指定资源从入口资源进来的流量,如果达到阈值,就进行限流) -
流控效果:
1.快速失败:直接失败,抛异常
2.Warm Up:根据codeFactor(冷加载因子,默认3)的值,从阈值/codeFactor,经过预热时长,才达到设置的QPS阈值。
3.排队等待:匀速排队,让请求以匀速的速度通过,阈值类型必须设置为QPS。否则无效。 -
1.RT平均响应时间
设置rt毫秒数,设置时间窗口,如果在设置的rt毫秒数内还没处理完,就设置降级的时间,不让访问 -
2.异常比例
设置异常比例(0.2=10%),设置时间窗口(间隔几秒),如果设置异常比例为0.2,设置时间是1,如果请求过来出现了20%以上的错误,才走降级,如果没超过,直接返回异常信息 -
3.异常数
设置异常比例,设置时间窗口如果设置异常比例为5,时间要大于1分钟(设置为70),如果1分钟出现5次以上的异常时,就会走熔断降级(就会返回指定的异常信息)。