计算机是当今世界的命脉,你能看到的任何地方,计算机都在改变着世界,不论是传统的制造生产,医疗通讯。还是新兴的虚拟现实,无人驾驶汽车 等领域。过去的几十年,计算机硬件飞速发展,软件领域也是不断刷新着人们的想象。可以说,计算机学科复杂而且庞大,甚至有人说,不亚于物理学。
今天我们讨论的话题,线上事故分析,只是其中的一部分,一小部分,为了说清楚这一点,我们简单了解一下软件工程学科。
玛格丽特·希菲尔德·汉密尔顿(英语:Margaret Heafield Hamilton,1936年8月17日-[ 1])被认为发明了软件工程一词。
她帮助了NASA在阿波罗计划中避免了严重问题。她曾这样说:“有点像牙根管治疗:你总是拖到最后才做,但有些事可以预先做好,有点像预防性体验,只不过是预防软件出错”。
我们不妨简单总结如何开发一个大型的软件项目下:
1-基于面向对象的编程语言
2-容易使用的集成开发环境
3-文档和注释(程序员最讨厌的两件事,写注释给别人读,阅读别人没有写注释的代码)
4-构建管理和版本控制
5-质量保证测试(QUALITY ASSURANCE-QA)
每个软件从业者从写下第一行代码开始,就一刻不停地 和软件中的错误做斗争 开发和维护(修复缺
陷、确保资源充 足等保障软件运行的活动)是一对伴随软件运行而产生的双 热爱从零到一开发软件是
开发者的天性 看着自己编写的 软件完美运行,为其他 提供服务,一直是驱动开发者前进的动力。为了
更快更好地开发软件,我们不断改进开发方法和软件架构,但是开发者在使用新的方法和更复杂的架构
时,往往也会低估潜在的风险。
本课程话题,主要讨论质量测试上线后,运营环节期间的一些问题,当然,我们暂时并不界定事故的产
生到底是因为测试覆盖不全还是操作不当等,这某种程度体现着管理的方式问题。
业务和产品的线上质量、是研发团队的生命线,也是支撑业务快速是错,小步跑的前置条件。
故障等级定义,不同的业务形态,不同的公司团队,有不一样的划分标准,下表列举了一般常见的维度和标准
【1】核心数据定义
个人敏感信息:姓名、出生日期、身份证件号码、个人生物识别信息、住址、通信通讯联系方式、通信记录和内容、账号密码、财产信息、征信信息、行踪轨迹、住宿信息、健康生理信息、交易信息等。
用户画像:职业、经济、健康、教育、个人喜好、信用、行为等。
【2】系统级别定义
零级系统(P0):为公司核心业务服务的核心系统,一旦发生不可用会直接影响公司核心业务的业务连续性,对所有系统用户造成影响。
一级系统(P1):重点的业务系统,一旦发生不可用,影响核心业务的连续型,并造成大部分内部用户或外部用户不可使用此系统。
二级系统(P2):重要的业务系统,一旦发生不可用存在一定的业务可用性问题,但不会影响核心业务的业务连续性。
三级系统(P3):非核心的支撑系统,一旦发生故障不直接产生业务影响,但会影响少部分内部用户使用此系统。
【3】影响范围与故障等级
如图所示,大体描述了一般生产故障的处理机制
故障发现:
1-客户投诉或者业务反馈,研发自我发现
2-监控报警:技术监控,业务监控
日常项目里中,站在开发者的角度:
【bug起源】:1945年9月9日,格蕾丝·赫柏(Grace Murray Hopper) 使用的Mark Ⅱ出现故障,导致工作无法进行。经过了近一天的检查,格蕾丝找到了故障的原因:继电器中有一只死掉的蛾子。蛾子被夹了出来。后来,”bug” (小虫) 和”debug” (除虫) 这两个本来普普通通的词汇成了计算机领域中特指莫明其妙的“错误”和“排除错误”的专用词汇而流传至今,而格蕾丝·赫柏也因此成了第一个发现“bug”的人。
另一方面,大名鼎鼎的 "千年虫"bug,也是由她带来的。当然,这也不全完全算作bug。
由软件Bug引发的18次重大事故 | 程序师 - 程序员、编程语言、软件开发、编程技术 (techug.com)
近年的CSDN600万用户信息泄露事件:CSDN网站六百万用户信息外泄-月光博客 (williamlong.info)
2018年github服务中断24小时11分钟事件:GitHub服务中断24小时11分钟事故分析报告 (qq.com)
观念和思想来源于:【混沌工程】一书
说起混沌工程一次,也许你听过阿里的红蓝军对抗。
混沌工程是一种通过实验探究的方式来让我们理解系统行为的方法,就像科学家通过实验来研究物理和社会现象一样,混沌工程通过实验来了解特定的系统 如何使用混沌工程提高系统弹性呢?混沌工程通过设计 和执行一系列实验,帮助我们发现系统中潜在的、可以导致灾难的或让我们的用户受损的脆弱环节,推动我主动解决这些环节存在的问题 和现在各大公司主流的被动式故障响应流程相比,混沌工程向前迈进了一大步。
混沌工程解决的问题:
要设计良好的系统需要考虑很多因素,比如可靠性、安全 性、可扩展性、可定制化、可伸缩性、可维护性、用户体验等。 为了更高效地支撑业务发展,越来越多的企业选择基于云服务 或云原生理念来构建平台。采用新思路和新技术必然会带来系统架构和组织结构的变革,引入风险因素。
如何通过实验证明生产环境下的分布式系统在面对失控条件的时候依然具备较强的“可观测性”和故障恢复能力呢?这就是混沌工程要解决的问题。
混沌工程和测试的区别:
混沌工程故障注入和故障测试在侧重点和工具集的使用上有些重叠 举个例子, Netflix 的很多混沌工程实验的研究对象都是基于故障注入来引入的。
混沌工程和其他测试方法的主要区别在于,混沌工程是发现新信息的实践过程,而故障注 入则是基于一个特定的条件、变址的验证方法。
混沌工程和故障注人本质上是思维方式上的不同 。故障 注人首先要知道会发生什么故障,然后一个一个地注人, 而在 复杂分布式系统中,想要穷举所有可能的故障,本身就是奢望 混沌工程的思维方式是主动去找故障,是探索性的,你不知道摘 掉一个节点、关掉一个服务会发生什么故障,虽然按计划做好了 降级预案,但是关闭节点时却引发了上游服务异常,进而引发雪崩,这不是靠故障注人或预先计划能发现的
一些混沌实验的输入样例:
模拟整个云服务区域或整个数据中心的故障
部分删除各种实例上的Kafka主题。
重新创建生产中发生的问题。
针对特定百分比的交易服务之间注入一段预期的访问延迟。
基于函数的混乱(运行时注入):随机导致抛出异常的函数。
代码插入:向目标程序添加指令和允许在某些指令之前进行故障注入。
时间旅行:强制系统时钟彼此不同步。
在模拟I/O错误的驱动程序代码中执行例程。
在 Elasticsearch 集群上最大化CPU核心。
混沌工程实验的机会是无限的,可能会根据分布式系统的架构和组织的核心业务价值而有所不同
混沌工程实现的四个步骤:
1.定义并测量系统的“稳定状态”。
首先精确定义指标,表明您的系统按照应有的方式运行。 Netflix使用客户点击视频流设备上播放按钮的速率作为指标,称为“每秒流量”。请注意,这更像是商业指标而非技术指标;事实上,在混沌工程中,业务指标通常比技术指标更有用,因为它们更适合衡量用户体验或运营。
2.创建假设。与任何实验一样,您需要一个假设来进行测试。
因为你试图破坏系统正常运行时的稳定状态,你的假设将是这样的,“当我们做X时,这个系统的稳定状态应该没有变化。”为什么用这种方式表达?如果你的期望是你的动作会破坏系统的稳定状态,那么你会做的第一件事会是修复问题。混沌工程应该包括真正的实验,涉及真正的未知数。
3.模拟现实世界中可能发生的事情,目前有如下混沌工程实践方法:模拟数据中心的故障、强制系统时钟不同步、在驱动程序代码中模拟I/O异常、模拟服务之间的延迟、随机引发函数抛异常。通常,您希望模拟可能导致系统不可用或导致其性能降低的场景。首先考虑可能出现什么问题,然后进行模拟。一定要优先考虑潜在的错误。 “当你拥有非常复杂的系统时,很容易引起出乎意料的下游效应,这是混沌工程寻找的结果之一,”
“因此,系统越复杂,越重要,它就越有可能成为混沌工程的候选对象。”
4.证明或反驳你的假设。将稳态指标与干扰注入系统后收集的指标进行比较。如果您发现测量结果存在差异,那么您的混沌工程实验已经成功 - 您现在可以继续加固系统,以便现实世界中的类似事件不会导致大问题。或者,如果您发现稳定状态可以保持,那么你对该系统的稳定性大可放心。
引入混沌工程的一些建议:来源于-周洋(花名:中亭)-阿里巴巴高可用架构团队高级技术专家
第一,引入混沌工程,需要建立进行面向失败设计(可以 使系统暴露出已有问题的设计)和拥抱失败的技术文化
第二,实施混沌工程,需要定义一个清晰可衡量的目标。
第三,推广混沌工程,要在控制风险的前提下不断提升效率。
混沌工程是一种实践思想,其本身是不绑定任何技术或工具的。
减少问题的最好方法就是让问题经常性地发生,通过不断 重复失败过程并找出解决方案,来持续提升系统的容错能力和 弹性。
混沌工程工具
chaosblade-io/chaosblade: An easy to use and powerful chaos engineering experiment
toolkit.(阿里巴巴开源的一款简单易用、功能强大的混沌实验注入工具) (github.com)
一个高可用的业务系统除了技术架构支撑之外,监控系统作为事中决策支撑和事后决策止损是必不可少的一部分
工具:Prometheus、Zabbix、Nagios、Open-Falcon、Pageduty等
监控体系分类:一般可分为:业务监控,系统级别监控,网络监控,程序代码监控,日志监控,用户行为分析监控,其他种类监控等
物理监控(对物理机或者容器的监控):存活、内存、cpu、load、硬盘(速率、使用率)、网络
活性检测:进程、端口
应用服务监控:jvm、gc、线程数
服务监控:rpc和http接口的qps、rt、错误码等
业务监控:包含用户访问的QPS,DAU,访问状态(http状态码),业务接口(登录,注册,聊天,送礼,留言,下单,支付,播放按钮点击率,搜索次数,好评差评数等等),产品转化率,充值额度,客诉等很宏观的概念
交易运营数据
业务监控自定义数据
1-业务监控设置静态阈值无法满足要求
阈值应该配成多少,不同的业务甚至不同的时间段都需要不同的阈值
业务总是出现周期性的趋势,规则配置极易产生误报
特殊的业务场景例如活动引起的冲高回落、大促的冲击都会引起大量误报
对大量维度的业务,比如要监控外部千万级别的商户、上百个不同类型的错误码该如何配置
支付宝lego
阿里妈妈goldeneye
IDC,对网络状态的监控(交换机、路由器、防火墙,)对于一个互联网公司必不可少,但是有很多时候又被忽略:例如:内网之间(物理内网,逻辑内网),外网,丢包率,网络重传,延迟等等
日志监控比较重要,所以一般单独管理和分类,日志不仅限于服务系统日志,对于很多专业化的运维工程师来说,需要采集的包括系统日志,设备日志,用户行为日志等等,后续可加工处理,(splunk,ELK)
当前排除故障的流程
【项目背景】目前公司线上业务,经常遇到以下几种问题:
一旦我们在生产中检测到问题,我们必须:
功能:
上一节,我们有提到,故障排除的一般流程,不妨在此再次总结如下:
1-一般情况下,需要了解业务场景,千万不要第一时间着急解决bug,应先评断是否可以回滚,影响面大小,是否为上层提供服务,是否有数据异常。
2-应熟悉项目依赖的监控,学会看监控。
3-应熟练开发环境的断点排查与诊断,熟悉git,maven,idea的使用,分析如何复现线上故障。
4-线上排查故障的工具链(仅供参考)-随着课程慢慢补齐
所在行处: Ctrl+F8
断点属性编辑: Ctrl+Shift+F8
行断点(line breakpoints)
当指定的字段被读取或写入时暂停程序。这允许你对与特定实例变量的交互作出反应。例如,如果在一个复杂的过程结束时,你的某个字段出现了明显的错误值,设置一个字段观察点可能有助于确定故障的来源。该类型断点的图标:
鼠标右键点击该断点图标 ,弹出该断点配置,会有Field access和Field modification选项,此选项是字段类型断点特有的,分别对应访问该字段或修改该字段触发断点,两项同时选中,则访问与修改该字段都会触发断点。
方法断点(method breakpoints)
在进入或退出指定的方法或其实现之一时暂停程序,允许你检查该方法的进入/退出条件。
断点删除
1-所有类型断点:断点设置中移除对应的即可。
2-快捷移除:行位置鼠标左键单击即可移除(异常断点除外)
建议:为了避免意外删除断点并丢失其参数,通常选择点击鼠标中键来删除断点。要做到这一点,请进入 “设置/首选项”|“构建、执行、部署”|“调试器”,选择 "拖到编辑器 "或用鼠标中键点击。点击一个断点将启用或禁用它。
断点静音
如果某些时候不需要在断点处停留一段时间,可以将断点静音。这样就可以在不离开调试器会话的情况下恢复正常的程序操作。之后,可以解除中断点的静音,继续调试。断点静音会静音所有断点
鼠标操作:右键断点:More(Ctrl+Shift+F8)
快捷键:Ctrl+Shift+F8
快捷键:光标所在行 Alt+Enter
断点有许多属性配置,如下图所示,下面将会对各个属性的作用以及使用进行说明。
Enabled
Supend
Condition
Log
Disable until hitting the following breakpoint
场景:当只需要在某些条件下或某些操作后暂停程序时,这个选项很有用。在这种情况下,触发断点通常不需要停止程序的执行,而是做成非暂停状态。
Filters
前边说的大都数属性,都只针对方法程序运行上下文。此属性更多关注通过过滤掉类、实例和调用者方法来微调断点操作,只在需要时暂停程序。,有如下几种过滤方式:
Pass count
勾选中并输入一个正整数N,N>=1,那么程序会每N次命中断点才会触发挂起,如果同时设置了condition 与 pass count 属性,ide会优先判断 condition 表达式,再判断 pass count 是否满足,下例中, pass count 中传入的是15,每15次命中断点才会触发断点,挂起程序
1-打开Idea的 Run/Debug Configurations 新增一个Remote
JVM参数添加 -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005
2-远程项目启动添加参数
java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 -jar xxx.jar
3-idea启动remote,并打断点调试
使用断点进行 "printf "调试
使用非暂停的日志断点,而不是在代码中插入打印语句。这为处理调试日志信息提供了一种更灵活和集中的方式。
场景:
所有需要打印的地方,生产上禁止 System.out.print();
调试无响应的应用程序
如果你的应用程序挂起,暂停会话,让调试器获得关于其当前状态的信息。然后你可以检查程序的状态并找出问题的原因。
场景:
项目启动卡死等处理
测试你的程序是否有并发性问题
发现多线程程序在并发方面是否健壮的一个好方法是使用断点,在碰到时只暂停一个线程。停止一个线程可能会揭示出应用程序设计中的问题,否则这些问题就不会显现出来。
计算保留的大小
对于每个类的实例,你可以计算它的保留大小。保留大小是指对象本身和它所引用的所有对象以及没有被其他对象引用的对象所占据的内存量。
这在估算重型单体或从磁盘上读取的数据(例如,复杂的JSON)的内存占用时,可能很有用。另外,在决定使用哪种数据结构时(例如,ArrayList与LinkedList),这也很有用。
在运行应用程序之前,确保在设置/首选项|构建、执行、部署|调试器中启用附加内存代理选项。
在查看类的实例时,右键单击一个实例并单击计算保留大小。