揭秘软件开发中的达摩克利斯之剑

为什么你的程序总是出现 bug?

凭什么让改 bug 占据了你大部分的时间?

看完本文,保证你能设计出更稳定的程序,摆脱 bug 的缠绕,做项目更安心!


记得我在学校的时候,做的那些项目,不是为了应付课程作业,就是为了参加比赛时展示用,因此对项目的质量要求非常低。

到底有多低呢?

大部分的项目,只要基本的功能可以使用,就算完成了,完全不考虑任何的异常情况。甚至只要能成功运行一次,让我截几张图放到 PPT 或者实验报告里,足够向老师交差或者应付比赛答辩就行。

那项目出现 bug 怎么办呢?

  • 如果测试的时候发现有些功能不可用,那很简单,不管他,直接 PS 一张正常运行的图就行。
  • 如果比赛的时候发现有些功能不可用,那也很简单,把锅甩给 “现场网络不好” 就行。

但是,这些 “小技巧” 在企业中是行不通的,企业级项目必须为企业带来实际的价值,容不得半点马虎和欺骗。

我第一次进入企业实习时,还保留着自己在学校开发项目的狼性 ?,只要能够完成基本功能就行,保证以最快的速度完成开发。

有一天,当我洋洋得意准备早点下班时,测试同学走过来跟我说。

“喂,你的程序有 bug,这里用户下单怎么金额是负的?”

在分享这些之前,先讲个故事。

达摩克利斯之剑

古希腊传说中,达摩克利斯是公元前 4 世纪意大利叙拉古的僭主(古希腊统治者独有的称号)狄奥尼修斯二世的朝臣,他非常喜欢奉承狄奥尼修斯。

他奉承道:“作为一个拥有权力和威信的伟人,狄奥尼修斯实在很幸运。”

于是狄奥尼修斯提议与他交换一天的身份,那他就可以尝试到首领的命运。

在晚上举行的宴会里,达摩克利斯非常享受成为国王的感觉。当晚餐快结束的时候,他抬头才注意到王位上方仅用一根马鬃悬挂着的利剑。他立即失去了对美食和美女的兴趣,并请求僭主放过他,他再也不想得到这样的幸运。

软件开发正是如此,表面上机器是 “死” 的,只会按照人输入的指令或编好的程序来执行,一成不变,听话的很。好像我们写好代码扔到机器上后,就可以高枕无忧。

但真的是这样么?我们真的可以信任机器和程序么?

其实,在程序世界中危机四伏,人为因素、环境因素等可能都会对我们的程序产生影响。因此,我们必须时刻坚守软件开发的不信任原则,保持 overly pessimistic(过于悲观),把和程序有关的一切请求、服务、接口、返回值、机器、框架、中间件等等都当做不可信的,步步为营、处处设防。

我是一个身价过亿的大项目,每天服务着上千万的用户,帮助他们获得知识与快乐。

我的小伙伴们只看到我身上的光环和荣耀,但是他们看不到我背负的压力和风险,今天终于有机会和大家倾诉我的苦衷了。

记得很多年前,我还是个孩子,只有几个小主人开发我,那段时间,我成长的很快。虽然只有几十个人使用我,但我感到非常轻松和快乐,偶尔偷会儿懒,也不会被人发现。

后来,我的功能越来越多,越来越强大。每天有数之不尽的新面孔来和我打招呼,并享受我提供的服务。渐渐地,更多开发者在我身上留下了印记,我感觉自己正在变得复杂,也开始感受到了压力。我再也找不到机会偷懒,因为我一旦休息,就会让我的主人们损失一比不小的财富。

如今,我已经是一个成熟的大项目了,每天有上千万的用户依赖我,我终于拥有了更大的价值,却也增加了很多烦恼,感受到了更大的危险。

首先,同时服务千万用户,每秒钟都可能会有几十万、甚至几百万个请求需要我来处理,因此我必须每时每刻无休止地高负载工作,且不说休息,哪怕稍微慢了一点,就会遭到用户的投诉,主人们也会因此受到批评。

我的运行,必须依靠很多兄弟们的支撑,因此我必须和兄弟们好好相处,哪怕一个兄弟倒了,我都会受到影响。

在我强大的实力背后,有一颗非常脆弱的心。经历了那么多次的强化和改造,我的功能逐渐变多的同时,也因此被植入了各种框架和插件,体积像滚雪球一般越来越大,不知道什么时候就会爆炸。以至于主人们每次改动我时都要万分谨慎,我的成长也变得十分缓慢。

1. 开发工具可信么?

我们通常是在大而全的开发工具中编写代码,比如 JetBrains IDEA 或者 Vscode。很多刚开始写代码的同学、甚至是一些经验丰富的老手,都对开发工具保持绝对的信任。

比如你在键盘上敲击 a,那编辑器界面上显示的一定是 a

但是,由于内存不足等种种原因,开发工具其实也会抽风

比如你想要调用某个函数,通常敲击函数名前几个字母后,开发工具就会自动给你提示完整的函数名,但如果开发工具没有给你提示,你首先怀疑的是这个函数不存在,而不是编辑器没有按预期给出提示。遇到这种情况,可以稍等编辑器一下,或者进一步确认函数是否真的不存在,而不是立刻创建一个新的函数。

又或是项目无法运行,怎么排查都觉得没问题,这时不妨重新启动下开发工具,或者清理一下缓存,说不定项目就能正常运行了!

