作者简介:曾任职于阿里巴巴,每日优鲜等互联网公司,任技术总监。15年电商互联网经历。
互联网系统为大量的C端用户提供服务,如果隔三差五的出问题宕机,会严重影响用户体验,甚至导致用户流失。所以稳定性对互联网系统非常重要!接下来,我根据自己的实际经验来聊聊基于微服务的互联网系统的稳定性。
下面我们从雪崩、隔离、服务降级、突发流量、缓存、数据冗余、熔断、限流、CDN、数据库、CI、网络等方面,聊聊如何保证基于微服务的系统稳定性。
雪崩效应产生原因,如何避免?
服务化后,服务变多,调用链路变长,如果一个调用链上某个服务节点出问题,很可能引发整个调用链路崩溃,也就是所谓的雪崩效应。
举个例子,详细理解一下雪崩。如上图,现在有A,B,C三个服务,A调B,B调C。假如C发生故障,B方法1调用C方法1的请求不能及时返回,B的线程会发生阻塞等待。B会在一定时间后因为线程阻塞耗尽线程池所有线程,这时B就会无法响应A的请求。A调用B的请求不能及时返回,A的线程池线程资源也会逐渐被耗尽,最终A也无法对外提供服务。这样就引发了连锁故障,发生了雪崩。纵向:C故障引发B故障,B故障引发A故障,最终发生连锁故障。横向:方法1出问题,导致线程阻塞,进而线程池线程资源耗尽,最终服务内所有方法都无法访问,这就是“线程池污染”
为了避免雪崩效应,我们可以从两个方面考虑:
常用开源熔断隔离组件:Hystrix,Resilience4j
如何应对突发流量对服务的巨大压力?
促销活动或秒杀时,访问量往往会猛增数倍。技术团队在活动开始前一般都会根据预估访问量适当增加节点,但是假如流量预估少了(实际访问量远大于预估的访问量),系统就可能会被压垮。所以我们可以在网关层(Zuul,Gateway,Nginx等)做限流,如果访问量超出系统承载能力,就按照一定策略抛弃超出阈值的访问请求(也要注意用户体验,可以给用户返回一个友好的页面提示)。
可以从全局,IP,userID等多维度做限流。限流的两个主要目的:1,应对突发流量,避免系统被压垮(全局限流和IP限流)2,防刷,防止机器人脚本等频繁调用服务(userID限流和IP限流)
数据冗余
在核心链路上,服务可以冗余它依赖的服务的数据,依赖的服务故障时,服务尽量做到自保。比如订单服务依赖库存服务。我们可以在订单服务冗余库存数据(注意控制合理的安全库存,防超卖)。下单减库存时,如果库存服务挂了,我们可以直接从订单服务取库存。可以结合熔断一起使用,作为熔断的Fallback(后备)方案。
服务降级
可能很多人都听过服务降级,但是又不知道降级是怎么回事。实际上,上面说的熔断,限流,数据冗余,都属于服务降级的范畴。还有手动降级的例子,比如大促期间我们会关掉第三方物流接口,页面上也关掉物流查询功能,避免拖垮自己的服务。这种降级的例子很多。不管什么降级方式,目的都是让系统可用性更高,容错能力更强,更稳定。
缓存要注意什么?
关于隔离的考虑
慢查询和大结果集问题
数据库层面主要考虑慢查询和大结果集问题:
系统问题快速定位!
服务化后,一次请求会跨多个服务,追踪问题也会变麻烦。这时就需要能够追踪整个调用链路的工具,协助我们排查问题。常见的开源全链路监控工具有(pinpoint,skywaking,cat等),以Pinpoint为例简单介绍一下:
Pinpoint基于JAVA,利用字节码增强技术,对服务零侵入,以traceID串联各个服务,已Plugin的方式支持不同API和中间件的监控,灵活方便。
上图是一个请求的调用栈,我们可以清晰看到一次请求调用了哪些服务和方法以及各个环节的耗时,以及发生在哪个节点。如果发生错误,会显示为红色,错误原因也会直接显示出来。这样通过APM系统我们就能轻松定位线上性能问题和错误了!
CI测试&性能测试
CI测试,持续集成测试,在我们每次提交代码到发布分支前自动构建项目并执行所有测试用例,如果有测试用例执行失败,拒绝将代码合并到发布分支,本次集成失败。CI测试可以保证上线质量,适用于用例不会经常变化的稳定业务。
性能测试,为了保证上线性能,所有用户侧功能需要进行性能测试。上线前要保证性能测试通过。而且要定期做全链路压测,有性能问题可以及时发现。
监控
我们需要一套完善的监控系统,系统出问题时能够快速告警,最好是系统出问题前能提前预警。包括系统监控(CPU,内存,网络IO,带宽等监控),数据库监控(QPS,TPS,慢查询,大结果集等监控),缓存中间件监控(如Redis),JVM监控(堆内存,GC,线程等监控),全链路监控(pinpoint,skywaking,cat等),各种接口监控(QPS,TPS等)
CDN
可以充分利用CDN。除了提高用户访问速度之外,页面静态化之后存放到CDN,用CDN扛流量,可以大幅减少系统(源站)的访问压力。同时也减少了网站带宽压力。对系统稳定性非常有好处。
避免单点问题
除了服务要多点部署外,网关,数据库,缓存也要避免单点问题,至少要有一个Backup,而且要可以自动发现上线节点和自动摘除下线和故障节点。
网络带宽
避免带宽成为瓶颈,促销和秒杀开始前提前申请带宽。不光要考虑外网带宽,还要考虑内网带宽,有些旧服务器网口是千兆网口,访问量高时很可能会打满。
安全
此外,一套完善的灰度发布系统,可以让上线更加平滑,避免上线大面积故障。DevOps工具,CI,CD对系统稳定性也有很大意义。
OK,就分享到这。如果感觉本文对您有帮助,有劳动动手指转发一下,分享是美德哦?