当前位置: 首页 > 科技观察

服务容错:服务雪崩与容错方案

时间:2023-03-19 18:42:41 科技观察

并发对系统的影响当系统的架构设计采用微服务架构模式时,庞大复杂的业务会被拆分成小的微服务。以接口或RPC的形式互相调用。在调用的过程中,会涉及到网络问题,再加上微服务本身的原因,比如很难做到100%的高可用。如果其中一个或某些微服务出现问题,不可用或宕机,其他微服务调用这些微服务的接口时会出现延迟。如果此时有大量请求进入系统,会造成请求任务大量堆积,甚至导致整体服务瘫痪。压测说明为了更直观的说明在系统没有容错的情况下,高并发、高流量场景对系统的影响,我们这里模拟一个并发场景。在订单微服务shop-order的io.binghe.shop.order.controller.OrderController类中添加concurrentRequest()方法,源码如下。@GetMapping(value="/concurrent_request")publicStringconcurrentRequest(){log.info("测试高并发场景下是否有问题");return"binghe";}接下来,为了更好的演示效果,我们限制Tomcat处理的最大并发请求数,在订单微服务shop-order的resources目录下的application.yml文件中添加如下配置。server:port:8080tomcat:max-threads:20限制Tomcat一次最多处理20个请求。接下来,我们使用JMeter来测试http://localhost:8080/order/submit_order接口。由于订单微服务中没有容错处理,当http://localhost:8080/order/submit_order接口请求压力过大时,当我们访问http://localhost:8080/order/再来看concurrent_request接口,我们会发现http://localhost:8080/order/concurrent_request接口会受到并发请求的影响,访问很慢甚至根本访问不了。实际压测使用JMeter对http://localhost:8080/order/submit_order接口进行压测。JMeter的配置过程如下。(1)打开JMeter主界面,如下图。(2)右键JMeter中的测试计划,添加线程组,如下图。(3)在JMeter中配置线程组的并发线程数,如下图。如上图,配置线程数为50,Ramp-Up时间为0,循环次数为100。表示JMeter每次同时向系统发送50个请求,直到100次。(4)在JMeter中右键线程组添加HTTP请求,如下图。(5)在JMeter中配置HTTP请求,如下图。具体配置如下。协议:http服务器名或IP:localhost端口号:8080方法:GET路径:/order/submit_order?userId=1001&productId=1001&count=1内容编码:UTF-8(6)配置好JMeter后,点击JMeter上的绿色小按钮三角开始压力测试,如下图。点击后会弹出需要保存JMeter脚本的弹框,根据实际需要点击保存即可。点击保存后,就会开始对http://localhost:8080/order/submit_order接口进行压测。压测的时候会发现,订单微服务在打印日志的时候,会比较卡。同时,在浏览器或其他工具中访问http://localhost:8080/order/concurrent_request接口会卡住,甚至无法访问。说明一旦订单微服务中某个接口的并发量过高,其他接口也会受到影响,导致订单微服务整体不可用。为了说明这个问题,让我们看一下什么是服务雪崩。服务雪崩系统采用分布式或微服务架构模型后,由于网络或服务问题,一般服务很难做到100%高可用。如果一个服务出现问题,可能会导致其他服务级联出现问题。这种故障问题会不断蔓延到整个系统,导致服务不可用甚至宕机,最终会给整个系统带来灾难性的后果。.为了最大程度地防止服务雪崩,组成整个系统的每一个微服务都需要支持服务容错。服务容错解决方案服务容错在一定程度上就是尽量兼容错误的发生,因为在分布式和微服务环境中,难免会出现一些异常情况。我们在设计分布式和微服务系统的时候,需要考虑到这些异常情况的发生,让系统具备服务容错能力。常见的服务错误场景包括:服务限流、服务隔离、服务超时、服务熔断、服务降级。业务限流业务限流就是对进入系统的流量进行限制,防止进入系统的流量过大,造成系统不堪重负。其主要作用是保护集群背后的服务节点或数据节点,防止服务和数据因瞬时流量过大(如大量前端缓存)而崩溃,导致不可用;它也可以用来平滑请求。限流算法有两种,一种是单纯统计请求总数,一种是时间窗限流(一般为1s),比如令牌桶算法和缺卡桶算法就是时间窗电流-限制算法。服务隔离服务隔离有点类似于系统的垂直拆分。系统按照一定的规则划分为多个服务模块,各个服务模块相互独立,不存在强依赖关系。如果一个拆分服务出现故障,故障的影响可以仅限于某个特定的服务,不会波及到其他服务,自然不会对整体服务造成致命的影响。互联网行业常用的服务隔离方式有:线程池隔离和信号量隔离。服务超时整个系统采用分布式微服务架构后,系统被拆分成小服务,服务之间会存在相互调用的现象,从而形成调用链。在形成调用链关系的两个服务中,主动调用其他服务接口的服务处于调用链的上游,提供接口供其他服务调用的服务处于调用链的下游。服务超时是设置上游服务调用下游服务时的最大响应时间。如果下游服务在超过最大响应时间后没有返回结果,则上游服务与下游服务之间的请求连接将被断开,资源将被释放。服务熔断在分布式和微服务系统中,如果下游服务由于访问压力过大而响应缓慢或无法调用,上游服务会暂时断开与下游服务的调用连接,以保证系统的整体可用性。这种方式是融合。一般来说,业务熔断会有三种状态:off、on、half-fuse。关闭状态:当服务正常,没有故障时,上游服务调用下游服务时不会有任何限制。启用状态:上游服务不再调用下游服务的接口,会直接返回上游服务中预定的方法。半熔断状态:处于开启状态时,上游服务会按照一定规则尝试恢复对下游服务的调用。此时上游服务会调用下游服务,限流,同时监控调用成功率。如果成功率符合预期,则进入关闭状态。如果它不符合预期,它会回到开启状态。服务降级服务降级,说白了就是一种服务托底方案。如果服务无法完成正常的调用过程,将使用默认的底层方案返回数据。例如,产品介绍信息一般显示在产品详情页面。一旦商品详情页系统出现故障,无法调用,会直接获取缓存中的商品介绍信息返回给前端页面。