从毕业至今,已经待过四家公司,算上实习期间三月游的公司差不多已经快十家了,时常会碰到一些有意思的言论。
在某司的时候就经常听到人说,“我们在 T 姓巨头的时候”,“我们在 A 姓巨头的时候”,“我们在 B 姓巨头的时候”,以任意一家巨头公司作为观点的前缀,显得观点就特别有分量。仔细想想,实习期间我也是在这些所谓的巨头公司待过的,我怎么就没有想到可以在自己编的故事前面加上这是 X 家的事情,所以还是他们比较机智。
大公司里的平均水平高,牛人多,并不代表进去的就一定是牛人,还有不少认不清是自己强还是公司机制强的混子。
即使是在大公司,也会有很多垃圾系统,他们内部没有限流,没有熔断,没有降级,也没有过载保护。但是他们却不会崩溃,为什么呢?
可能因为做这个垃圾系统的人很牛吧(笑
当然不是这样,我们又不是什么教的信徒,不能给这么神棍的结论。
按照这几年的观察,个人认为能够保障垃圾系统在整个大公司体系之中一直苟活的并不是限流,熔断和降级这些八股工具,毕竟它们连这些都没有。
主要就是压测。
以这方面做的比较成熟的电商为例,在每次人造促销节日之前,都是有长时间,大规模的全链路压测的。
能不能是单系统压测?
不行。单系统压测是发现不了问题的。简单起见,我们假设这样的系统中有 10 个 http 接口:
A/B/C/D/E/F/G/H/I/J
正常情况下的流量分布比较均衡,每个都是 10%,刚好凑够 100%。有一天节日来了,他们的流量分布大变样:
A: 40%; B: 5%; C:5%;D:5%;E:5%;F:5%;G:5%;H:5%;I:5%;J:20%。
每个接口的资源消耗不太可能都是一样的,如果 A 接口恰好是一个 CPU 密集型的计算功能,那么当前系统大概率直接挂掉了。
靠人肉显然猜不出来节日是这样的分布,你又没有点预知技能。。
所以关键就是要做全链路压测,用真实的流量从整个系统的入口发压,模拟真实的用户行为。然后将该行为放大几千几万倍,让每个系统实际地在处理这些压测请求,才能看出真实场景的流量分布情况。
看着好像挺容易,真实的全链路压测对所有需要承压的系统都是需要做一些改造的,对业务本身有一定的侵入性。一些技术栈统一的公司可以通过对公用的框架做统一改造来缓解侵入带来的痛苦,但某些五种语言八种框架的公司,就没那么容易了,需要漫长的改造时间对所有系统做改造。
有了健全的全链路压测机制,在这种机制下运行的垃圾系统只要会扩容就可以了,限流熔断?不存在的。
我们知道,国内大多数做业务的大公司,一般都是不写测试的。研发和白盒测试的工资差别造成了很多人鄙视测试这个工种,既然看不起写测试代码的,自己就更不会去写测试了。(哦,当然,很多靠玩生产关系起家的老板连写代码的都看不起,更不用说写测试的了。
再举个例子,我曾经碰到过一个从三巨头出来的大厂程序员,拍着胸脯说自己的代码一定没有 bug,但是他连断言都不会用,为了完成提升项目测试覆盖率的政治任务,测试代码到处都是 fmt.Println。
这样恶劣的开发环境,是怎么让大公司的系统没有崩溃得很难看的呢?
有两方面原因,一是公司内的灰度发布做的很完善,这样新业务可以做渐进式发布,既然一线城市到处都是网红和刺儿头,一点问题就上微博,那我们选个忍耐力比较强的二线城市总可以了吧。
发布后没有问题,再继续开放新城市,最后再对一线城市开放功能。
这是什么样的精神,这是把用户当成公司的免费 QA 的精神。至少这么玩还没有翻过车。
如果再恶劣一点的话,通过完备的数据体系,我们可以把用户里的那些老实人用人群圈选服务给圈出来,先向他们推新功能。
老实人嘛,就是那些从来不骂街不举报不上微博的老实人,让他们来做我们新功能的 MVP 版本用户。而且偶尔还会友善地通过内部渠道向我们反馈问题的那种人。遵从社会的要欺负就先拣老实人欺负的原则,可以保证我们不管做什么新业务都所向披靡。
另外一点,当前大公司基本都有自己的流量录制与流量回放系统。当系统在迭代时,将直接从线上采集的流量转成自动的测试用例,当作系统的测试输入,在 CI 阶段将不靠谱的修改直接拦截住。这里连程序员自己写测试都省了。
当系统功能迭代时,即使正在做迭代的研发是个菜鸡,他也很难将系统改出特别大的问题。因为我们把所有用户可能做的事情都在线上采集下来了,你改出问题,那就是你的问题。
一旦被大公司的研发体系麻醉,很容易让沉浸在其中的程序员产生自己很牛逼的错觉,当有一天,他们离开了这个密罐时,才能知道自己到底有多菜。