精华内容
下载资源
问答
  • 稳定性全系列()——如何做好系统稳定性建设

    千次阅读 多人点赞 2019-12-24 00:49:37
    、背景介绍 二、故障源的分类 三、稳定性建设四要素 第要素:人 第二要素:工具 第三要素:预案 第四要素:目标 四、稳定性建设四个方向 第个方向:根基要抓牢(45%) 第二个方向:工作在日常(30%)...

    目录

    一、背景介绍

    二、故障源的分类

    三、稳定性建设四要素

    第一要素:人

    第二要素:工具

    第三要素:预案

    第四要素:目标

    四、稳定性建设四个方向

    第一个方向:根基要抓牢(45%)

    第二个方向:工作在日常(30%)

    第三个方向:预案是关键(15%)

    第四个方向:容量是核心(10%)

    五、稳定性建设本质

    六、总结


    一、背景介绍

    在移动互联网时代,用户群的积累比之前更容易,但同样,也会因为糟糕的用户体验,而快速流失用户,哪怕是号称独一无二的12306网站,也在不断优化系统来提升用户体验;而在后移动互联网的物联网时代,软件工程师需要和硬件工程师配合,来保证提供的服务稳定和可靠。对,我们的产品就是为了实现用户价值,并提供非凡用户体验!

    如果说良好用户体验是增长的基础,那么良好的操作性、稳定的使用体验就是用户体验的基础,排除掉软件可操作性(这一块需要依靠专业的设计师),剩下的就是客户端(这里的客户端包括各种小程序、WebApp、H5页面等)和服务端,这一切都基于我们软件工程师来构建可靠、稳定的软件系统。 然而,随着我们服务的用户量越来越多,服务复杂度也越来越高,我们的系统为了可维护性,也会在业务架构和系统架构上进行调整,现在流行的微服务架构也因此应运而生。然而微服务架构也并不是没有副作用,例如它会增加维护成本和系统稳定性建设的成本。

    那么,什么是系统稳定性?这里我们引用百度百科的定义:系统稳定性是指系统要素在外界影响下表现出的某种稳定状态。为了方便,本文阐述的系统主要指软件系统。那么如何衡量系统稳定性的高与低呢?一个常用的指标就是服务可用时长占比,占比越高说明系统稳定性也越高,如果我们拿一整年的数据来看,常见的4个9(99.99%)意味着我们系统提供的服务全年的不可用时长只有52分钟! 它其实是一个综合指标,为什么这么说?因为我们在服务可用的定义上会有一些差别,常见的服务可用包括:服务无异常服务响应时间低服务有效(逻辑正确)服务能正常触发等。

    二、故障源的分类

    系统的故障源一般可以分为两大类,一类是人为因素,另一类是自然因素

    常见人为因素导致的故障如下:

    人为因素我们要尽可能的事前(故障发生前)避免,因为这些原因引发的事故很可能会导致数据丢失或错乱、资金受损等较严重后果,而且除了重启或修复后重新上线外没有过多有效的止损手段。人为因素导致的故障往往会导致软件工程师的内心受到严重打击,工作和专业能力受到质疑,造成“人财两空”的后果,“我拼了老命来产出,结果却给自己挖了个坑”是故障责任人内心的真实写照。

    我们再来说说自然因素,自然因素受很多客观因素的影响,往往不受控制,无法避免。

    常见的自然因素导致的故障如下:

    自然原因导致的故障可大可小,虽然无法避免,但由于没有第一责任人,避免了“人性拷问”,软件工程师可以和运维部、安全部的同学协作起来处理故障。

    三、稳定性建设四要素

    “如果事情有变坏的可能,不管这种可能性有多小,它总会发生。”,残酷的墨菲定律预示着我们对自己系统提供的服务不要太乐观,接下来,我们说说如何建设系统稳定性,人为因素的根源一方面是专业能力不足,经验不足,另一方面很多都是无心之失,所以需要通过流程、规范来保住“底线”,减少人为因素导致的故障,而自然因素导致的故障往往具有突发性,需要联合多个团队协作来解决故障。

    稳定性建设四要素工具预案和目标

    第一要素:人

    我们先来说“人”这一要素,它需要回答如下5个问题:

    • 谁应该参与稳定性建设?

    • 如何降低犯错的概率?

    • 如何提高稳定性意识?

    • 如何定责?

    • 如何激励?

    稳定性建设工作需要老板支持,它的实施一般需要开发测试运维安全还有产品等同学参与,而且主导方应该是开发、测试和运维。确定了参与方后,就可以做关键的一步:“参与稳定性建设的每个团队都需要在OKR中背负一部分稳定性指标”,这也是为什么说稳定性建设工作需要老板支持,因为和绩效考核相关。

    稳定性工作,规范先行。OKR的部分只是让各参与方在稳定性方面工作的投入变成合规化,平时如何去参与稳定性建设还得“有迹可循”,对于开发和测试来说就是要根据公司的当前技术体系去建设开发规范提测规范测试规范上线规范、复盘规范等。我们拿和软件开发最相关的开发规范来说,开发规范是对开发人员的要求,让开发人员知道什么是必须要做的、什么是推荐的、什么是应该避免的。通常开发规范至少应该包括如下几个部分:

    编码规范:对外接口命名方式、统一异常父类、业务异常码规范、对外提供服务不可用是抛异常还是返回错误码、统一第三方库的版本、哪些场景必须使用内部公共库、埋点日志怎么打、提供统一的日志、监控切面实现等,编码规范除了能规范开发的编码行为、避免犯一些低级错误和踩一些重复的坑外,另一个好处是让新入职的同学能快速了解公司的编码原则,这点对编码快速上手很重要。这里再重点说一下为什么要统一异常父类和业务异常码,例如虽然不同模块(这里的模块指的是能独立部署的项目)可能有不同的异常父类,比如订单模块的异常父类是OrderException、交易支付模块的异常父类是TradeException,而OrderException和TradeException的父类是BizException(当然BizException是定义在一个通用共公共库中的),而我们也需要去统一异常码,比如200代表正确的返回码,异常的返回码是6位数字(前3位代表模块,后3位代表异常类型),有了统一的异常父类和异常码后,很多切面就都可以由公共库来做了,比如统一的监控、统一的出入口日志打印,统一的异常拦截,压测标识透传、特殊的字段埋点等,千万别小看这些,这些能在未来持续提升研发效率,降低稳定性工作成本。

    公共库使用规范:为了能对通用功能进行定制化改造和封装,公司内部肯定会有一些公共库,例如日志库、HTTP库、线程池库、监控埋点库等,这些库都“久经考验”,已经被证实是有效且可靠的,这些就应该强制使用,当然为了适应业务的发展,这些公共库也应该进行迭代和升级。

    项目结构规范:为了贯彻标准的项目结构,一方面我们需要为各种类型项目通过“项目脚手架”来创建标准的项目结构原型,然后基于这个项目原型来进行开发,统一的项目结构一个最显著的好处是让开发能快速接手和了解项目,这种对于团队内维护多个项目很重要,人员能进行快速补位。

    数据库规范:数据库连接资源堪比CPU资源,现在的应用都离不开数据库,而且通常数据库都属于核心资源,一旦数据库不可用,应用都没有太有效的止损手段,所以在数据库规范里,库名、表名、索引、字段、分库分表的一些规范都必须明确,这里特别提一点,就是分表数量不要用2的幂(比如1024张表,很多人认为使用2的幂分表数在计算分表时用位运算会更快,但这个开销相比数据库操作其实可以忽略),而应该用质数(比如最接近1024的质数应该是1019),采用质数分表数能让数据分的更均匀

    这会引发另一个问题,那就是我们有这些规范,那么如何让开发来知晓和遵守?一方面是设定合理的奖惩机制(例如由于没有遵守规范而引发的线上事故要严惩),另一方面就是——考试!没错,就是考试,将这些规范和历史的线上事故整理成试题,让新老开发定期去考试,考试是一种传统的考核机制,我们可以把规范和公共库的更新部分,也及时加入到考试试题中,来督促大伙及时学习。

    有了OKR、规范和考核机制,加上我们定期宣导,相信各成员的稳定性意识会有显著提高。

    事故定责一般是比较复杂的过程,除非事故原因非常简单明了,但实际上事故原因常常涉及多个团队,如果责任分摊不合理,难免会引发跨团队的争吵,合理的做法是引入第三方稳定性团队来干预,例如滴滴的星辰花团队,星辰花会撰写定责指南,并制定一些相关流程机制。

    当然,如果达成稳定性年度目标,也应该对这些团队进行适当表彰。

    第二要素:工具

    工具意味着手段,要做好稳定性建设,强大的支持工具和平台是不可缺少的,常见的工具和平台包括:日志采集分析检索平台(例如滴滴的Arius)、监控告警平台(例如滴滴的Odin Metrics)、分布式追踪系统(例如Google的Dapper、滴滴的把脉平台)、自动化打包部署平台(例如滴滴的One Experience)、服务降级系统(例如滴滴的SDS)、预案平台(例如滴滴的911预案平台)、根因定位平台(记录所有故障发生前所有系统变更事件)、放火平台等。

    强大的工具能回答如下3个关键问题:

    • 我们能做什么?

    • 我们能做到什么程度?

    • 如何降低稳定性工作成本?

    工具本质上是手段,它能降低我们在稳定性工作上投入的成本,例如有了监控告警平台,我们就不需要专人时刻盯着日志或大盘,有了分布式追踪系统,问题定位会更有效率,有了降级系统,一些故障能自动控制和恢复,不用我们再上线一次。要想做好稳定性工作,工具必不可少,没有工具,稳定性建设总是低效的。

    其实公司内建的公共库也属于工具的一种,像滴滴内部的公共库,业务系统接入Odin Metrics和把脉几乎不要做额外的工作(当然接入把脉需要提日志采集工单,头疼),千万不要吝啬在工具方面的投入,很多开源框架可以拿来用或拿来参考,工具和平台可以内部进行互通和联动,这样可以建成一站式的稳定性工作平台。

    第三要素:预案

    紧急预案是我们在故障发生时的行动指南,这在故障可能涉及到多个团队、故障进展需要周知到多个团队时特别有用。

    完善的紧急预案能回答如下4个问题:

    • 故障发生时我们该做什么?

    • 谁来指挥?

    • 谁来决策?

    • 我们如何善后?

    当一个不那么容易定位的故障发生时,你应该做的第一件事应该是什么?这在不同公司、同一个公司同一个团队的不同成员恐怕都会给出一个不同的答案,而在滴滴内部,我们大多会第一时间通知团队内其他成员、Leader(寻求帮助)和客服、上游业务开发等可能的影响方 (问题周知)。当这一步做完以后,一般就会有一部分同学加入问题排查和止损,然而介入的人多了,排查和止损的效率不一定会成比例的提升,这时候协调者很重要,协调者要避免介入的同学在做重复工作,协调者还需要持续和客服、上游业务开发等影响方沟通(我们曾经就经历过由于问题排查问题进度没有及时有效和业务方沟通,业务方将故障升级的case)。对于排查问题和止损的同学来说,要操作某个开关,有可能还要去查代码看开关的名字是什么,还有可能关掉一个功能需要操作多个开关,这些在紧急时刻都有可能由于慌乱而出错。而且什么条件下才能操作开关,谁能决定应不应该操作开关,恐怕在当时很难去做最正确的事情,而这一切,没错,都应该提前写到预案中!!!

    紧急预案一般要包含如下内容:

    1. 故障发生时应该通知哪些人或团队。

    2. 如何选出协调者,什么情况下该选出协调者。

    3. 协调者的职责有哪些。

    4. 需要操作开关时,谁有权利决策。

    5. 常见故障以及对应的止损方式。

    6. 止损的原则是什么,什么是最重要的。

    7. 善后方案谁来拍板。

    预案很重要,完备的预案能降低故障定位和止损的时间,提升协作效率。

    第四要素:目标

    如何衡量稳定性建设工作是有价值的?如何考核稳定性建设工作达没达标、做的好不好?这些都能在稳定性建设的目标中找到答案。

    稳定性建设的目标主要用来回答如下2个问题:

    • 稳定性工作的价值是什么?
    • 稳定性工作如何考核?

    稳定性建设工作的价值不仅需要团队所有成员认可,更重要的是需要老板的认可,没有老板的认可,稳定性建设工作只是团队内部的“小打小闹”,难以去跨团队来体系化运作。

    稳定性建设工作的年度目标可以拿服务可用时长占比来定,也可以拿全年故障等级和次数来定,像滴滴这边,星辰花将故障等级分成了P0至P5六个等级,P0、P1、P2属于重大事故,是需要消耗服务不可用时长的(根据全年定的服务可用时长占比指标来计算出某个部门的全年服务不可用总时长),一旦年底某个部门的全年服务不可用时长超过年初设定的阈值,就会有一定的处罚,并影响部门绩效(之前达标也有奖励,但后来奖励取消了)。

    这里做一个汇总:

    四、稳定性建设四个方向

    前面我们提到的稳定性建设工作的四个关键点,但对如何落地阐述的并不多,这里结合作者多年的稳定性建设工作经验,谈谈稳定性建设工作的四个方向。

    第一个方向:根基要抓牢(45%)

    稳定性建设工作重在预防,根据作者多年的工作经验,至少6成线上故障都可以在预防工作中消除,我们需要投入45%的精力来做根基建设,所谓根基建设,就是把开发测试上线这三大流程做透!!下面列了几个关键点:

    Code Review:CR其实是一个很重要的环节,当一个开发整个编码和提测都可以自己闭环搞定时,时间一长就容易产生懈怠,这时候写隐患代码的几率会大大提高,CR的过程并不是diss的过程,这个一定要在团队内拉齐,相反,CR是一次很好的团队沟通和塑造自己影响力的机会。我就很佩服那些代码写得质量高并且能把整个流程讲顺的人。我们团队的项目都接入了全流程(例如滴滴的鲲鹏),分支合master必须要其他人Review,但这是“离线”的,没有代码作者讲的过程,效果没有几个人坐在小黑屋讲的好,只是更快而已。我们团队规定,大于等于4人日的项目需要进行小黑屋CR。CR还可以让其他成员来检测该代码实现是否遵循了开发规范,毕竟“先污染后治理”的成本太高,记住,CR一定是一个相互学习的过程

    设计评审:再也没有比糟糕的设计更有破坏力的东西了,设计评审和CR可以放在一起做,先评审设计再进行CR,有人就会说,都编码完了才进行设计评审是不是晚了?其实这要看情况而定,如果团队内部经常产出“糟糕设计”,那么我觉得设计评审就应该编码之前来做,但如果团队成员专业能力和经验都还不错,那么我们允许你再编码之后再做设计评审,而且编码的过程其实也是设计的过程,可以规避提前设计而导致后续编码和设计不一致的问题。设计评审的原则是,既要讲最终的设计方案,也要讲你淘汰的设计方案!

    提测标准:写完代码就可以提测了?当然不是,至少得完成补充单元测试、完成自测、完成开发侧的联调、通过测试用例(如果QA提前给了测试用例的话)、补充改动点和影响点(便于QA评估测试范围)、补充设计文档(对,现在滴滴的QA养成了读代码、看设计的习惯)这些步骤才能说可以提测了。当然,提测标准理论上是QA同学来定义的。

    测试流程:测试的全流程覆盖最好能做到全自动化,很多测试用例可以沉淀下来,用来做全流程回归,当然这需要系统支持。我也见过太多犹豫QA没精力进行全流程回归而导致问题没有提前发现而产生的事故,所以测试的原则是尽可能自动化和全流程覆盖,让宝贵的人力资源投入到只能人工测试的环节。

    上线流程:上线也是一个风险很高的操作,我们简单统计了19年的上线次数,光我们团队负责的系统就上线了五百多次。部署平台需要支持灰度发布、小流量发布,强制让开发在发布时观察线上大盘和日志,一旦有问题,能做到快速回滚(当然要关注回滚条件)。我们这边的做法是先小流量集群灰度(我们把单量少的城市单独做了一套小流量集群),再线上灰度,确保哪怕出问题也能控制影响。

    第二个方向:工作在日常(30%)

    俗话说养兵一日,用兵一时,平日的养兵其实也非常重要,这一方向我们需要投入30%的精力,需要我们做到如下几点:

    人人参与:团队内人人都需要参与稳定性建设工作,稳定性工作不是某个人的事情,所以我会要求所有人的OKR中都有稳定性建设的部分。做toC研发的同学,都养成了带电脑回家的习惯,哪怕是加班到晚上12点,当然在外旅游也带着电脑,手机24小时保持畅通;稳定性已经成为了生活本身。

    持续完善监控告警:监控告警就是我们发现故障的“眼睛”和“耳朵”,然而大多数监控告警都需要我们手动一个个配置,随着业务的不断迭代,会有很多新接口需要添加监控,一些老的监控的阈值也需要不断调整(否则大量告警会让人麻木),所以监控告警是一个持续优化的过程。

    及时消灭线上小隐患:平日发现的一些问题要及时消灭,很多线上事故在事前都有一定预兆,放任平时的一些小问题不管,到后面只会给未来埋上隐患。

    跨团队联动:稳定性肯定不是一个团队的事情,一些降级方案可能涉及多个团队的工作,所以定期的跨团队的沟通会议是很有必要的,要大伙一起使劲才能把事情做好。

    复盘机制:对出过的线上事故一定要及时的进行复盘,通过复盘来发现我们现有流程、机制是否有问题,让大伙不要踩重复的坑,并不断完善我们的紧急预案。复盘虽然属于事后的行为,但很重要,我们需要通过复盘来看下次是否能预防此故障,或者是否能更快的定位和止损。

    会议机制:稳定性周会、稳定性月会,我们通过各种定期的会议来总结一些阶段性进展和成果,拉齐大家认知,这也是大伙日常稳定性工作露出的一个机会,所以非常重要。

    第三个方向:预案是关键(15%)

    我们通常都会忽视预案的作用,因为预案整理起来确实比较麻烦,预案也需要随着功能的迭代而不断更新,否则将很容易过时,而且预案在平日非故障期间也确实没有发挥作用的机会。但我们不得不承认紧急预案相当重要,特别是当我们去定位和止损一个比较复杂的线上问题时。

    我们需要在预案的制定和演练上投入15%的精力,可以从如下三个方面着手:

    分场景制定和完善紧急预案:如果我们还没有紧急预案,那第一步就是分类分场景整理下历史上经常发生的线上事故,例如MySQL故障预案、MQ故障预案、发单接口故障预案等。而且预案有可能会被多人查看,一定要清晰易懂,如果某些预案是有损的,需要把副作用也描述清楚。

    通过放火平台来验证预案:借助放火平台和服务降级系统,我们可以通过主动给主流程服务的非核心依赖注入故障,来验证系统在遇到非核心依赖发生故障时,核心服务是否仍旧有效,如果某些预案无法做成系统自动的(比如某些预案有一定的风险或副作用),也可以在预发环境来验证该预案是否能达到预期效果,防止真正故障发生时“手生”。预案就是在这种不断演练过程中来优化和完善的,这样的预案才是动态的,才是活生生有效可靠的!

    第四个方向:容量是核心(10%)

    我们知道木桶效应,一个木桶能装多少水取决于最短的那块板,在分布式系统中也是如此,我们需要摸到分布式系统中的这块“短木板”才能知道整个系统的吞吐量(容量),如果我们没有这个值,老板问你明年单量要Double,问你要预算,要规划你凭什么给?最准确的容量预估方案就是——线上全链路压测。至于滴滴是如何做线上全链路压测,后续我会有专门的文章来阐述。

    我们继续探讨容量这个话题,我们应该投入10%的精力来摸容量、扩容量、水位预警等。容量也相当重要,根据我的经验,线上有大约10%的故障和容量有关,当遇到这种问题,最有效的解决方案就是扩容!关于容量,我们在日常需要做到如下三点:

    常态化的全链路压测:线上全链路压测必须定期举行,特别的在有大促活动时,也需要提前进行一次。因为随着业务的快速迭代,系统老的瓶颈可能消失,新的瓶颈可能出现,所以之前的全链路压测的结果将失效,我们需要定期去摸这个线上环境的这个阈值。

    定期进行扩容演练:在滴滴内部,我们会定期进行弹性云扩容演练,这在紧急情况下很有用,我们就曾经遇到过弹性云扩容比修改阈值重新上线更快解决问题的case。

    多活建设:我们知道多活主要是为了容灾,但其实多活实际上也从整体上增加了系统容量,所以也属于容量扩充的范畴,一旦某个机房遇到瓶颈,我们可以分流到其他机房。当然多活建设需要一定成本,业务量大到一定程度才需要投入。

    说了这么多,我们也放张图来进行总结:

     

    五、稳定性建设本质

    就像我们做项目要“面向风险”编程一样,系统稳定性建设的目的其实就是为了应对未来的风险,和未来风险做对抗(哪怕我们有些手段将未来的风险变小)。如果非让我们探究稳定性建设的本质,我觉得稳定性建设的本质是将系统和系统间未来不可控的因素逐渐变为可预见,可控的因素,并着手去一一解决的一个过程。

    六、总结

    做稳定性建设一定要结合公司或组织的实际情况,量入为出,最合适的方案才是最好的方案。结合咱们上述讨论的几点,我们可以画出稳定性建设的房子,如下:

    希望我们能像建筑师一样,给业务构建一套稳定、可扩展、性价比高的房子!!!

     

     

    其他稳定性全系列文章:

    稳定性全系列(二)——如何做线上全链路压测 https://blog.csdn.net/manzhizhen/article/details/104439629

    展开全文
  • 无论是哪种方式,都会面临个问题:如何确定什么时候降级,什么时候恢复?一般有两种方式, 其是人工确认,通过监控报警等反馈机制,人工识别故障,推送降级,待故障恢复后在手动回滚; 其二是自适应识别...

    本文来自kriszhang老师的分享。针对高可用的方法,思考框架如下:

    • 指导原则

    • 高可用

      事前

      • 副本技术

      • 隔离技术

      • 配额技术

      • 探知技术

      • 预案

      • 监控和报警

      • 降级

      • 回滚

      • failXXX系列

    • 高并发

      • 多线程

      • 扩容

      • 缓存

      • 异步

    1、指导原则

    书中所列举的,里有一些可能并不是原则,而是技巧。我理解的原则如下:

    高并发原则:

    1. 无状态设计:因为有状态可能涉及锁操作,锁又可能导致并发的串行化。

    2. 保持合理的粒度:无论拆分还是服务化,其实就是服务粒度控制,控制粒度为了分散请求提高并发,或为了从管理等角度提高可操性。

    3. 缓存、队列、并发等技巧在高并发设计上可供参考,但需依场景使用。

    高可用原则:

    1. 系统的任何发布必须具有可回滚能力。

    2. 系统任何外部依赖必须准确衡量是否可降级,是否可无损降级,并提供降级开关。

    3. 系统对外暴露的接口必须配置好限流,限流值必须尽量准确可靠。

    业务设计原则:

    1. 安全性:防抓取,防刷单、防表单重复提交,等等等等。

    2. at least 消费,应考虑是否采用幂等设计

    3. 业务流程动态化,业务规则动态化

    4. 系统owner负责制、人员备份制、值班制

    5. 系统文档化

    6. 后台操作可追溯

    以上原则只是大千世界中的一小部分,读者应当在工作学习中点滴积累。

     

    2、高可用

    我们先说高可用的本质诉求:高可用就是抵御不确定性,保证系统7*24小时健康服务。关于高可用,我们其实面对的问题就是对抗不确定性,这个不确定性来自四面八方。比如大地震,会导致整个机房中断,如何应对?比如负责核心系统的工程师离职了,如何应对?再比如下游接口挂了,如何应对?系统磁盘坏了,数据面临丢失风险,如何应对?

    我想关于上述问题的应对方式,大家在工作中或多或少都有所了解,而这个不确定性的处理过程,就是容灾,其不同的‘灾难’,对应不同的容灾级别。

    为了对抗这些不同级别的不确定性,就要付出不同级别的成本,因此可用性也应是有标准的。这标准就是大家常说的N个9。

    随着N的增加,成本也相应增加,那如何在达到业务需要的可用性的基础上,尽量节省成本?这也是一个值得思考的话题。除此之外,100%减去这N个9就说所谓的平均故障时间(MTBF),很多人只关心那些9,而忽略了故障处理时间,这是不该的:

    你的故障处理速度越快,系统的可用性才有可能越高。

    上面扯了一些可用性概念上的东西,下面来说一下技巧。开涛的书中没有对可用性技巧做出一个分类,我这里则尝试使用‘事情’来分个类。这里的‘事’就是故障,分为:事前(故障发生以前)、事发(故障发生到系统或人感知到故障)、事中(故障发生到故障处理这段时间)、事后(故障结束之后)。

    按照上述分类,不同的阶段应有着不同的技巧:

    事前:副本、隔离、配额、提前预案、探知
    事发:监控、报警
    事中:降级、回滚、应急预案,failXXX系列
    事后:复盘、思考、技改

     

    事前

    副本技术

    大自然是副本技术当之无愧的集大成者,无论是冰河时代,还是陨石撞击地球所带来的毁灭性打击,物种依然绵绵不绝的繁衍,这便是基因复制的作用。副本是对抗不确定性的有力武器,把副本技术引入计算机系统,也会带来高可用性的提升。

    无状态服务集群便是副本的一个应用,因为没有状态,便可水平伸缩,而这些无状态服务器之间需要一层代理来统一调度管理,这便有了反向代理。

    当代理通过心跳检测机制检测到有一台机器出现问题时,就将其下线,其他‘副本’机器继续提供服务;存储领域也是经常使用副本技术的,比如OB的三地三中心五副本技术等,mysql主备切换,rabbitMQ的镜像队列,磁盘的RAID技术,各种nosql中的分区副本,等等等等,数不胜数,几乎所有保证高可用的系统都有冗余副本存在。

     

    隔离技术

    书上提到了很多种隔离:线程隔离、进程隔离、集群隔离、机房隔离、读写隔离、动静隔离、爬虫隔离、热点隔离、硬件资源隔离。

    在我看来,这些隔离其实就是一种,即资源隔离,无论线程、进程、硬件、机房、集群都是一种资源;动态资源和静态资源也不过是资源的一种分类;热点隔离也即是热点资源和非热点资源的隔离;读写隔离不过仅仅是资源的使用方式而已,相同的两份资源,一份用来写,一份用来读。

    因此,隔离的本质,其实就是对资源的独立保护。因为每个资源都得到了独立的保护,其中一个资源出了问题,不会影响到其他资源,这就提高了整体服务的可用性。人类使用隔离术也由来已久了,从农业养殖,到股票投资,甚至关犯人的监狱,都能找到隔离术的影子。

     

    配额技术

    配额技术通过限制资源供给来保护系统,从而提高整体可用性。限流是配额技术的一种,它通过调节入口流量水位上线,来避免供给不足所导致的服务宕机。

    限流分为集群限流和单机限流,集群限流需要分布式基础设施配合,单机限流则不需要。大部分业务场景使用单机限流足以,特殊场景(类秒杀等)下的限流则需限制整个集群。除此之外,限流这里我们还需要考虑几点:

    如何设置合理的限流值?限流值的设定是需要经过全链路压测、妥善评估CPU容量、磁盘、内存、IO等指标与流量之间的变化关系(不一定线性关系)、结合业务预估和运维经验后,才能确定。

    对于被限流的流量如何处理?有几种处理方式,其一直接丢弃,用温和的文案提醒用户;其二,静默,俗称的无损降级,用缓存内容刷新页面;其三,蓄洪,异步回血,这一般用于事务型场景。

    会不会导致误杀?单机限流会导致误杀,尤其当负载不均衡的情况下,很容易出现误杀;单机限流值设定过小也容易出现误杀的情况。

     

    探知技术

    其只用于探知系统当前可用性能力,无法切实提高系统可用性,做不好甚至还会降低系统可用性。压测和演练和最常见的探知技术 。压测分为全链路压测和单链路压测,全链路压测用于像双十一大促活动等,需要各上下游系统整体配合,单链路压测一般验证功能或做简单的单机压测提取性能指标。

    全链路压测的一般过程是:压测目标设定和评估,压测改造,压测脚本编写部署,压测数据准备,小流量链路验证,通知上下游系统owner,压测预热,压测,压测结果评估报告,性能优化。以上过程反复迭代,直到达到压测目标为止;

    演练一般按规模划分:比如城市级别的容灾演练,机房级别的容灾演练,集群规模的容灾演练(DB集群,缓存集群,应用集群等),单机级别的故障注入,预案演练等。演练的作用无需过多强调,但演练一般发生在凌晨,也需要各系统owner配合排错,着实累人,一般都是轮班去搞。

     

    预案

    预案一般分为提前预案(事前)和应急预案(事中)。提前预案提前执行,比如将系统临时从高峰模式切换成节能模式;应急预案关键时刻才执行,主要用于止血,比如一键容灾切换等。预案技术一般要配合开关使用,推预案一般也就是推开关了。除此之外,预案也可和限流、回滚、降级等相结合,并可以作为一个定期演练项目。

     

    事发

    事发是指当故障发生了到系统或人感知到故障准备处理的这段时间,核心诉求即是如何快速、准确的识别故障。

     

    监控和报警

    一般出现故障的时候,老板大多会有三问:为什么才发现?为什么才解决?影响有多大?即使故障影响面较大,如果能迅速止血,在做复盘的时候多少能挽回一些面子,相反如果处理不及时,即使小小的故障,都可能让你丢了饭碗。越早识别故障,就能越早解决问题,而这眼睛便是监控和报警了。监控报警耳熟能详,这里不多赘述。

     

    事中

    事中是指当故障发生时,为了保证系统可用性,我们可以或必须做的事情。分为降级、回滚、应急预案(见上文,这里不多数了),faillXXX系列。

     

    降级

    降级的内涵丰富,我们只从链路角度去思考。降级的本质是弃车保帅,通过临时舍弃部分功能,保证系统整体可用性。降级虽然从整体上看系统仍然可用,但由于取舍的关系,那么可知所有的降级一定是有损的。不可能有真正的无损降级,而常说的无损降级指的是用户体验无损。

    降级一定发生在层与层之间(上下游),要么a层临时性不调用b层,这叫做熔断,要么a层临时调用c层(c层合理性一定<b层),这叫备用链路。

    无论是哪一种方式,都会面临一个问题:如何确定什么时候降级,什么时候恢复?一般有两种方式,

    其一是人工确认,通过监控报警等反馈机制,人工识别故障,推送降级,待故障恢复后在手动回滚;

    其二是自适应识别,最常用的指标有超时时间、错误次数、限值流等等,当达到阈值时自动执行降级,恢复时自动回滚。

    这两种方式无需对比,它们都是经常采用的高可用技巧。

    除此之外,我们还要注意降级和强弱依赖的关系。强弱依赖表示的是链路上下游之间的依赖关系,是’是否可降级‘的一种专业表述。

    我们再来看书中的一些降级的例子:

    ①读写降级,实际上是存储层和应用层之间的降级,采用备用链路切换方式,损失了一致性;

    ②功能降级,将部分功能关闭,实际上是应用层和功能模块层之间的降级,采用熔断方式,损失了部分功能。

    ③爬虫降级,实际上是搜索引擎爬虫和应用系统之间的降级,采用备用链路切换方式,将爬虫引导到静态页面,损失是引擎索引的建立和页面收录。

     

    回滚

    当执行某种变更出现故障时,最为稳妥和有效的办法就是回滚。虽然回滚行之有效,但并不简单,因为回滚有一个大前提:变更必须具有可回滚性。

    而让某一种变更具有可回滚的特性,是要耗费很大力气的。索性的是,大部分基础服务已经帮我们封装好了这一特性,比如DB的事务回滚(DB事务机制),代码库回滚(GIT的文件版本控制),发布回滚(发布系统支持)等等。

    我们在日常变更操作的时候,必须要确定你的操作是否可回滚,并尽力保证所有变更均可回滚。如果不能回滚,是否可以进行热更新(比如发布应用到app store)或最终一致性补偿等额外手段保证系统高可用。

    failXXX系列

    当出现下游调用失败时,我们一般有几种处理方式:

    1. failretry,即失败重试,需要配合退避时间,否则马上重试不一定会有效果。

    2. failover,即所谓的故障转移。比如调用下游a接口失败,那么RPC的负载均衡器将会调用a接口提供方的其他机器进行重试;在比如数据库x挂了,应用自适应容灾将对x库的调用切换到y库调用,此y库即可以是faillover库(流水型业务),也可以备库(状态型业务)。

    3. failsafe,即静默,一般下游链路是弱依赖的时候,可以采用failsafe,即可和failover相结合,比如failover了3次还是失败,那么执行failsafe。

    4. failfast,立即报错,failfast主要让工程师快速的感知问题所在,并及时进行人工干预。

    5. failback,延迟补偿(回血),一般可以采用消息队列或定时扫描等。

    上面的1,2,4是属于重试策略,即书中《超时与重试》章节所讲到的重试。重试有个问题:退避间隔是多少?重试几次?一般在下游临时抖动的情况下,很短时间内就可以恢复;但当下游完全不可用,那么很有可能重试多少次都不会成功,反而会对下游造成了更大的压力,那这种情况就应当做用熔断了。

    所以正确设定重试次数、选择退避时间等都是需要仔细思考的。我们在来说一下超时,超时只是一种预防机制,不是故障应对策略,其主要为了防止请求堆积——资源都用于等待下游请求返回了。堆积的后果自不用多说,重要的是如何选择正确的超时时间?书上只说了链路每个部分超时时间怎么配置,却不知道应配置多少,这是不够全面的。

     

    事后

    复盘、思考、技改。不多赘述。

     

    2、高并发

    如果仅是追求高可用性,这其实并不难做,试想如果一年只有一个人访问你的系统,只要这一个人访问成功,那你系统的‘’可用性‘就是100%了。

    可现实是,随着业务的发展,请求量会越来越高,进而各种系统资源得以激活,那潜在风险也会慢慢的暴露出来。

    因此,做系统的难点之一便是:如何在高并发的条件下,保证系统的高可用。上文已经说了一些保证高可用的技巧,这节将结合开涛的书,说说高并发。

    上图是我们生活中常见的一个场景——排队购物。收银员就是我们的服务,每一个在队列中的顾客都是一个请求。我们的本质诉求是让尽可能多的人都在合理的等待时间内完成消费。

    如何做到这一点呢?其一是提高收银员的处理速度,他们处理的越快,单位时间内就能服务更多的顾客;其二是增加人手,一名收银员处理不过来,我们就雇十名收银员,十名不够我们就雇佣一百名(如果不计成本);其三是减少访问人数,也即分流过滤,将一些人提前过滤掉,或做活动预热(比如双十一预热),在高峰之前先满足一部分人的需求。因此,想要高并发无外乎从以下几个方面入手:

    提高处理速度:缓存、异步
    增加处理人手:多线程(多进程)、扩容
    减少访问人数:预处理(本文不涉及)

    提高处理速度

    缓存

    缓存之所以能够提高处理速度,是因为不同设备的访问速度存在差异。缓存的话题可以扯几本书不带重样的。从CPU可以一直扯到客户端缓存,即从最底层一直到扯到最特近用户的一层,每一层都可能或可以有缓存的存在。我们这里不扯这么多,只说简单服务端缓存。现在从几个不同角度来看一下缓存:

    ①从效果角度。命中率越高越好吗?10万个店铺数据,缓存了1000个,命中率稳定100%,那是不是说,有99000个店铺都是长尾店铺?缓存效果评估不能单看命中率。

    ②从回收策略。如果把缓存当做数据库一样的存储设备去用,那就没有回收的说法了(除非重启或者宕机,否则数据依然有效);如果只存储热数据,那就有回收和替换的问题。回收有两种方式,一种是空间配额,另一种是时间配额。替换也有几种方式,LRU,FIFO,LFU。

    ③从缓存使用模式角度:用户直接操作缓存和db;用户直接操作缓存,缓存帮助我们读写DbB;

    ④从缓存分级角度。java堆内缓存、java堆外缓存、磁盘缓存、分布式缓存,多级缓存。

    ⑤从缓存使用角度。null穿透问题、惊群问题、缓存热点问题、缓存一致性问题、读写扩散问题……

    ⑥更新方式。读更新、写更新、异步更新。

    如果缓存集群涉及到异地多集群部署,再结合大数据量高并发业务场景,还会遇到很多更加复杂的问题,这里就不一一列举了。

     

    异步

    异步这里有几点内涵,

    其一是将多个同步调用变成异步并发调用,这样就将总响应时间由原来的t1+t2+t3+…..+tn变成了max(t1,t2,t3….,tn),这也叫异步编排;

    其二是在操作系统层面,使用asyc io以提高io处理性能;

    其三是将请求’转储‘,稍后异步进行处理,一般使用队列中间件。其中的异步编排,可以使用CompletableFuture;异步IO一般框架都做了封装;而队列中间件则是最为常用的技术之一,也是我们重点关注的对象。

    业务允许延迟处理,是使用队列中间件的大前提,即非实时系统或准实时系统更适合使用。主要作用有:异步处理(增加吞吐),削峰蓄洪(保障稳定性),数据同步(最终一致性组件),系统解耦(下游无需感知订阅方)。

    • 缓冲队列:一般使用环形缓冲队列,控制缓冲区大小。

    • 任务队列:一般用于任务调度系统,比如线程池等,disrupter

    • 消息队列:一般意义上的消息中间件,不同业务场景需要的中间件能力不同,有的需要高吞吐,有的需要支持事务,有的需要支持多客户端,有的需要支持特定协议等等,妄图开发一个大而全的消息队列,个人觉得不如提供多种队列按需选型,之后在统一提供一个通信中台,全面整合消息能力。

    • 请求队列:就是处理请求的队列,有点像流程引擎,可以做一些前置后置的入队出队处理,比如限流、过滤等等

    • 数据总线队列:比如canal,datax等数据(异构或同构)同步用的。

    • 优先级队列:一般大根堆实现

    • 副本队列:如果队列支持回放,副本队列有些冗余。

    • 镜像队列:一般用于做队列系统的高可用切换的。

      有时候也跨集群跨机房做复制,提供更多消费者消费,增加投递能力。

    队列的消费端有pull模式或者push模式的选取。pull模式可以控制进度,push模式则实时性更高一些;pull能支持单队列上的有序,push很难支持。除了消费模式,队列还有一系列其他问题请参考其他书籍,这里不多说明了。

    这里在补充一点关于异步的说明。同步转异步,可以提高吞吐量;异步转同步,可以增加可靠性。

    增加处理人手

     

    多线程

    多线程(多进程)技术是‘增加处理人手’技术中最容易想到的,一般我们也广泛采用。无论是web服务容器、网关、RPC服务端、消息队列消费和发送端等等都有使用多线程技术。其优点也无需过多说明。

    这里我们只说一件重要的事情,即线程数的设置问题,如果线程数过高则可能会吃光系统资源,如果过低又无法发挥多线程优势。

    一般设置的时候,会参考平均处理时长、并发峰值、平均并发量、阻塞率、最长可容忍响应时间、CPU核心数等等,然后做一定的运算,计算出线程数、core和max,以及阻塞队列大小。

    具体算法可以自行谷歌。

     

    扩容

    在无状态服务下,扩容可能是迄今为止效果最明显的增加并发量的技巧之一。

    有临时性并发问题时,可以直接提扩容工单,立竿见影。但扩容的最大问题就是成本了,想想动辄几万的实体机,如果只是为了支撑一个小时的大促,而平常利用率几乎为0,那确实是浪费。

    因此便有了弹性云,当需要扩容时,借别人机器(阿里云)用完再还回去;以及离线在线混部,充分利用资源。

    从扩容方式角度讲,分为垂直扩容(scale up)和水平扩容(scale out)。

    垂直扩容就是增加单机处理能力,怼硬件,但硬件能力毕竟还是有限;水平扩容说白了就是增加机器数量,怼机器,但随着机器数量的增加,单应用并发能力并不一定与其呈现线性关系, 此时就可能需要进行应用服务化拆分了。

    从数据角度讲,扩容可以分为无状态扩容和有状态扩容。

    无状态扩容一般就是指我们的应用服务器扩容;有状态扩容一般是指数据存储扩容,要么将一份数据拆分成不同的多份,即sharding,要么就整体复制n份,即副本。

    sharding遇到的问题就是分片的可靠性,一般做转移、rehash、分片副本;副本遇到的问题是一致性性,一般做一致性算法,如paxos,raft等。

     


    =>更多文章请参考《中国互联网业务研发体系架构指南》https://blog.csdn.net/Ture010Love/article/details/104381157

    =>更多行业架构案例及行业标准资料请关注微信公众号:

    公众号:关注更多实时动态
    更多内容关注公众号:软件真理与光

     

    展开全文
  • 希尔排序为什么稳定

    千次阅读 2018-10-19 15:47:00
    由于多次插入排序,我们知道次插入排序是稳定的,不会改变相同元素的相对顺序,但在不同的插入排序过程中,相同的元素可能在各自的插入排序中...对于排序算法,所谓的不稳定指的就是相同元素在排序过程中被移动;...

    由于多次插入排序,我们知道一次插入排序是稳定的,不会改变相同元素的相对顺序,但在不同的插入排序过程中,相同的元素可能在各自的插入排序中移动,最后其稳定性就会被打乱,所以shell排序是不稳定的。对于排序算法,所谓的不稳定指的就是相同元素在排序过程中被移动;

    展开全文
  • 下面哪种排序算法是不稳定的() A.插入排序 B.冒泡排序 C.快速排序 D.归并排序 答案:C 现在分析一下常见的排序算法的稳定性,每个都给出简单的理由。 (1)冒泡排序 ...

    (转自:https://www.nowcoder.com/questionTerminal/1ed2cf389c134a2ebc9d14ecdd8de3b0

    下面哪种排序算法是不稳定的()

    • A.插入排序
    • B.冒泡排序
    • C.快速排序
    • D.归并排序

    答案:C

     

    现在分析一下常见的排序算法的稳定性,每个都给出简单的理由。

       (1)冒泡排序

            冒泡排序就是把小的元素往前调或者把大的元素往后调。比较是相邻的两个元素比较,交换也发生在这两个元素之间。所以,如果两个元素相等,我想你是不会再无聊地把他们俩交换一下的;如果两个相等的元素没有相邻,那么即使通过前面的两两交换把两个相邻起来,这时候也不会交换,所以相同元素的前后顺序并没有改变,所以冒泡排序是一种稳定排序算法。

    (2)选择排序

          选择排序是给每个位置选择当前元素最小的,比如给第一个位置选择最小的,在剩余元素里面给第二个元素选择第二小的,依次类推,直到第n-1个元素,第n个元素不用选择了,因为只剩下它一个最大的元素了。那么,在一趟选择,如果当前元素比一个元素小,而该小的元素又出现在一个和当前元素相等的元素后面,那么交换后稳定性就被破坏了。比较拗口,举个例子,序列5 8 5 2 9, 我们知道第一遍选择第1个元素5会和2交换,那么原序列中2个5的相对前后顺序就被破坏了,所以选择排序不是一个稳定的排序算法。

    (3)插入排序
         插入排序是在一个已经有序的小序列的基础上,一次插入一个元素。当然,刚开始这个有序的小序列只有1个元素,就是第一个元素。比较是从有序序列的末尾开始,也就是想要插入的元素和已经有序的最大者开始比起,如果比它大则直接插入在其后面,否则一直往前找直到找到它该插入的位置。如果碰见一个和插入元素相等的,那么插入元素把想插入的元素放在相等元素的后面。所以,相等元素的前后顺序没有改变,从原无序序列出去的顺序就是排好序后的顺序,所以插入排序是稳定的。

    (4)快速排序
        快速排序有两个方向,左边的i下标一直往右走,当a[i] <= a[center_index],其中center_index是中枢元素的数组下标,一般取为数组第0个元素。而右边的j下标一直往左走,当a[j] > a[center_index]。如果i和j都走不动了,i <= j, 交换a[i]和a[j],重复上面的过程,直到i>j。 交换a[j]和a[center_index],完成一趟快速排序。在中枢元素和a[j]交换的时候,很有可能把前面的元素的稳定性打乱,比如序列为 5 3 3 4 3 8 9 10 11, 现在中枢元素5和3(第5个元素,下标从1开始计)交换就会把元素3的稳定性打乱,所以快速排序是一个不稳定的排序算法,不稳定发生在中枢元素和a[j]交换的时刻。

    (5)归并排序
        归并排序是把序列递归地分成短序列,递归出口是短序列只有1个元素(认为直接有序)或者2个序列(1次比较和交换),然后把各个有序的段序列合并成一个有序的长序列,不断合并直到原序列全部排好序。可以发现,在1个或2个元素时,1个元素不会交换,2个元素如果大小相等也没有人故意交换,这不会破坏稳定性。那么,在短的有序序列合并的过程中,稳定是是否受到破坏?没有,合并过程中我们可以保证如果两个当前元素相等时,我们把处在前面的序列的元素保存在结果序列的前面,这样就保证了稳定性。所以,归并排序也是稳定的排序算法。

    (6)基数排序
       基数排序是按照低位先排序,然后收集;再按照高位排序,然后再收集;依次类推,直到最高位。有时候有些属性是有优先级顺序的,先按低优先级排序,再按高优先级排序,最后的次序就是高优先级高的在前,高优先级相同的低优先级高的在前。基数排序基于分别排序,分别收集,所以其是稳定的排序算法。

    (7)希尔排序(shell)
        希尔排序是按照不同步长对元素进行插入排序,当刚开始元素很无序的时候,步长最大,所以插入排序的元素个数很少,速度很快;当元素基本有序了,步长很小,插入排序对于有序的序列效率很高。所以,希尔排序的时间复杂度会比o(n^2)好一些。由于多次插入排序,我们知道一次插入排序是稳定的,不会改变相同元素的相对顺序,但在不同的插入排序过程中,相同的元素可能在各自的插入排序中移动,最后其稳定性就会被打乱,所以shell排序是不稳定的。

    (8)堆排序
       我们知道堆的结构是节点i的孩子为2*i和2*i+1节点,大顶堆要求父节点大于等于其2个子节点,小顶堆要求父节点小于等于其2个子节点。在一个长为n的序列,堆排序的过程是从第n/2开始和其子节点共3个值选择最大(大顶堆)或者最小(小顶堆),这3个元素之间的选择当然不会破坏稳定性。但当为n/2-1, n/2-2, ...1这些个父节点选择元素时,就会破坏稳定性。有可能第n/2个父节点交换把后面一个元素交换过去了,而第n/2-1个父节点把后面一个相同的元素没有交换,那么这2个相同的元素之间的稳定性就被破坏了。所以,堆排序不是稳定的排序算法。

    总结:选堆希快不稳。

     

     

     

    展开全文
  • 平台是干嘛的?...比如你卖出了一套480元的产品,我们平台就会结算240元给你,如果你能稳定每天卖出1单,那个月下来你就能赚到7200元   原来是CPS模式,那平台现在有多少人了? 截至目前为止,我们...
  • 静态功耗具体指什么

    千次阅读 2017-03-06 11:27:17
    百度百科给出的定义是漏电流功耗,是电路状态稳定时的功耗,其数量级很小。其实这个定义很模糊,怎样的状态是电路稳定状态。我自己的理解是静态功耗为两种:、等同于关机功耗,即器件全部关闭时漏电流功耗。二、...
  • 什么是排序算法的稳定

    千次阅读 2016-01-28 14:36:16
    排序算法的稳定性,通俗地讲...排序算法如果是稳定的,那么从个键上排序,然后再从另个键上排序,第个键排序的结果可以为第二个键排序所用。基数排序就是这样,先按低位排序,逐次按高位排序,低位相同的元素其
  • 如果排序结束后,a[0]可以保证一定在a[3]前头,也就是他们原有的顺序不变,那这种排序算法就是稳定的。(比如常见的冒泡排序、基数排序、插入排序、归并排序、桶排序、二叉树排序等都是稳定的排序算法) 反之,如果...
  • 编程中的api指什么?是什么意思?

    千次阅读 多人点赞 2019-09-24 13:02:53
    API是一些预定义函数,目的是用来提供应用程序与开发人员基于某软件或者硬件得以访问组例程的能力,并且无需访问源码或无需理解内部工作机制细节。 API就是操作系统给应用程序的调用接口,应用程序通过调用操作...
  • 排序算法的稳定性是排序前 2 个相等的数其在序列的前后位置顺序和排序后它们两个的前后位置顺序相同。简单来说就是,如果Ai = Aj,Ai原来在位置前,排序后Ai还是要在Aj位置前。 排序算法如果是稳定的,那么从个...
  • 排序稳定性的意义

    千次阅读 2018-10-08 11:07:06
    首先,为什么会有排序算法稳定性的说法?只要能排好不就可以了吗? 看例子 第1行是数字2 记作 1 2 第2行是数字4 记作 2 4 第3行是数字2 记作 3 2 排序后的结果(如果看不懂命令的意思,参照这个博客) 那么引入...
  • 稳定性测试

    千次阅读 2018-08-28 17:04:00
    最近工作过程中没少开会,产品总监与研发总监就产品可用性和稳定性开始了轮大战。 于是我搜集网络资源,罗列一些稳定性测试,只为分享。 1 关于软件稳定性测试的思路 如何测试软件的稳定性其实是很难的,按照...
  • 深入理解快速排序算法的稳定

    万次阅读 2014-04-30 11:30:06
    在初次接触排序算法稳定性这个概念时,我一直认为复杂度为O(n2)的算法是稳定的,复杂度为O(nlogn)的算法是不稳定的。当时是这样理解的,复杂度为O(n2)的算法不可能再坏,而复杂度为O(nlogn)的算法在极端情况下可能会...
  • Lyapunov稳定性理论

    万次阅读 2018-07-09 12:32:58
    所谓平衡点稳定性是系统在受到外扰动作用下,轻微偏离平衡点后,是否具有回到平衡点处的能力,若系统偏离平衡点后,能自行回复到平衡点处,则系统关于平衡点是稳定的,否则系统关于平衡点是不稳定的。在Lyapunov...
  • 个连续线性定常系统,渐进稳定的充分必要条件是:它的系数矩阵 AAA 的特征值全都具有负是实部。 如果系数矩阵 AAA 存在实部为零的单重特征值,那么其对应的动态响应分量会随着时间的增长而趋于常数值(或等幅振荡...
  • 数值稳定

    千次阅读 2019-03-08 16:09:56
    在数值分析中,数值稳定性是种希望得到的数值算法特性。根据算法的不同,稳定性的精确定义也有所不同,但是都与算法的精确性与正确性相关。 理论上有些计算下可以用多种代数上等价的理想实数或者复数算法来实现,...
  • 几种排序算法的稳定性分析

    千次阅读 多人点赞 2019-06-25 12:07:02
    稳定指的是什么?   稳定排序是指原来相等的两个元素前后相对位置在排序后依然不变。   为什么要对排序算法提出稳定性的要求?   简单的举个小例子:比如我们班次期末考试,分高的在前面,...
  • .李雅普诺夫稳定性理论 1.前期铺垫~ !:稳定性是系统正常工作的重要特性 稳定性,是描述初始条件(不一定为0)下,系统是否具有收敛性,与输入作用无关 在经典控制理论中,有代数判据(劳斯、霍尔维茨)、...
  • 具体指什么? 转载自:柔情西瓜啊 来自百度知道认证团队 TR是技术评审的英文Technical Review的缩写,目的是尽早地发现工作成果中的缺陷,并帮助开发人员及时消除缺陷,从而有效地提高产品的质量。 产品开发中,...
  • 分布式架构的架构稳定

    千次阅读 2019-07-08 10:43:50
    接上期架构性能,本期讲架构稳定性 1.服务拆分 服务拆分主要有两个目的:是为了隔离故障,二是为了重用服务模块。但服务拆分完之后,会引入服务调用间的依赖问题。 2.服务冗余 服务冗余是为了去除单点故障,并...
  • 系统稳定

    千次阅读 2016-12-21 09:18:42
    系统的运动稳定性可以分为:基于输入输出描述的外部稳定性和基于状态空间描述的内部稳定性。内部稳定性和外部稳定性的关系: 对连续时间线性定常系统 {x˙=Ax+Buy=Cx+Dux(0)=x0,t≥0,\left\{ {\begin{array}{*{20}...
  • Monkey 稳定性测试

    万次阅读 多人点赞 2018-04-16 12:23:52
    什么稳定性测试?通过随机点击屏幕段时间,看看app会不会奔溃,能不能维持正常运行二. Money是什么?Monkey测试是Android平台自动化测试的种手段,通过Monkey程序模拟用户触摸屏幕、滑动Trackball、按键等...
  • 神经网络稳定性分析

    千次阅读 2017-09-17 16:13:58
    神经网络稳定性系统动力学系统表述研究个系统最终目的是为了得到系统变量随时间变化的轨迹x(t)=f(t)x( t) =f( t),但实际上,只能获取系统每时每刻的受力情况,而并不能直接知道最终的轨迹方程,这个是符合我们...
  • 排序算法 及其稳定性解释

    千次阅读 2016-04-03 16:53:10
    排序算法的稳定性是在待排序的序列中,存在多个相同的元素,若经过排序后这些元素的相对词序保持不变,即Xm=Xn,排序前m在n前,排序后m依然在n前,则称此时的排序算法是稳定的。下面针对常见的排序算法做个简单的...
  • Android稳定性测试工具Monkey的使用

    万次阅读 2017-01-15 13:07:12
    Monkey是个命令行工具,它可以运行在我们的模拟器或者设备当中。...我们能够使用Monkey工具来对我们所...Monkey测试是种为了测试软件的稳定性,健壮性的快速有效的方法。Monkey程序介绍 Monkey是Android自带的系统
  • 第二个是内部稳定,internal stability,所有的状态稳定。第二个可以保证第个,反之则不行 第稳定实际上在数学上对应的是算子的有界性 初值确定时,特征值包含极点,有的特征值可能会因为不可控不...
  • 常见排序算法的稳定性分析和结论

    万次阅读 多人点赞 2010-05-31 12:26:00
    这几天笔试了好几次了,连续碰到个关于常见排序算法稳定性判别的问题,往往还是多选,对于我以及和我一样拿不准的同学可不是个能轻易下结论的题目,当然如果你笔试之前已经记住了数据结构书上哪些是稳定的,哪些...
  • 区块链上的稳定币:理论支持和技术实现 大家好,很高兴今天受到 EthFans 邀请参加第期的“洞见”活动。我将给大家分享一下区块链的稳定币...我在标题“稳定币理论”前面给“区块链上的”打了个括号,因为我觉得...
  • STL stable_sort 稳定排序

    千次阅读 2013-11-13 10:26:34
    所谓稳定排序,是个序列进行排序之后,如果两个元素的值相等,则原来乱序时在前面的元素现在(排好序之后)仍然排在前面。STL中提供stable_sort()函数来让我们进行稳定排序。为了更好的说明稳定排序的效果,...
  • 稳定&渐进稳定,一致有界&一致最终有界

    万次阅读 多人点赞 2016-08-04 21:46:10
    组概念:稳定&渐进稳定定义1(stable):平衡点x=0x=0在t0t_0时刻是稳定的,如果对于任意ϵ>0\epsilon\gt0,存在个常数δ(t0,ϵ)>0\delta(t_0,\epsilon)\gt0使得∥x(t0)∥<δ(t0,ϵ)⇒∥x(t)∥<ϵ,∀t≥t0\Vert ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 370,138
精华内容 148,055
关键字:

一稳定指什么