还有很多非常有意思的情况,比如编辑器一片大红,各种提示错误,但是项目依然能成功运行。

因此,在选用依赖库的时候,要做好充分的调研,尽量确认依赖库的安全,并且保证不要和已有的依赖冲突。

4. 编程语言可信么?

Java 是一种强类型语言,具有健壮性。这句话我相信所有学过 Java 的同学都再熟悉不过了。但是,强类型编程语言就一定可信么?

这里可能有同学就要表示怀疑了,如果我们一直使用的最基础最底层的编程语言都存在 bug,那我们怎么去相信建立在这些编程语言上的框架呢?

然而真相是,所有的编程语言都有 bug!而且基本每次编程语言发布新版本时都会对一些历史 bug 进行修正。就 Java 而言,甚至还有一个专门记录 bug 的数据库!

因此,不能完全相信对象存储,虽然大部分情况下大公司的对象存储服务很可靠,但不能确保万无一失。尤其是同步备份的场景下,是否真的同步成功了,又有多少同学关心过呢?不妨写个程序去验证和保障。

9. API 接口可信么?

在开发中,我们经常会调用其他系统提供的 API 接口来轻松实现某种功能。比如查询某地的天气,可以直接调用其他人提供的天气查询接口,而无需自己编写。我们也可以提供 API 接口给其他人使用,尤其是在微服务架构中,各服务之间都是以接口调用的形式实现交互协作的。

几乎所有的 API 接口提供者都会说自己的接口有多安全、请放心使用,那么 API 接口真的可信么?

其实,API 接口是最不可信的资源!

首先,API 接口的提供方可以是任何开发者,很难通过他们的一面之词来确定接口的稳定性和安全性。

即使这个接口性能很高、也很安全,但是你并不了解有多少人和你在同时使用这个接口,也许只有你,又也许是 100 万个其他的开发者呢?在这个竞争条件下,接口的 qps(query per second 每秒查询数)还能达到预期么?接口返回时长真的不会超时么?

更有甚者,偷偷地把 API 接口改动了,却没有给调用者发送通知,这样接口的调用方全部都会调用失败,严重影响项目的运行!

因此,我们在调用第三方 API 接口时,一定要慎重、慎重、再慎重!

此外,如果我们是 API 接口的提供者,也要注意保护好自己的 API 接口,避免同时被太多的开发者调用,导致接口挂掉。

4. 流量控制

上面提到,所有的请求都是不可信的,不仅仅是请求的值,还有请求的量和频率。对于所有接口,都要限制它的调用频率,防止接口被大量瞬时的请求刷爆。对于付费接口,还要防止用户对接口的请求数超过原购买数。

此外,还有一种容易被忽视的情况,假如你的接口 A 中又调用了其他人的接口 B,也许你的接口 A 自身的逻辑能够承受每秒 1000 个请求,但是你确定接口 B 可以承受么?

因此,需要进行流量控制,不仅仅是预防接口被刷爆,还可以保护内部的服务和调用。

什么,你说你的接口很牛逼,每秒能抗 100 万个请求,也没有调用其他的服务,那我就找 100 万 + 1 个人同时请求你的接口,看你怕不怕!

6. 多级缓存

上面提到,缓存对项目是非常重要的,不仅是提升性能的利器,也是数据库的保护伞。

但如果缓存挂掉怎么办呢?

有两种方案,第一种是为缓存搭建集群,从而保证缓存的高可用。

我们的项目其实远比想象的要脆弱,很多服务经常因为各种原因出现问题。比如搞活动时,大量用户同时访问会导致对项目服务的请求增多,如果项目顶不住压力,就会挂掉。

为了防止这种风险,我们可以采用服务降级策略,如果系统实在无法为所有用户提供服务,那就退而求其次,给用户直接返回一个 “友好的” 提示或界面,而不是强行让项目顶着压力过劳死。

配合服务熔断技术,可以根据系统的负载等指标来动态开启或关闭降级。比如机器的 CPU 被占用爆满时,就开启降级,直接返回错误;当机器 CPU 恢复正常时,再正常返回数据、执行操作。

Hystrix 就是比较有名的微服务熔断降级框架。

10. 数据备份

数据是企业的生命,因此我们必须尽可能地保证数据的安全和完整。

很多同学会把自己重要的文件存放在多个地方,比如自己的电脑、网盘上等等。同样,在软件开发中,我们也应该把重要的数据复制多份,作为副本存放在不同的地方。这样,即使一台服务器挂了,也可以从其他的服务器上获取到数据,减少了风险。

13. 弹性扩缩容

梦想还是要有的,说不定突然,我们原先只有 100 人使用的小项目突然就火了,有几十万新用户要来使用。

但是,由于我们的项目只部署在一台服务器上,根本无法支撑那么多人,直接挂掉,导致这些用户非常扫兴,再也不想用我们的项目了。

本站文章资源均来源自网络,除非特别声明,否则均不代表站方观点,并仅供查阅,不作为任何参考依据!
如有侵权请及时跟我们联系,本站将及时删除!
如遇版权问题,请查看 本站版权声明
THE END
分享
二维码
海报
揭秘软件开发中的达摩克利斯之剑
记得我在学校的时候,做的那些项目,不是为了应付课程作业,就是为了参加比赛时展示用,因此对项目的质量要求非常低。
<<上一篇
下一篇>>