- 解决了服务拆分之后的服务治理问题:Nacos解决了服务治理问题
- OpenFeign解决了服务之间的远程调用问题
- 网关与前端进行交互,基于网关的过滤器解决了登录校验的问题
流量控制:避免因为突发流量而导致的服务宕机。
隔离和降级:避免微服务出现雪崩
避免非法的请求进入微服务当中
避免因为服务的重启而导致这些规则的丢失
微服务中,服务间调用关系错综复杂,一个微服务往往依赖于其它多个微服务。
如图,服务消费者调用服务提供者,如果服务提供者发生了故障,由于当前服务消费者应用的部分业务依赖于服务提供者,导致服务消费者的业务请求会被阻塞,因为服务消费者要等待服务提供者结果的返回,请求被阻塞,用户自然不会得到响应,Tomcat的这个线程也不会释放,因为阻塞它就不会释放Tomcat的连接,于是越来越多的用户请求到来,越来越多的线程会被阻塞,由于Tomcat服务器支持的线程和并发数有限,业务请求一直被阻塞,会导致服务器资源耗尽,从而导致其它业务请求请求不进来,导致当前服务也故障不可用了,形成级联失败,雪崩就发生了 => 一个服务故障导致依赖于它的服务最终也出现故障了,导致依赖于它的服务最终被拖垮
在微服务架构中,服务与服务之间会通过远程调用的方式进行通信,一旦微服务调用链路中的某个服务发生故障或某个资源出现不稳定,例如,表现为timeout - 业务接口超时响应,业务接口响应时间过长,会导致其依赖服务也会发生故障,此时就会发生故障的蔓延,引起整个链路中的所有微服务都不可用,也就是引起整个链路中的所有微服务都无法访问的情况,最终导致系统瘫痪,这就是服务雪崩问题或者叫级联失败问题。
这些方案或多或少都会导致服务的体验上略有下降,比如
但通过这些方案,服务的健壮性得到了提升。
容错保护就是当某个服务发生故障时,通过断路器的监控,给调用返回一个错误响应,而不是长时间的等待,这样就不会使得调用方由于长时间得不到响应而占用线程,从而防止故障的蔓延。
超时处理:
舱壁模式(线程隔离)
断路器模式或熔断降级(模式):比较推荐的一种解决方案
限流 - 流量控制:
Hystrix和Sentinel都是非常成熟可靠的服务保护工具,早期比较流行的是Hystrix框架,但目前国内使用最广泛的还是阿里巴巴的Sentinel服务保护框架(是Spring Cloud Alibaba的组件之一),这里我们做下对比:
关于Hystrix和Sentinel的对比,在Sentinel的官网上有一篇文章写的很详细:
sentinel-vs-hystrix | Sentinelsentinel-vs-hystrixhttps://sentinelguard.io/zh-cn/blog/sentinel-vs-hystrix.html
技术选型:Sentinel vs Hystrix本文将从多个角度对 Sentinel 和 Hystrix 进行对比,希望在面临技术选型的时候,对各位开发者能有所帮助。https://mp.weixin.qq.com/s/D8RKfnzofM-br_y4fTLIaA
Sentinel底层是基于信号量来实现资源隔离,而Hystrix提供两种隔离策略,Hystrix支持线程池隔离或信号量隔离,但默认情况下都是使用线程池隔离来实现资源隔离。
线程池隔离模式下需要配置线程池对应的参数,信号量隔离模式下需要配置最大并发数。
- 线程池隔离:在一个业务请求进入Tomcat以后,它会给每一个被隔离的业务创建一个独立的线程池,Hystrix也一样,Hystrix的线程池隔离针对不同的资源分别创建不同的线程池,这样,不同的服务调用都发生在不同的线程池中,在线程池阻塞情况时可以快速失败,线程池隔离的好处是隔离度比较高,资源和资源之间做到了最彻底的隔离,可以针对某个资源的线程池去进行处理而不影响其它资源,但是代价就是线程上下文切换的overhead比较大,线程上下文切换会有非常大的损耗,增加了线程切换的成本,特别是对低延时的调用有比较大的影响。另外,还需要预先给各个资源做线程池大小的分配,实际情况下,线程池隔离并没有带来非常多的好处,最直接的影响,就是会让机器资源碎片化。
- Hystrix的信号量隔离限制对某个资源调用的并发数,这样的隔离非常轻量级,仅限制对某个资源调用的并发数,而不是显式的去创建线程池(也就意味着不会去创建新的线程,这样就减少了线程的创建),所以overhead比较小,但是效果不错,但缺点是无法对慢调用自动进行降级,只能等待客户端自己超时,因此仍然可能会出现级联阻塞的情况。
- 而Sentinel可以通过并发线程数模式的流量控制来提供信号量隔离的功能,并且结合基于响应时间的熔断降级模式,可以在不稳定资源的平均响应时间比较高的时候自动降级,防止过多的慢调用占满并发数,影响整个系统。
- Sentinel和Hystrix的熔断降级功能本质上都是基于熔断器或断路器模式;
Sentinel和Hystrix都支持基于失败比率(异常比率)的熔断降级,在调用达到一定量级并且失败比率达到设定的阈值时自动进行熔断,此时所有对该资源的调用都会被block,直到过了指定的时间窗口后才启发性的恢复;
- 而且Sentinel还支持基于平均响应时间的熔断降级,可以在服务响应时间持续飙高的时候自动熔断,拒绝掉更多的请求,直到一段时间后才恢复,这样可以防止调用非常慢,也就是防止慢调用造成级联阻塞的情况。
1. 轻量级、高性能
- Sentinel非常轻量级,其核心sentinel-core没有任何多余依赖,打包后只有不到200KB,非常轻量级,同时Sentinel非常高性能,引入Sentinel带来的性能损耗非常小,只有在业务单机量级超过25wQPS的时候才会有一些显著的影响,单机QPS不太大的时候损耗几乎可以忽略不计。
2. 流量控制
- Sentinel可以针对不同的调用关系,以不同的运行指标(如QPS、并发调用数、系统负载)为基准,对系统资源的调用进行流量控制,将随机的请求调整成合适的形状。
Sentinel支持多样化的流量整形策略,在QPS过高时可以自动将流量调整成合适的形状,常用的有:
- 直接拒绝模式:即超出的请求直接拒绝。
- 慢启动预热模式:当流量激增的时候,控制流量通过的速率,让通过的流量缓慢增加,在一定时间内逐渐增加到阈值上限,给冷系统一个预热的时间,避免冷系统被压垮。
- 匀速器模式:利用Leaky Bucket漏桶算法实现的匀速模式,严格控制了请求通过的时间间隔,同时推积的请求将会排队,超过超时时长的请求直接被拒绝。
Sentinel还支持调用关系的限流,包括基于调用方限流、基于调用链入口限流、关联流量限流等,依托于Sentinel强大的调用链路统计信息,可以提供精准的不同维度的限流。
3. 系统负载保护或系统自适应保护
- 当系统负载较高时,如果仍持续让请求进入,可能会导致系统崩溃,无法响应。
- 在集群环境下,网络负载均衡会把本应这台机器承载的流量转发到其它的机器上去,如果这个时候其它的汲取也处在一个边缘状态的时候,这个时候增加的流量就会导致这台机器也崩溃,最后导致整个集群不可用,针对这个情况,Sentinel提供了对应的保护机制,让系统的入口流量和系统的负载达到一个平衡,保证系统在能力范围之内处理最多的请求。
4. 实时监控和控制面板
- Sentinel控制台(Dashboard)提供了机器发现、配置规则、查看实时监控、查看调用链路信息等功能,使得用户可以非常方便的去查看监控和进行配置。
5. 生态
- Sentinel目前已经针对Servlet、Dubbo、Spring Boot/Spring Cloud、gRPC等进行了适配,用户只需引入相应引来并进行简单配置即可非常的方便的享受Sentinel的高可用流量防护能力。
随着微服务的流行,服务和服务之间的稳定性变得越来越重要,Sentinel是面向分布式、多语言异构化服务架构的流量治理组件,主要以流量为切入点,从流量路由、流量控制、熔断降级、系统自适应过载保护、热点流量防护等多个维度来帮助开发者保障微服务的稳定性。
Sentinel和Hystrix的原则是一致的:当调用链路中的某个资源出现不稳定,例如,表现为 timeout,异常比例升高的时候,则对这个资源的调用进行限制,并让请求快速失败,避免影响到其它的资源,最终产生雪崩的效果。
在限制的手段上,Sentinel和Hystrix采取了完全不一样的方法。
和资源池隔离的方法不同,Sentinel通过限制资源并发线程的数量,来减少不稳定资源对其它资源的影响,这样不但没用线程切换的损耗,也不需要您预先分配线程池的大小。当某个资源出现不稳定的情况下,例如响应时间变长,对资源的直接影响就是会造成线程数的逐步堆积,当线程数在特定资源上堆积到一定的数量之后,对该资源的新请求就会被拒绝,堆积的线程完成任务后才开始继续接收请求。
当线程池阻塞时,你其它所有请求打进来也会被阻塞,除非当线程池能够处理新请求了,那你此时被阻塞的线程就要被唤醒,这个时候就会有线程上下文的切换开销;
而控制线程并发数就是你一旦达到我这个线程上限的阈值,你还来请求,我就直接给你拒绝掉,这样也就不存在什么阻塞了,自然不会有线程上下文切换的开销。
除了对并发线程数进行控制以外,Sentinel还可以通过响应时间来快速降级不稳定的资源,当依赖的资源出现响应时间过长后,所有对该资源的访问都会被直接拒绝,直到过了指定的时间窗口之后才重新恢复。
官网详情:
dashboard | Sentinel
Sentinel官方提供了UI控制台,方便我们对系统做限流设置,其实就是下载一个jar包。
1. 将其拷贝到一个你能记住的非中文、不包含特殊字符的目录下,重命名为sentinel-dashboard,然后运行命令:
java -jar sentinel-dashboard.jar
2. jar包运行完成以后它底层其实就是一个基于Spring Boot的Web应用,然后访问:localhost:8080 即可看到控制台页面,默认的账户和密码都是sentinel
注意:Sentinel控制台目前仅支持单机部署,启动Sentinel控制台需要JDK版本为1.8及以上版本。
登录后,即可看到控制台,但是登录后,我们发现一片空白,什么都没有:
默认会监控sentinel-dashboard服务本身。。。。。
我们在微服务模块中整合Sentinel,并且连接sentinel-dashboard控制台,步骤如下:
1. 引入Sentinel依赖
com.alibaba.cloud
spring-cloud-starter-alibaba-sentinel
2. 配置Sentinel的控制台地址,修改application.yaml文件,添加下面内容:
spring:
cloud:
sentinel:
transport:
dashboard: localhost:8080
3. 重启微服务,访问微服务的任意端点,触发sentinel监控
Spring MVC的任意一个Controller接口都是一个端点。