接下来我简单介绍去哪儿网的系统群情况。目前线上运行的活跃的应用有3000+个,提供18000+个dubbo rpc的服务接口,有3500+个http的域名注册,有13000+个mq的主题,公司内部有5种语言的技术栈,以Java和node为主,可见其中关系的复杂程度。只要一个地方出现问题,就有可能会级联地传递到c端,那么用户侧就会感受到问题。因此我们应该如何治理这些系统群?混沌工程则是一个非常好的手段,后面我将会介绍如何用混沌工程解决这些问题。
在我从业的八九年期间,我们也遇见过大量的基础设施问题,如微服务的注册中心zookeeper经常出现抖动的问题,消息队列出现问题,甚至机房的网络、断电也会出现问题。
从故障的原因来看,我们可以将其分成几大类:底层的机房、中间件、机器问题影响规模相对较大,机房挂掉时整个机房的相关应用都会受到影响;
我认为混沌工程可以有以下三方面的收益。1)人人的不同角色,如从用户的角度来看,能够得到稳定的用户体验,不会再由于技术问题导致用户体验的不佳,甚至于无法得到服务;从测试的角度来看,能够提前降低甚至有可能阻止故障的发生;从开发和运维的角度来看,可以提升应急的效率。2)流程把一个乱序的具体问题具体分析的流程转化为体系性治理的流程。3)系统面向正确的设计转向了面向失败的设计,为整个系统提供了一定的韧性容灾能力。对于一些基础能力而言,可观测、可灰度、可回滚、可降级都不再是期望,而是实际能够得到的能力。
从应用架构层次来看,基本每个公司偏差不大,最底层是机房可用区,往上依次是中间件、服务器层、应用层、依赖层。层次越往下,出问题的概率相对而言越小。在服务治理里超时熔断甚至限流发生频率非常高,但是在机房层面统一的挂掉或断电的概率则小很多。然而,底层的失效概率小,影响面却非常大。应用架构的层次和对应的失效情况,很大程度影响了我们实践的节奏。混沌工程要达到两个目标,并不是一蹴而就的,这意味着我们要做大量的工作以确保机制的制定和生效。应用架构层次是我们对应阶段划分投入的人力时一个很好的向导。当我们一无所有时,应当优先解决影响面大的问题。如果把服务之间依赖关系做得很好,但机房挂掉或中间件挂掉了,整个服务都不可用时,一切都是笑谈。
因此,从实践路径出发,我认为可以分成四个节奏:1)先要做到机房、中间件、实体机、虚拟机级别的关机演练,尽可能消除大面的影响。2)应用演练在于应用的可用性治理。3)依赖演练在于拓扑合理性依赖的治理。4)攻防演练解决的是人面对失效时,是否有对应的预案策略,预案策略的执行时效性与恢复时间。从左往右的路径其实是一个影响面逐渐缩小的过程。
关机演练的实现有以下几点:
关机演练效果:
首先要对注入工具做技术选型。我们云平台里的容器和虚拟机都需要支持,要求的场景也比较丰富,我们对开源的要求也比较高,因为需要进行二次开发,最终从选型上我们选择了比较适合的chaosblade。
接下来对chaosblade做一个简单的介绍。chaosblade支持的场景非常多,有容器级别、操作系统级别以及语言层面的,比如Java的executor。以上是我们广泛应用的,尤其是通过Java的技术,我们对其进行了大量的改造。
chaosblade的功能基本上涵盖了我们日常通用的中间件场景,比如在应用服务的层次里,一般的rpc框架、网关、消息中心件对于我们来说覆盖面是比较广的,特别是数据库、缓存等都有一定的支持。
chaosblade基础功能比较完善,但是在企业场景里有一些缺失,比如HTTP超时能力、fullGC和日志拥堵,甚至官方不支持同一个接口的依赖但是不同的调用点等区分,以及比如全链路的匹配。我们把这些能力实现之后回馈给了官方,因此大家现在再去用最新版本的chaosblade则具备了以上企业场景。
选完chaosblade之后,我们需要进行演练前的准备,首先选定它的资源和策略,在演练进行的过程中把 agent自动化挂载上去,再通过选好的策略自动注入故障,通过流量copy的方式和人工手动触发的case在C端触发两部分进行验证。目前我们已经实现了全链路的场景匹配,因此能够区分用户的真实流量和测试人员的人工流量。在恢复阶段我们有两种恢复方式,一是对我们来说是预防底线的告警或超时恢复,如果都执行完之后没有触发则采取人工恢复,然后卸载agent,最后总结问题并改进完成复盘。
以上是新建演练效果图,演练时可以选择对应的应用、机器以及策略,编排好之后就可以定期执行。
应用可靠性不仅受应用本身影响,还会受到依赖的信息服务影响。大家维护所有应用时都会想到:死道友不死贫道,即所有的同行都可以出现问题但我不能。当我们保持这个心态治理服务时,就需要非常关注依赖关系,被拖死、被波及、被传递时,如何解决依赖关系导致的蝴蝶效应;依赖的超时、熔断、异常、限流是否符合我们的预期;以及强依赖太多,能否降级为弱依赖,以上问题都非常关键。因此,依赖演练的能力目标是对应用层的外部依赖进行多策略演练,并且断言它是强依赖还是弱依赖。依赖演练的关键点在于:1)做好应用元数据采集
如果没有应用元数据的采集,则无法得知应用所有的外部依赖。我们将所有rpc和服务注册相关的、数据依赖和redis以及一些定时任务等信息采集到一起,将通过日志、注册中心、DB元数据或应用暴露出来的元数据,甚至还有trace信息进行汇总,产生了一个最全的应用元数据。2)可视化应用拓扑结构便于我们观测到该应用被谁调了,我调了谁,对于我们做生效面控制非常有效。3)区分不同场景的同一个依赖即刚才提到的不同调用点的同一个接口的依赖。4)标注强弱依赖关系
将采集到的信息进行分析聚合和存储,并对信息进行强弱依赖关系标注。以上是强弱依赖关系标注的界面效果图,我们能够区分的类型多且细,对应的目标也非常多。
依赖演练存在一个逻辑的闭环:当我们的服务治理收集了依赖关系之后,需要让用户标注依赖关系,相当于得知用户期望的依赖,我们再进行强弱依赖演练,并且得到演练结果进行修正,查看是否符合用户预期,从而产生对比差距。如用户期望它是一个弱依赖,实际线上执行它是一个强依赖,那么就能产生我们改进的计划集,对其进行修复。
依赖演练效果:我们执行了1200+次演练,依赖的接口涉及3000+个,我们在去年五一前做的依赖演练发现了136个问题,且问题类型各不一致,如代码编写将一个弱依赖写成了一个强依赖,以及配置问题、容量问题等。
关机演练、应用演练与依赖演练做完之后,我们平台架构如上图。
我们自动演练的流程如上图。第一步是做控制面,可以获取到应用的信息。第二步是对其进行故障的注入。第三步是触发自动化测试,从而产生两份流量,这两份流量会打向我们的基准环境和对应测试环境,测试环境的代码配置等与基准环境是相同的,然后自动化平台会对两者返回的结果做一个断言,进而得到一个结论:当我注入这个问题时,流量是否依然正常。自动化检测完结果之后就能产生依赖关系的判断。如果注入了故障从而产生了问题,那就意味着它是个强依赖。通过自动演练流程,引入了自动化测试平台之后,我们就能做到不需要人工触发流量和判断。
从信息来看,一个功能入口对应后面的一个过程,过程里的强弱依赖关系是非常复杂的,可能有一条完整的强依赖,也可能有中间部分的强依赖,或者一些是纯弱依赖,这些关系决定了我们的方案。
与刚才说的单应用断言不同,做全链路断言需要引入一个全链路压测的演练系统。我们内部有一个全链路压测平台,能够做到用例自动生成、数据隔离,且执行成本非常低,比如执行完一个机票业务线所有核心场景可能只需要半天,相当于我们只需要0.5pd的人力就能覆盖上千个应用。
从断言来看,我们有一个断言的逻辑:当入口产生调用流量时,我们就会对它进行一个断言,观测我们的核心指标尤其是用户侧的核心指标是否存在问题,如果存在问题,我们则会中断演练,并且记录对应的结果;如果不产生对应的报警,我们还会从另外一个角度看是否对C端的功能有其它影响。我们会对人工主动标注的告警事件和系统自动分析的雷达事件进行统一,进而得到一个结论,就是当全链路注入问题时,对于入口来说是一个强依赖还是一个弱依赖,这是断言的逻辑。
从流程来看,与刚才的自动演练流程有点相似,只是把接口自动化的测试平台转化为全链路压测平台,但是它的断言与自动化的断言逻辑不同。
需要注意的是,我们需要对链路上的命中率做一定的优化。命中率是指从入口发下去的流量是否一定会经过我们想测试的依赖,比如我想测e系统打到g系统的调用,入口的流量发出来不一定都能达到e的依赖链路里,它打到了b系统,再打到e系统,再打到了f系统,这就需要一个非常有效的机制提前发现,演练的流量与我们预期的依赖是否达到。这需要依赖到其它大量的信息,如果我们没用精准的方式,而是随机地挑选入口流量,那么链路上的命中率只有40%左右,我们希望能够将命中率提到90%以上。我们针对命中率做了一个精准的策略:利用依赖关系已经产生的实际数据,即线上APM的trace数据反查能够经过链路的请求条件和流量,比如当我们想要找e和f的调用链路时,可以从b系统入口打到e系统再打到f系统,这就是我们想要找的其中一个链路,再逆向给出一个结论,从而得到对应trace的入口信息,再得到入口的请求条件信息,通过请求条件做用例的自动构造,就能得到一部分非常有效的用例,从而把我们的命中率提升到了90%以上。从全链路自动演练的效果来看,目前覆盖了去哪儿网的55个核心入口和80%以上的核心应用,仅剩最后的人工成本,只要对汇总的报告进行最终的分析,产生一个节假日混沌工程的报告即可。
2020年,我们故障处理时间的中位数是54分钟和39分钟,2021年也是51分钟,因此在线上的真实故障里处理的时间还是比较长的。
我们设计了一个攻防演练的流程:流程依赖于大量的基础设施系统,包含故障平台、混沌工程平台、监控告警平台、日志平台、trace平台等。首先做攻击点的规划,汇总历史故障原因,优先把出现次数多的原因规划为对应的攻击点;其次故障随机注入,注入点与时间随机,不同的接口依赖不提前告知开发;然后监控告警触发,防守方排查问题,需要上报对应的结论、耗时等排查结果;最后对其进行一定的计分公式,复盘分析。
故障注入流程与全链路依赖流程相似,只需要把流量真正注入即可,不需要断言它的强弱依赖。
从积分例子可以看出,大部分问题1~3分钟即可解决,通过这个方式演练能够有效提升排查和处理问题的速度。很好奇,就使用rubyonrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提
导读:随着叮咚买菜业务的发展,不同的业务场景对数据分析提出了不同的需求,他们希望引入一款实时OLAP数据库,构建一个灵活的多维实时查询和分析的平台,统一数据的接入和查询方案,解决各业务线对数据高效实时查询和精细化运营的需求。经过调研选型,最终引入ApacheDoris作为最终的OLAP分析引擎,Doris作为核心的OLAP引擎支持复杂地分析操作、提供多维的数据视图,在叮咚买菜数十个业务场景中广泛应用。作者|叮咚买菜资深数据工程师韩青叮咚买菜创立于2017年5月,是一家专注美好食物的创业公司。叮咚买菜专注吃的事业,为满足更多人“想吃什么”而努力,通过美好食材的供应、美好滋味的开发以及美食品牌的孵
相信很多人在录制视频的时候都会遇到各种各样的问题,比如录制的视频没有声音。屏幕录制为什么没声音?今天小编就和大家分享一下如何录制音画同步视频的具体操作方法。如果你有录制的视频没有声音,你可以试试这个方法。 一、检查是否打开电脑系统声音相信很多小伙伴在录制视频后会发现录制的视频没有声音,屏幕录制为什么没声音?如果当时没有打开音频录制,则录制好的视频是没有声音的。因此,建议在录制前进行检查。屏幕上没有声音,很可能是因为你的电脑系统的声音被禁止了。您只需打开电脑系统的声音,即可录制音频和图画同步视频。操作方法:步骤1:点击电脑屏幕右下侧的“小喇叭”图案,在上方的选项中,选择“声音”。 步骤2:在“声
我认为我的问题最好用一个例子来描述。假设我有一个名为“Thing”的简单模型,它有一些简单数据类型的属性。像...Thing-foo:string-goo:string-bar:int这并不难。数据库表将包含具有这三个属性的三列,我可以使用@thing.foo或@thing.bar之类的东西访问它们。但我要解决的问题是当“foo”或“goo”不再包含在简单数据类型中时会发生什么?假设foo和goo代表相同类型的对象。也就是说,它们都是“Whazit”的实例,只是数据不同。所以现在事情可能看起来像这样......Thing-bar:int但是现在有一个新的模型叫做“Whazit”,看起来
我有一个要在我的Rails3项目中使用的数组扩展方法。它应该住在哪里?我有一个应用程序/类,我最初把它放在(array_extensions.rb)中,在我的config/application.rb中我加载路径:config.autoload_paths+=%W(#{Rails.root}/应用程序/类)。但是,当我转到railsconsole时,未加载扩展。是否有一个预定义的位置可以放置我的Rails3扩展方法?或者,一种预先定义的方式来添加它们?我知道Rails有自己的数组扩展方法。我应该将我的添加到active_support/core_ext/array/conversion
参见下面的示例,我想最好使用第二种方法,但第一种也可以。哪种方法最好,使用另一种的后果是什么?classTestdefstartp"started"endtest=Test.newtest.startendclassTest2defstartp"started"endendtest2=Test2.newtest2.start 最佳答案 我肯定会说第二种变体更有意义。第一个不会导致错误,但对象实例化完全过时且毫无意义。外部变量在类的范围内不可见:var="string"classAvar=A.newendputsvar#=>strin
如果我构建了一个应用程序来访问来自Gmail、Twitter和Facebook的一些数据,并且我希望用户只需输入一次他们的身份验证信息,并且在几天或几周后重置,那会怎样是在Ruby中动态执行此操作的最佳方法吗?我看到很多人只是拥有他们客户/用户凭证的配置文件,如下所示:gmail_account:username:myClientpassword:myClientsPassword这看起来a)非常不安全,b)如果我想为成千上万的用户存储此类信息,它就无法工作。推荐的方法是什么?我希望能够在这些服务之上构建一个界面,因此每次用户进行交易时都必须输入凭据是不可行的。
文章目录1.任务背景2.任务目标3.相关知识点4.任务实操4.1安装配置JDK4.2启动FISCOBCOS4.3下载解压WeBASE-Front4.4拷贝sdk证书文件4.5启动节点4.6访问节点4.7检查运行状态5.任务总结1.任务背景FISCOBCOS其实是有控制台管理工具,用来对区块链系统进行各种管理操作。但是对于初学者来说,还是可视化界面更友好,本节就来介绍WeBASE管理平台,这是一款微众银行开源的自研区块链中间件平台,可以降低区块链使用的门槛,大幅提高区块链应用的开发效率。微众银行是腾讯牵头设立的民营银行,在国内民营银行里还是比较出名的。微众银行参与FISCOBCOS生态建设,一定
基本上我想选择一个节点(div),其中它的子节点(h1,b,h3)包含指定的文本。Childtext1Childtext2...Childtext3我期待的是/html/div/而不是/html/div/h1我在下面有这个,但不幸的是返回了child,而不是div的xpath。expression="//div[contains(text(),'Childtext1')]"doc.xpath(expression)我期待的是/html/div/而不是/html/div/h1那么有没有一种方法可以简单地使用xpath语法来做到这一点? 最佳答案
我正在使用Devise在Rails应用程序中,并希望通过API公开一些模型数据,但应该像应用程序一样限制对API的访问。$curlhttp://myapp.com/api/v1/sales/7.json{"error":"Youneedtosigninorsignupbeforecontinuing."}很明显。在这种情况下是否有访问API的最佳实践?我更喜欢一步验证+获取数据,但这只是为了让客户的工作更轻松。他们将使用JQuery在客户端提取数据。感谢您提供任何信息!凡妮莎 最佳答案 我建议您按照以下帖子中的选项2:使用APIke