10 个让微服务完全失败的 tips

这是三年前伦敦一个技术大会上的一场非常独特的分享,没想到一场技术大会上能有这么幽默的另类架构师,作者以反讽的形式举出了 10 个微服务环境下对系统搞破坏的 tips。我看了很多遍,其中的案例其实日常研发中大部分也都遇到过了,之前也总结过各式各样的吐槽,比如之前写的《中台的末路》《微服务的灾难》《MQ 正在变成臭水沟》等等。希望日后自己也能做类似风格的演讲。

下面是演讲的内容:

开场白,先是免责声明,让人对号入座就不好了:

disclaimer

然后是听众收益:

acquirements

老板想要搞事情,让公司系统更现代化,你不想这么干,得找点理由反驳他;或者你想破坏你们现在的系统;学习从实践中总结的血淋淋教训;具体案例做过了匿名化处理,让罪犯可以稍微心安理得一些。

老板从网上学到了新词汇,比如工业4.0(哪个营销号说德国人不讲工业4.0来的?);云 + 敏捷就是牛逼;Extreme agile cloud native digital microservice 听着就非常 modern。

然后把这个政治任务交给了 IT 人员,你们来干吧,我们全都要。

搞 IT 的还是要面向老板服务,一通调研,总结了微服务的特性:

microservices

靠,太复杂了,还是看猫片更轻松愉快哦!

cat

这后面举的例子,都可以用来给你的系统搞破坏,按照 awesome 度的排列是 10 -> 1 越来越 awesome。

awesome

10 - Go Full-Scale-Polyglot

polyglot
英[ˈpɒliɡlɒt]
美[ˈpɑːliɡlɑːt]
adj.	通晓(或使用)多种语言的; 用多种语言写成的;
n.	通晓多种语言的人;
[其他]	复数:polyglots

这是早期微服务吹的最多的多语言优势,你可以用合适的语言重构系统的任意一部分。这里推荐更激进的方式,最好把所有的技术栈全用上:

techzoo

有种类繁多的前后端技术栈,有种类繁多的各式打包工具,最终形成多彩的科技动物园:

  • 学到了技术知识,技术人员很开心
  • 可以用各种语言把同一个轮子造一万遍,好开心
  • 碰到了技术栈的问题(如 React 的 Bug),还能去逼着 Facebook 的人来修问题,很酷
  • 还可以搞出类似量子物理中的 Heisenberg monitoring 的问题,线上没法监控,开心

让系统有更多 risk 这样才能更有趣。这里我们说的 polyglot 有时也被人戏称为 polywtf。当然从另一些方面来讲:

  • 自由是人权的一部分
  • 每个人都喜欢解 puzzle - 我们可以有各种不同风格的接口,比如 REST,HAL,SIREN,这样人们在接入你的系统的时候就不太搞得清楚你到底在用什么玩艺儿
  • 程序员们都喜欢通过在 stackoverflow 上搜结果的时候交朋友
  • 我们可以用各种各样的 UI 组件,并且应该多尝试那些 beta 特性
  • 让运维们忙起来,可以用各种多样的监控和打日志方式,比如你还可以搞自己特别的日期格式,比如用中文来写日期,这样大家就都看不懂了

9 - The data monolith

share

分享是一种美德,我们让所有的系统都接入到一个 DB2 的数据库里。比如让 Account 和其它两个服务的数据库完全放在一起,这样大家都可以很高性能地读取各种数据。

这时候 Account 突然要把用户名从 VARCHAR(50) 改成 VARCHAR(200),这时候 Credit 服务炸了:

boom

很酷,这样简单的方式就可以搞成一团糟。

  • 分享是很棒的事情
  • 所有微服务都应该共享数据库
  • 不要让你的表或者 schema 归某个服务或者某个团队来管理
  • 保留那些潜在的依赖,比如每晚都把大家吵醒的连接池什么的

8 - The event monolith

Event Sourcing 是个完美的市场营销概念,同时可以解决很多问题:

  • 修订记录 - 完全无成本的不可变历史
  • 分布式数据管理
  • 用 CQRS 给微服务解耦
  • 还有很多其它优点

这时候我们的 Account 服务需要把 country 改成一个 free text 字段,因为以前的 code 没法满足当前需求了。

比如这里消息中的 country 字段需要增加特殊判断,那么我们在每个服务中都需要额外增加:

unless ISO.is_country_code(cnt) do
...
end

WET 的意思是 we enjoy typing,DRY 是过去老掉牙的理念了。微服务是一个很好的借口来让我们 copy && paste 代码。所以说 Wet is the new DRY,比如像 netflix 这样的公司,有成千上万的服务,我们可以把代码拷得到处都是,修 bug 的时候也需要修一大堆,这样就可以打一堆字了,开心。

  • 不要修改过去乱七八糟的 event
  • 不要想什么数据管理策略
  • 把补偿动作代码复制粘贴一下就可以解决问题了啦
  • 我们 event history,什么时候都能修 bug
  • 要是有人说我们这么个小系统,为什么要 event sourcing?那你只要回复他,我们哪天说不定就长到 Google 或者 linkedin 的规模了呢,万金油哦

7 - The Home Grown monolith

“If you wish to make MICROSERVICES from scratch, you must first create a FRAMEWORK”
– Carl Sagan (slightly paraphrased)

大家都喜欢造框架。

这里我们在公司内造了一套 event sourcing 的框架,每个需要发消息的系统都要接入这个 event sourcing 框架。

evid

