https://blog.csdn.net/paolei/article/details/94390330前端
背景简介linux
对于大型应用后台系统来讲,稳定性相当重要。目前愈来愈多的大型应用系统采用微服务架构,更加须要关注稳定性的技术能力建设。稳定性是服务系统基础能力的体现。ios
基础知识算法
在介绍稳定性技术策略主题以前,咱们首先梳理一些基础概念和知识。数据库
针对咱们业务后台系统建设,任何大型业务后台系统绝对不是一蹴而就。它是伴随着业务不一样阶段,不断进行演进的过程。若是经历过从 0 到 1 建设一个业务后台系统的同窗,都会有相似的体会。缓存
启动阶段性能优化
启动阶段,业务模型相对简单,用户量少,这时候咱们能够将全部的系统模块耦合在一个工程里面,进行单机部署。这时候可能仅仅须要将业务系统与数据库进行隔离。服务器
探索阶段网络
探索阶段,业务模型不断演进,用户量增长,单机服务能力瓶颈凸显。这时候就须要由单机服务部署向集群服务部署来优化,利用负载均衡将请求合理分配,减小单机服务压力。另一个方面,数据量不断的增长,也须要考虑针对数据来进行水平的扩展(主从部署,读写分离)。架构
在这一阶段,咱们仅仅是作了集群扩展,但全部的业务代码都在同一个工程维护,全部的数据信息都在同一个数据库中存储。随着团队的扩充与业务交互不断复杂化,在工程维护上存在很大的风险,工程研发效率受到制约,业务代码之间的耦合也难以清晰,系统可靠性存在很大风险,一个 bug 可能会形成整个应用的崩溃不可用。
发展阶段
若是咱们比较幸运,业务持续快速发展,对于业务角色模型理解愈来愈清晰,业务角色模型之间的交互愈来愈肯定。这时候就须要咱们基于对业务充分的理解前提下进行垂直拆分。不一样的业务模型会部署到不一样的系统工程中,工程之间经过接口来进行交互。这样工程内业务高度集中,工程间经过接口服务来进行解耦。这时候无论是系统维护,仍是业务模块维护,都将大大的提升效率。数据部分一样垂直拆分,不一样业务数据拆分到不一样的数据库,从而提升单机数据库的能力。
拿电商系统的结构来讲,以下图所示:
基于业务模型分为几个大的系统服务,系统服务之间经过内部 RPC 接口来进行交互。
成熟阶段
上面是基于大的业务模型进行划分,随着业务复杂度愈来愈高,咱们必将对大业务模型,基于功能或者业务边界进行更细粒度的拆分。好比说,咱们能够将产品中心划分为:基础信息中心,库存管理中心,SKU 中心等。
这时候就涉及到微服务的拆分与治理工做。
微服务的拆分原则咱们应该注意:业务功能单一; 服务间业务边界清晰;拆分粒度合理; 分层划分合理。
从研发的角度来讲,微服务带来的好处:研发效率提高;代码质量更优;可以独立部署;单模块复杂度下降。上面提到的产品中心咱们能够拆分不少小的服务来提供,以下图所示:
细粒度的拆分,也会带来必定的挑战:
微服务划分单元越细,总体服务维护很是复杂;
微服务经过 RPC 接口交互,整个链路可能会不清晰;
单服务的修改或者优化会受到其余模块的牵制。
固然这些挑战都是咱们须要思考与解决的问题,并不能抹杀微服务的优势。
大型业务后台系统,不断的微服务化,带来系统之间的接口交互与依赖管理也愈来愈重要。咱们须要从总体上考虑咱们如何保证这样一个流量并发高,业务模型复杂,服务依赖交互多的大型微服务后台应用系统的稳定性。不能因为某个不利因素来影响整个业务微服务系统的不可用。接下来咱们将重点介绍稳定性相关的内容。
稳定性技术策略
什么是稳定性
对于大型微服务系统,在错综复杂的服务逻辑各类交互情景下,面对各类未知的条件变化,总体系统依旧可以正常平稳的提供服务,这即是稳定性。
影响稳定性的因素
系统稳定性影响因素很是多,举例来讲:
1. 服务间的依赖:某个服务 BUG 形成其余依赖服务的不可用;
2. 业务逻辑变动:业务逻辑不断迭代演变,新老服务的不兼容;
3. 访问流量激增:流量忽然增长,好比咱们进行促销活动期间,致使服务压力过大 ,达到服务能力上限,从而致使服务崩溃;
4. 机器老化异常:任何机器和人同样,都有生老病死,随着长时间的运行,也会有磨损,所以某个机器故障,也是可能的异常。
还有其余各方面的因素,在这里就不进行穷尽了,你们能够思考一下,还有那些经典的影响因素。
稳定性的衡量标准
稳定性衡量标准通常用 N 个 9 来衡量。如表格所示:
名称级别年度停机时间描述2 个 999%87.6 小时基本可用3 个 999.9%8.8 小时较高可用性4 个 999.99%53 分钟技术容灾能力可用性5 个 999.999%5 分钟极高可用性
好比说某个系统网站整年稳定性达到 4 个 9 ,意味着整年服务不可用的时间小于等于 53 分钟。
稳定性技术策略
稳定性的技术策略,是咱们本文介绍的重点,从大的方面来讲,稳定性技术策略包含:监控,冗余,限流,降级,回滚,重试。
监控
监控是指对整个系统服务进行实时的监控操做,准确反馈系统运行状态,可以作到及时发现异常故障,记录详细日志与数据,提升故障发现,定位,解决的效率。从而提升系统服务总体稳定性。
监控是保证稳定性最基础工做。咱们将重点介绍监控须要从几个方面考虑? 有哪些监控方向?
监控能够分为如下几类来进行:
流量监控
流量监控包括:PV、 UV、 IP,热门页面,用户响应时间。
这些基本的流量指标就不在这里向你们详细说明了,若是有不太清楚的同窗能够本身搜索一下。
在流量监控这块,咱们须要注意的是:流量毛刺。流量毛刺每每表明了系统某个风险点或者异常状况的发生。
一个正常业务的流量趋势具有周期一致性特征。好比说,一个业务天天的流量峰值通常在中午 12:00 和下午 18:00,那么这种峰值在没有特殊状况出现的前提下,应该会遵循该峰值时间规律。 那么流量毛刺是啥呢? 以下图所示:
从图中左侧部分能够看到,8 点钟有流量的突增,这时候咱们须要确认为何会有流量的突增。是业务的正常表现,仍是有其余的异常流量进入。
从图中右侧部分能够看到,每条曲线表明了每一天的流量统计,红色曲线相对于其余几天的流量曲线在凌晨 3:00 和早上 8:00 的时候有明显的流量毛刺,这时候咱们就须要确认是什么因素形成流量数据的突变。
经过对于流量毛刺的观察,可以让咱们及时了解业务中的风险,及时作好预警与准备。
业务监控
业务监控是根据业务属性来定义监控指标,能够用于断定总体业务的运转是否正常。不一样业务类型监控的指标确定有所不一样,好比电商场景、物流场景、游戏场景是彻底不一样的监控方向。
咱们拿一个电商交易业务系统来举例,看看有哪些监控指标?你们能够参考着思考本身目前负责的业务指标。举例来讲针对一个电商交易系统咱们能够监控的业务指标有:
用户下单监控:秒/分/时 用户下单统计 ;
用户支付监控:秒/分/时 用户支付统计;
用户退款状况:秒/分/时 用户退款统计;
商品库存状态:库存消耗/剩余统计;
业务 GMV 监控:业务总体销售额统计;
商家在线状态:监控商家在线状态;
促销运营监控:监控促销金额与数量。
在业务监控中,还须要重点关注业务转化漏斗概念。流量漏斗能够看出业务转化率以及用户的访问深度。它是业务健康程度的监控,也是部分需求效果的衡量标准。
机器监控
机器监控须要关注的内容,应该是后台研发比较熟悉的部分。 主要监控方向包含下面几个部分:
固然在 linux 系统中,也有各类经常使用指令,来进行该类数据的收集:top、free、ping、iostat、netstat。
对于 Java 系统来讲,须要进行 JVM 层面的监控内容,好比说:gc 的状况,线程建立销毁状况,full gc 状况,内存不一样模块使用状况等。 JVM 一样也提供了指令集,方便咱们进行信息的查找:jstat、jps、stack、jmap、jhat 等。
日志记录
在日志的打印过程当中,咱们须要注意日志的打印规范,日志打印内容应该包含对于问题排查有益的信息,而且日志格式清晰,可解析性高。日志通常是打印到服务器磁盘上面,可是因为单机磁盘能力有限,而且对于大型分布式系统来讲须要总体收集不一样服务器模块的日志,进行统一分析,提升问题排查效率。这时候就须要一个集中式的日志中心。
日志中心的核心能力通常包含:获取日志、存储日志、展现日志、分析日志、报警服务。
相对比较简单的实现方式能够采用ELK快速搭建本身的日志中心。
咱们利用 kafka 将日志信息,进行异步广播,而后进行日志的解析,存储到 ES 检索系统中,利用 kibana 来进行日志的检索、查看等。进一步提高日志的有效管理。
冗余
冗余的对立面是单点。冗余能够有效的减小单点问题形成的影响。你们能够思考一下,若是一个系统服务只部署到一台机器,机器服务挂掉以后,意味着服务不可用,依赖于它的服务也会出现异常,最坏的状况可能会形成雪崩。
为了简化冗余的思考,咱们将整个应用后台架构简化为四层架构,以下图所示:
最上层是用户访问,而后到反向代理,Nginx 为流量入口; 而后到站点应用,好比说我们的 Tomcat 或者 Jetty 应用服务器; 最后是数据层 db;为了性能优化增长了 Cache 服务。
你们思考一下,若是这几层服务,所有的都是单点,单点就是咱们只有一个机器去部署这些服务。Nginx 只有一台机器,Server 应用也只有一台机器。若是机器宕机会形成什么样的后果?会直接致使整个系统服务不可用,这个就是单点的风险。
彻底依赖一个单点 没有任何冗余备份,致使服务的稳定性很是脆弱。
怎么去作冗余呢?
对于 Nginx 层与 Server 层,咱们能够从下面几个方向考虑冗余:
多机部署:同一个机房内,部署多个服务节点,其中一台挂掉,还有同机房的冗余备份;
跨机房部署:不一样机房内,部署多个服务几点,其中一个机房断电或者其余异常状况,还有其余机房来备份提供支持;
异地多活:若是全部机房都在同一个城市,就会形成地域单点,好比说城市光纤异常。这时候异地多活部署就会减小这部分影响。
对于数据层面好比 MySQL、Redis 都有自身提供的冗余方案。 MySQL 自身提供了主从部署,主从同步的机制,系统服务能够进行读主写从操做。
Redis 也相似,提供了集群冗余方案:主从配置,哨兵机制,集群模式。
Redis 集群模式可以实现数据分区冗余备份,主从同步,多主容灾,故障自动转移能力。
冗余的思路,在业务实现方向也能够落地考虑,好比说重要数据的多介质存储;重要组件的多版本选择等等。
限流
大型微服务架构中的任何服务节点,无论我们怎么优化,怎么拓展,都会有能力上限。若是达到能力上线,系统服务奔溃的可能性增长,这种状况也很容易形成整个微服务应用的雪崩效应。
做为一个面向用户的网站,有时候咱们会面对流量激增的情形,若是这时候达到了咱们某个或者多个服务的能力上限,咱们应该怎么保证系统的稳定性?
限流在这种情形下就起到了做用。
限流的目的
就是当服务器的压力剧增的状况下,为了保证服务不被拖垮,对一些流量采起拒绝或者降级的策略,以此来保证核心服务的正常运转。这是一种有损的技术手段。
将部分流量进行限制速率,控制输入和输出,将超过限制速率部分的流量,进行拒绝服务、或者排队等措施。以此来达到系统的自我保护目的。
限流策略:
限流策略有三种经常使用方式:
1. 总量计数限流:并发量或者访问量超过设定的阈值,将拒绝提供服务;
2. 漏桶限流算法:一个固定容量漏斗,任意速率流入或者生成并发或者访问,但会以一个固定的速率执行这些并发或者访问。若是超过固定容量的部分将被拒绝;
3. 令牌桶限流算法:一个固定容量的令牌通,令牌按照固定速率放到桶中,请求到来时候先去令牌通获取令牌,若是获取到则能够进入业务逻辑部分,获取不到则不会执行。
三者的区别:
限流的维度
以下图所示,限流思考从三个维度去思考:
限流的实现
1. 基于 AtomicLong 来实现单机(接口)总量计数法限流;
2. 基于 Semaphore 信号量来实现单机(接口)总量计数法限流;
3. 利用 Guava limiter 来实现令牌通的算法;
4. 对于分布式限流,咱们能够考虑,利用 Redis 的 Incr 来进行实现。
降级
降级的目的
1. 削弱非核心服务资源占用;
2. 保证业务核心服务稳定性。
举例来讲:
一个交易平台,有用户下单,支付等功能,同时也有用户评论,商品推荐,广告推荐等模块。在促销活动期间,用户大批量的进入,那么这时候因为功能模块很是多,流量或者机器资源消耗很是大。形成系统总体负载太高。那么极可能出现一个可怕的状况,用户没办法进行正常交易。
面对这种状况,咱们应该怎么作?这时候降级就体现了它的实用价值。
降级策略
降级策略有不少方面须要思考与落地,在这里总结一下常常用到降级策略。
页面降级:非核心页面模块,占用紧张资源,关停该页面,减小访问;
服务降级:将功能分类,分为核心服务与非核心服务,将非核心服务进行关停;
依赖降级:将依赖服务梳理分类,保证核心依赖的稳定,将非核心进行降级关停;
读写降级:将直接读写数据库切换为读写缓存; 对于缓存依旧能够进行备份冗余;
延迟降级:页面的异步加载策略; 数据写入异步消息队列等。
降级实现
降级就须要一个分布式开关,经过开关来肯定降级策略的启动与否。 分布式开关的实现方式,咱们也简述一下:
基于 Redis 实现;
基于 ZK 来实现;
基于内部数据库来实现。
每一个具体的实现方式你们若是感兴趣能够查阅一下资料,基本上都是功能实现相对简单。
合理降级了解了降级方法以后, 咱们还须要清楚不是全部服务都能降级,也不是等到故障发生了之后,才去选择或者肯定哪些服务能够降级。故障的降级策略必定是要提早去规划与思考。
系统或者服务须要分为核心系统和非核心系统(核心服务和非核心服务)来区分。核心服务是咱们力保不能有任何问题的主流程服务 P0; 非核心服务,又能够根据重要性进行再次分层。能够划分为 P一、P二、P3 服务。
P0 服务网为主服务,是力保稳定性的对象,他们挂了整个业务也就崩溃;
P1 服务为与紧密主服务相关,但能够后续异步补偿来操做的服务,好比说,结算流水,订单统计;
P2 服务与主服务有点相关,但关闭了对主服务任何业务逻辑没有影响,好比说,订单评价,商品推荐等;
P3 服务于主服务没有相关,关闭以后对主服务没有任何影响 好比说,广告推荐,用户喜爱,评论浏览等。
在梳理服务等级的时候,须要注意 2-8 原则 也就是 20% 的系统为核心系统,80% 的系统为非核心服务。
回滚
根据经验,线上的大部分 BUG 都是因为新需求或者新的工程改动形成的。
那么当系统出现 BUG 或者不稳定的时候,考虑到寻找或者排查问题耗时会比较久,咱们通常都会选择先回滚而后再去寻找问题具体缘由。这种方式在必定程度上保证了系统的稳定性状态。
回滚定义:快速恢复到变化以前的状态,让程序或者服务恢复到改动以前的稳定状态。回滚目的:及时止损,减小线上问题排查付出的代价回滚影响:新改动的需求会延迟生效
那么咱们回滚的方向又有哪些呢?
回滚方向:
1. 代码版本,也就是新旧代码的转换;
2. 系统服务,就是讲新上线部署的功能给予回滚操做,让服务恢复到新上线前的状态;
3. 数据内容,将修改的数据内容从新修改成历史数据版本。
怎么才能科学的回滚?
若是想把回滚的工做作好,须要处理好下面的主要内容:
发布信息规范:每次发布包,都有惟一的版本号;命名必定要规范。包含主要内容。 举例:工程名称 - 模块名称 - 代码版本 - 环境类型 - 日期版本 .jar(war)
代码管理科学:代码分支管理科学、 代码 review 机制、工程结构统一化。
代码 review 时机:
大版本(需求)代码必须 review;
线上 case 修复,代码必须 review;
测试前代码 review (保证测试质量);
周期固定时间,造成团队习惯。
数据管理规范:避免线上库直接操做、任何变动必须有回滚脚本、线下验证 。
注意事项:
尽可能避免线上数据库手动操做;
若手动,须要执行详细规范;
不断设计减小手动操做频次。
工程上线规范:上线窗口避免流量高峰,灰度验证避免全量上线,及时验证回归测试,上线通告。
重试
重试目的
配合超时机制,正确的获取结果,同时保护系统资源服务;
利用屡次访问策略,减小外部抖动对系统结果形成的影响;
借助幂等概念,保证信息提交成功,达到分布式一致性。
重试的场景能够有 异常重试,超时重试。
异常重试:咱们访问某个依赖接口的时候,若是出现接口返回异常的状况,咱们能够进行访问重试,从而获取正确结果。
超时重试:接口在规定的超时时间内没有获得相应的结果数据,进行重试操做。
全局思考重试策略
如何进行合理的超时重试策略设定,须要结合业务特色来进行详细的规划与测试。若是设定很差,极可能形成线上问题。
超时时间过长,可能致使服务阻塞; 超时时间过短,可能致使服务调用成功率下降。若是成功率下降,可能就会致使重试的几率加大。 重试必然会致使新的请求发生,增长一次访问时间,可能在用户体验上存在影响。
若是不断的重试,极可能致使不断的新建访问线程,重复请求,致使三方接口的压力。
因此超时时间 重试策略 都须要根绝咱们业务特色进行验证与设计,避免上面介绍问题的出现。
峰值应对策略
当咱们业务系统须要进行运营促销活动的时候,或者面临特殊日期将要给网站带来高于平时流量的时候,咱们须要作好应对流量峰值的准备。咱们须要系统的思考如何在系统峰值时刻保证咱们大型微服务系统的稳定性。
咱们将峰值应对按照时间维度进行划分:事前,事中,过后。
事前
前期准备
肯定模块:肯定本次峰值影响的工程或者服务,梳理必定要完整;
团队组建:根据影响模块,肯定本次维稳参与同窗(注意跨团队),确认分工;
合做约定:周期性的沟通,好比周会、约会、事前会议、过后总结会议。
数据预估
容量预估方向:
数据预估的时候不只仅要考虑峰值的应对时候的容量冗余,同时也要考虑数据长期增量的准备。
系统压测
系统压测的维度由小到达来讲:
单接口压测:接口维度的压测,人工根据接口模型进行压测数据;咱们可使用 Apach ab、Http load 来进行。
单机初级压测:针对机器维度来进行总体压测,能够人工构造数据也能够线上访问流量的复制来构造压测数据。咱们可使用 Jemeter、LoadRunner、tcp dump 等相关工具来进行。
单机负载均衡压测:也是针对单机维度来进行压测,与初级压测不一样的是,根据负责均衡,将线上流量进行实时转发,将流量比例向压测机器倾斜,从而达到压测的目的。
全链路压测:全业务后台服务总体压测,复制线上真实流量,进行压测数据的改造,而后高并发的访问业务系统,提早相对真实的模拟峰值到来的情形。
全链路压测是最困难,涉及面最广的一种压测方式。同时也是最能发现系统瓶颈的一种方式,全链路压测的挑战有:
困难1:链路梳理复杂度;
困难2:多模块,多服务,多团队协同;
困难3:寻找短板,避免系统雪崩风险;
困难4:压测数据准备,脏数据处理;
困难5:压测统筹安排,数据采样对比。
全链路压测的流程如图所示:
容灾演练
目的
主动触发异常,熟悉异常处理流程;
验证故障处理规范,不断完善规范;
验证服务异常状态,验证报警机制。
步骤:
目前内容,评估影响,方案确认;
制定故障 SOP 手册,详细到每一步执行;
根据 SOP 进行问题解决执行操做;
记录故障数据与现象,监控报警确认;
故障分类:能够快速解决,须要外部支持。
容灾演练的 SOP 建设:
服务巡检
在峰值到达以前的一段时间里,咱们须要对系统服务总体巡检,确保的咱们的各项指标都能正常工做,及时发现可能存在的风向。
定事:
1. 对业务、流量、系统、机器、日志 进行数据指标的 check ;
2. 确保主要数据无遗漏,不重复,没错误。
定人: 专人专事,责任明确,分工合理,推动平常巡检工做 。
定时:
1. 根据业务特色周期性的进行服务巡检,好比天天一次,每周一次;
2. 根据业务特色,合理的安排巡检的时间,好比说中午、下午。
定方案: 根据巡检出现的异常数据或者不合理数据,进行解决方案的制定 方案必须可执行同时有完成时间点。
事中
峰值应对值班
在面对峰值期间,咱们须要保证团队资源的稳定,须要安排核心人员进行值班操做。值班过程当中须要作一下工做:
服务观察:业务数据,服务监控,日志报警,趋势检测; **熟悉 SOP **:容灾操做 SOP ,值班 SOP ,同步 SOP;组织形式:站会,日报,总结。
数据观察同步
为了让团队其余人或者合做团队了解当前的系统运行状况,咱们须要在固定的时间里同步相关数据,及时检查数据走向与趋势。
天天固定时间进行数据同步(尽可能选择峰值时间段);
数据同步对象包含:业务、PM、QA、RD 多个团队;
统计指标注意跨团队的理解程度(可理解的形式来描述);
对比属性,好比说目前峰值是上次活动峰值的多少倍。
线上紧急状况处理
处理准则:
这里特别重要的一点准则就是,快速止损是第一要务,问题排查以及解决是止损以后的动做。
这时候在快速恢复线上服务的时候,就能考察咱们前期的容灾演练的效果了。
上面图形展现的操做规范都应该在容灾 SOP 建设中覆盖到。
过后
1. 全部报警异常的梳理与解决,全部不规范性的讨论与优化;
2. 根据真实的场景进行 SOP 的优化,这个 SOP 可能包含我们的值班 SOP 以及容灾演练 SOP 的建设;
3. 复盘讨论,须要根据业务数据、流量数据、系统服务状况统一来进行复盘整理。复盘的边界,不只仅是应用后台,还应该也包含前端研发、SRE、运营产品、中间件平台等。
复盘讨论的内容通常包含:
应用后台: 峰值期间业务数据、服务性能数据、总体稳定性数据;
前端研发:APP crash 率、性能表现状况、DAU、各页面转化率;
SRE 运维:机房总体状况、机器负载状况、网络宽带状况、资源利用率等;
运营产品:业务指标完成度、同比(环比)状况、将来规划;
中间件平台:中间件峰值稳定性状况、容量状况、服务能力状况。
性能优化策略
性能优化重要性:
用户角度:网站体验重要衡量标准;
系统角度:稳定性的基本要求保障;
研发角度:自身技术能力的竞争力。
在这里因为篇幅有限,咱们不针对每一块优化的技术策略进行详细的讲解,咱们重点介绍一下技术优化的总体方向与策略,以及如何选择方案。
咱们在考虑网站性能优化方案选择的时候,从收益与投入两个方向综合考虑。
应用技术栈对于后台研发同窗来讲是相对比较熟悉的技术内容,因此投入会相对较少,收益却会很大。由于大部分性能优化的问题,还都在于代码与技术方案层面。
数据库方面也是须要重点投入的方向,可以避免业务数据获取以及存储方面的瓶颈。
其余的三个方向网络优化,容器组件,底层环境都不是业务后台研发同窗常常学习的方向。因此这几块优化方向能够考虑和公司的运维同窗进行共同思考与建设。
固然性能优化是一个长期重复执行的动做,须要进行不断的总结,梳理出来符合本身业务的性能优化策略。
总结
本文介绍了大型微服务架构后台应用系统稳定性技术策略的介绍。每一个技术点都须要咱们持续的思考与落地,全面总体的思考稳定性相关的建设动做。与此同时,还进行峰值应对过程当中稳定性的保障工做如何开展,但愿对你们有所帮助。