原文地址: 梁桂钊的博客博客地址:http://blog.720ui.comshell
欢迎关注公众号:「服务端思惟」。一群同频者,一块儿成长,一块儿精进,打破认知的局限性。segmentfault
近期肆虐的新型冠状病毒,已然成为大众视野的焦点。笔者,最近趁过年之际也看了一些相关新闻和书籍,其中,有一本名为卡尔·齐默《病毒星球》让我印象深入。固然,本文并非谈及新型冠状病毒和《病毒星球》,而是将故障和病毒进行类比,聊一聊计算机软件的故障应对机制,而其中关于病毒相关科普性的资料和数据来自于《病毒星球》一书。后端
人鼻病毒做为普通感冒和哮喘的罪魁祸首,是人类普遍存在的老朋友。鼻病毒巧妙地利用鼻涕来自我扩散。人擤鼻涕的时候,病毒会借机跑到手上,经过手再蹭到门把手和其余手碰过的地方。下次其余人碰到这些地方,病毒就会借机沾上他们的手,再进入他们的身体——大多数时候也是借道鼻子。鼻病毒能巧妙地让细胞对它们打开一扇“小门”,继而入侵位于鼻腔内部、咽喉内部或肺脏内部的细胞。在接下来的几个小时里,鼻病毒利用宿主细胞,复制本身的遗传物质和包裹它们的蛋白外壳。随后这些复制产生的病毒会从宿主细胞内破壁而出。此外,咱们每一个人的基因组中携带了近 10 万个内源性逆转录病毒的 DNA 片断,占到人类 DNA 总量的 8%。虽然这类病毒 DNA 中的大多数都没用,但咱们的祖先也的确“征用”了一些对咱们自身有好处的病毒。若是没有这些病毒,咱们甚至无法出生。在演化史上最近的瞬间,人类脱颖而出,病毒对咱们的生存功不可没。本来就并无什么“它们”和“咱们”之分——生物在本质上只是一堆不断混合、不断闪转腾挪的 DNA 而已。所以,鼻病毒在几千年前就开始让古埃及人患上感冒,内源性逆转录病毒早在数千万年前就入侵了咱们灵长类祖先的基因组。(摘自《病毒星球》)微信
故障也与之相似,它就好似生命体的 DNA 片断缠绕于计算机软件中,没法割舍。现在软件开发迭代频繁,咱们很难所有排除故障,只能说尽量多地发现和解决问题,避免故障发生在生产环境致使线上问题。当咱们遭到病毒感染,细胞释放一种名为“细胞因子”的信号分子,把附近的免疫细胞都召唤过来。它们让咱们的身体产生炎性反应,等免疫系统帮咱们把体内的病毒所有干掉。而在计算机软件,咱们也会有相似的场景,咱们的开发人员或测试人员一旦确认是程序 BUG,就会当即记录并周知相关人员进行处理与修复,并持续跟踪,直至故障解决。网络
感冒这么难治,一个缘由是它存在形态多种多样,因为其基于突变及快速复制带来来遗传多样性。而面对故障,虽然它的底层导火索可能就只有哪几种,可是因为技术的复杂性和业务的复杂性致使了计算机软件的总体复杂性。app
咱们知道 NPE (NullPointerExcepion)会给咱们带来巨大灾难,可是咱们在实际的研发中常常遗忘或忽视。这里,因为没有对受检对象进行非空判断致使 NPE 故障。测试
public static void npe03(){ Person person = null; System.out.println(person.blog); }
下面的示例将会致使 NPE,你发现了吗?ui
public static void npe01(){ Integer x = 1; Integer y = 2; Integer z = null; Integer val = false ? x * y : z; }
而这个示例,也是很是典型的由 Java 自动装箱和拆箱致使的 NPE 故障。spa
public static void invoke(){ Long x = null; npe02(x); } public static void npe02(long x){ System.out.println(x); }
再聊一个有意思的故障问题。你们都知道因为死循环会致使 CPU 100%。可是,致使 CPU 100% 导因是多样性的,笔者团队曾经遇到一个 JDK 8 的 BUG,它是因为 ConcurrentHashMap 递归建立对象扩展致使死循环,文章连接:https://mp.weixin.qq.com/s/O6UmB7YDKIYtNvqCOjNwDQ。日志
一般状况下,线上故障一旦发生,其后果通常都比较严重。因此,咱们须要尽快解决,下降其带来的影响和资损。例如,咱们团队以前口号是:“1-5-10”,即一分钟发现,五分钟处理,十分钟解决。那么,如何作到快速的发现线上故障呢?搭建成熟的监控系统就很是重要啦,例如经过 Zabbix 或 Prometheus 监控各类基础设施(MySQL、Redis、MongoDB、ElasticSearch 等)运行状况,以及业务系统的运行状况,以及 CPU、内存、磁盘 I/O、网络 I/O 等波动状况,还有 GC 状况、binlog 同步状况等等。那么,发现问题后,就须要经过告警系统根据业务规则进行多渠道(邮件、钉钉、电话)联系故障处理人。要快速解决,怎么办?首先,须要一套完备的日志排查系统(日志聚合 + 链路追踪),此外,还须要对于 JVM 相关能快速 dump 堆栈信息,对于自助分析有 DevOps 平台支撑。可是,最主要的仍是须要有一套预案体系。什么是预案系统?就是针对不一样的问题,有一套完整的预先方案来快速响应。例如,某个服务不可用了,笔者排查发现是因为进程假死了,那么就能够经过预案里面的执行方案执行 shell 脚本进行快速拉活。再好比,笔者经过监控告警感知到某个商家资金异常波动,那么此时经过预案里面的执行方案将其经过动态开关将其快速熔断。
可是,若是此次线上故障没有应急预案,又比较棘手,怎么办?别无他法,只能因着头皮来处理啦。注意的是,故障的评级通常根据业务的影响范围面而定,事实上,最本质的资金损失,包括直接的资损,例如前段时间某知名电商的免额优惠劵致使很是严重的资损;间接的资损,例如挖断电缆致使整个 app 没法使用,那么,转化成正常的交易额也是大把大把的资损呀。而后呢,过了 2 个小时,故障还没修复,可能原先定级 P2 的故障就会升级到 P1。
若是发生最差的状况,就是可能短期内没法解决,那么就极可能须要停服维修了。例如,近期肆虐的新型冠状病毒致使全国性的封城封路,事实上,也是由于咱们没有特效药(计算机软件领域的预案),也尚未研制出新药(计算机软件领域的解决方案),因此只能封城封路(计算机软件领域的停服)。
一般状况下,偶尔感冒会提供咱们的免疫力。而在计算机领域,偶然采起故障演练也能够尽量确保在线上运行的系统没有缺陷和故障。这里,Netflix 为应对不肯定性的领域带来了一种全新的思惟模式:混沌工程。事实上,混沌工程提倡咱们正面接受系统必定会存在缺陷和故障,而后咱们经过一系列实验找出可能发生问题的风险点,进而不断地加固系统。
故障演练能够模拟 CPU 满载、杀掉指定进程、域名访问不通、网络延迟、网络丢包、填充磁盘、磁盘 IO 高等场景,以下所示。
总结一下,故障就像潜伏于计算机软件的病毒,因为技术的复杂性和业务的复杂性致使了其排查和解决的困难性,咱们能够采起监控、告警、预案,以及故障演练提前发现故障并解决故障。
最后,欢迎关注个人微信公众号「服务端思惟」,里面有更多精彩文章与技术干货。回复”669“获取独家整理的精选资料集,回复”加群“加入全国服务端高端社群「后端圈」,内容过于专业,仅限服务端从业人员。