有一天,我们突然要做个 breaking change,看起来消息里的这个 id 之前没啥用,我们就稍微修改一下,把原来的数值变成字符串吧。这个也不需要什么设计,毕竟设计这种事,我们敏捷信徒是从来不干的。

evid2

线上跑了一下,卧槽,炸了:

boom2

这种事件叫 Change the world event,既然产生了,那就得让所有的依赖服务升级 V2 来兼容这个升级。

微服务承诺各个服务可以并发开发和上线,不过现在我们有了这么个公共的框架,那他们还是得等框架开发完,才能一起上线。

  • Cross-cutting 依赖可以作为一种社交工具
  • 我们做这些侵入式的框架还是一种对工作岗位的保障
  • 写框架实在是太开心了,一定要多尝试
  • 如果你没啥思路,这里给你推荐一些 ideas:Collections, String-Utils, Logging, ORM!

6 - Think of the meat cloud

在当前的微服务场景下,所有微服务都是通过 CI 流程上线了。

不过完全自动化的环境是没有灵魂的,handcrafted 工作才能体现出你的 love。

运维人员都很喜欢 vi,vi 非常棒,各种令人匪夷所思的命令。我们用自己的爱来修改 nginx 的配置的时候写出了下面这样的配置:

location /custmoer {
}

这个错误只在线上犯,而在线下 test、staging 环境均不存在,这样只有在客户那里才会炸。这样和客户发生了沟通,非常的 social,在星期天休息日和客户沟通非常的开心。

  • 以手动维护为荣耀。
  • microsoft word 也是一种形式的自动化。
  • 如果有人 diss 你,你就搬出:我们又不是 Google,不需要那么复杂的基础设施
  • 如果有人问我们怎么做 LB 什么的,那我们直接说用 docker,因为 docker 可以掌管一切,LB,Security 什么的,你一说 docker 他们就跑了

5 - The distributed monolith

服务之间互相调用,级联调用,就像亲密无间的朋友:Friends stay close together。

Credit --> Account --> Customer --> Security

Credit 需要 Account 的数据,Account 需要 Customer 的数据,Customer 需要 Security 提供的安全特性。多重依赖,只要末端服务故障,整个服务一起扑街。只要 Security 挂了,大家一起完蛋。

The Musketeer Pattern

这种形式完美地结合了微服务的复杂性以及单体的脆弱性,是 shortest way to success。

  • 网络超级可靠的
  • 依赖越多,说明设计的越好,因为大家都在谈 dependency injection 啊
  • 同步的依赖就更棒了
  • 能服务一部分请求也比挂了强啊,不要熔断了

4 - The SPA monolith

前端 UI 直接对接所有后端服务,因为我们的后端服务要 micro 啊,只要让前端 big 就行了。

bigui

现在要加个什么字段检验,逻辑要加到哪里?无所谓了,随便能找地方塞进去就行了。

  • 这样我们前后端也没啥明确的业务职责划分,我们就可以开会来讨论职责和各种彼此冲突的 feature 了
  • 同时还能因为各种 side effects 让 tester 们忙起来,tester 也是要吃饭的,大家都开心
  • 要是发生了什么失败,非常容易找,反正就在那一坨 UI 里面

尽量别用组合,我们这样的大 UI 已经够了呀,也别用超链来关联,我们这样就够了。

3 - The decision monolith

都 2017 了,快上 Java 7 吧。

同事们想尝试新技术,我让他们准备 PPT 来说这东西有多好用,哈哈,好开心。

  • 这样可以让那些积极的同事受挫
  • 如果你已经超过 30 了,还可以这么说:这是企业级开发,小朋友
  • 象牙塔很美哦,你见过么?
  • 别人都是 SB,只有你最聪明

2 The monolithic business

业务人员也不知道你们的技术架构是啥样的,反正有需求么就拉会,有变更么就管理,这样就有了 Change Management,有 Requirement Management,这两样都是瀑布开发的好朋友啊。

  • 只要工作慢,我们就有更多的时间刷 Twitter 了
  • 只要为多个老板工作,我们就是个自由人,某个老板来找,我们只要说正在为其他老板工作就好
  • 变更和需求管理是你的朋友
  • 那些业务人员又不懂 Eric Evans
  • Conway 定律我们还可以反着用哦

1 - Use a HR driven Architecture

直接找一个会 React 的人比找一个软件大师来还是容易多了。

让前后端协作太顺畅也不行,最好在前后端里建起一堵墙,这样在墙中间就能填上各种 project manager,让他们在团队间互相传话。有需求听不懂?直接转给另一个团队就可以。

  • 我们程序员讨厌除了自己以外的所有其他人
  • 要避免知识的传播
  • 业务人员懂业务,技术人员懂技术
  • 没有人应该知道企业的业务大图,最好都在黑暗中工作
  • 开会还是很开心的,虽然我不喜欢人,但是开会的咖啡和零食还是不错的

要是工作中出 Bug 了怎么办,随时指责别人啊,因为:

It’s always the other team’s fault!

总结:

所有的失败都是因为隐藏在背后的某种单体:

  • Data

  • Frontend

  • Framework

  • Deployment and Release

  • Process,比如隐藏在 Agile 后面的 waterfall

microservice 表示更多的工作,我们需要与之抗争。

用各种 it's too difficult,we can't do it 的借口

多想想组织架构上的影响,不想改变。还是拥抱单体架构吧。

微服务是垃圾,坐等 SOAP 4.0

不要低估破窗效应,我是个 developer,我什么都能给你破坏掉

[1] 原视频链接

Xargin

Xargin

If you don't keep moving, you'll quickly fall behind
Beijing