本文作者把微服务向 Service Mesh 的进化融入到了三国故事中,妙趣横生。故事比较长,大家慢慢看,精彩的在后边。
话说曹操官渡之战大获全胜,收编了袁绍的大批将士和军队,有搞 Python的,有搞 JS 的,有搞 Ruby 的,有搞 C++ 的,还有搞 PHP 的,不一而足。
浩浩荡荡,号称百万大军,正向东边来袭。
刘备率领自己的 Java 大军,哦不,其实也就万人不到,一边抵御一边向东逃去。
刘备:“曹操大军压进,如何是好啊?”
诸葛亮:“主公不必多虑,我等可投奔东吴。”
刘备:“他们岂肯逆曹而收留我们?”
诸葛亮:“亮自有妙计,且听我慢慢道来。”
诸葛亮:“东吴世代熟悉水战,创始人孙坚,一直使用 Go 语言,其儿孙策继承父志,搞出了 Docker。现在孙策之弟孙权在位,我们可以说服他联合抗曹。”
刘备:“talk is cheap,你先带赵云去东吴游说,我们带着军队随后就到。”
01 东吴
诸葛亮来到东吴,说明了来意。
诸葛亮:“曹操正率百万大军向东吴进攻,目前形势危急,我主刘备欲助东吴一起抗曹”。
张昭:“主公,万万不可听信此人,曹操明明是要进攻刘备,与我东吴何干?”
诸葛亮:“此言差矣,如果我主刘备被灭,东吴离灭亡还会远吗?”
张昭:“你说你来帮我们一起抗曹,但是你们自己兵力微弱,被曹操打得节节败退,又如何帮我们?”
诸葛亮:“我主自幼苦练 Java,又有关羽张飞赵云等良将,最近我又在研究微服务兵法,配合东吴 Docker 可以发挥最大的效能。”
张昭:“什么乱七八糟的,无非是想借我们的兵力而已。”
见两人在朝堂上吵吵闹闹,孙权一时头疼:“汝等暂且退下,容我三思。”
孙权回到房间,马上下诏书让周瑜回来。
02 周瑜
周瑜回来见过孙权:“主公,事情我都听说了,我也是主张抗曹。”
孙权:“哦?你有把握吗?”
周瑜:“我一直在训练 Docker 水军,战斗力已经 Max,只是我要见那诸葛亮一见”。
说完,周瑜向诸葛亮的住处奔去。
诸葛亮早已正装等候。
周瑜:“诸葛先生,你的好意我心领了,但是你也知道,你军不到一万,加上我军也不到五万,如何抵抗曹操百万大军?”
诸葛亮:“曹操百万大军看似很多,其实都是纸老虎。你想,曹军大部分都是收编其他势力,比较杂乱,什么 Python、JS、PHP、Ruby、C++,这些人在一起,相互之间无法配合,战斗力要大打折扣的。”
周瑜见诸葛亮一言就说到了要害,知道此人并不简单,决定继续试探。
周瑜:“汝可有良策?”
诸葛亮也不虚:“不如你我各自在手心写下计策,同时打开?”
周瑜一听,觉得有点意思,便拿笔在手心写下一字,诸葛亮也在手心写下一字。写完,两人头碰头,同时打开手心。
只见两人写下的是同一个字,“船”!
周瑜:“我以为你会写火。”
诸葛亮哈哈大笑:“我也以为你会写火”。
看到了吗,英雄的想法总是相似的,无论他们多么想与对方不一样。
两人彻夜长谈,共同商定抗曹方案,从微服务谈到服务降级,限流,最后到 Docker 部署,制定了周详的作战计划。
计划制定完毕,两人作了最后一次模拟演练,演练过程中,这二人竟然有一种惺惺相惜的感觉。
天亮了,周瑜离开了诸葛亮的住处,路上,他心思极重:“诸葛亮真乃旷世奇才,可惜和我各事其主,此人必不可久留。”
话分两头说,曹操这边倒是正在发愁。
03 曹营
曹操:“我虽有百万大军,但是大部分是北方人士,到这东吴水土不服,特别是在水上作战,不像在陆地这般平稳,大批将士一到水上就脑袋发晕,这可如何是好呀?”
谋士荀彧率先开口:“主公所言极是,依我看来,咱们的部队兵力过于分散,搞 Python 的、搞 PHP 的、搞 Ruby 的、搞 JS 的、搞 C++ 的,就像一片大海中的五个孤岛一样,无法联合作战啊。”
曹操:“爱卿所言正是我之担忧,我扩张太快,内部尚未磨合好,战斗力怕是要打些折扣啊。汝等有何良策?”
谋士程昱说道:“主公可听说过万能的重写?”
曹操:“这是何意?”
程昱:“我们可以选择一种语言,比如 PHP,将其他语言实现的系统全部用这种语言重写一遍。这样大家都用一种语言,相互之间能够紧密配合。”
曹操:“这需要多长时间才能完成?”
程昱:“大概需要两年时间。”
曹操:“这可不行啊,兵贵神速,等上两年时间,那刘备和孙权都不知道能发展成什么样了。”
正在这时,曹营中一个声音说道:“我有一计,可以不用重写系统。”
①庞统
曹操寻声望去,只见坐下一人,样貌极丑,却一副胸有成竹的样子。
曹操:“哦?你说说看!”
庞统上前说到:“主公可听说过 RPC?”
曹操:“RPC?什么东西?”
庞统:“就是远程过程调用的意思,虽然每个系统实现的语言不一样,但是只要遵循某种协议对外提供接口,比如都对外提供 HTTP 的接口,它们便可以相互调用。”
曹操:“这样就不用重写系统?来,你来给我详细说说。”
庞统:“比如那用 Ruby 写的系统,将自身能够提供的服务用 HTTP 接口封装一层,用 PHP 写的系统只需要发起一个 HTTP 的请求,便可以调用那 Ruby 系统提供的服务了。”
曹操:“嗯,明白了,这样改造需要多长时间?”
庞统:“因为不用重写,业务代码也不用大改,只需要用 HTTP 将某些服务包装,不出一周便能完成。”
曹操一听大喜:“行,就按照你的方案来,你来实施吧。”
庞统带领曹操的将士们对系统进行了改造,让原本割裂的五个不同语言的系统相互依赖,全部连了起来,完美地实现了曹操所需要的所有功能。
改罢,庞统暗自欣喜:“连环计已经完成,我现在该赶紧逃离曹营了。”
庞统想要坐筏渡江,只听后面有人拍了他的肩膀:“汝献此计策,不怕项上人头不保吗?”
②徐庶
庞统一听计策被识破,大惊失色,回头一看,原来是徐庶,提到嗓子眼的心又放了下来:“哎呀,元直兄,你这样吓人可不好啊,我心脏病都快被你吓出来了。”
这徐庶正是向刘备间接推荐诸葛亮之人,只是母亲被曹操控制,不得已而在曹营,发誓终生不为曹操献一计。
徐庶:“基于远程调用的分布式系统,我很早就在研究,这里面的复杂度可是单机程序所不能比拟的。”
庞统:“哦?愿闻其详。”
徐庶:“首先你要考虑被调用方挂了怎么办,要做限流和降级方案,还要考虑调用的负载均衡问题,还有服务的自动注册和发现,要有注册中心。你现在只是带领将士们实现了功能,根本没有考虑系统的稳定性和容灾情况,这不是把曹操往火坑里推?”
庞统一听哈哈大笑:“不愧是元直兄,不过老板们只要实现功能就行,谁会管什么容灾和稳定性?”
徐庶:“看来曹操天数将尽,你走吧,就当没见过我。”
庞统坐上竹筏往东吴而去。
04 开战
月黑风高,长江上的浪花拍打着两岸,发出巨大的声响。江岸两边,曹操与周瑜隔江相对。就在今晚,曹操向孙刘发起了总攻,而周瑜也早已做好了战斗准备。
不远处,诸葛亮登上了七星台,与周瑜遥相呼应,相互配合。
曹操一声令下:“全军出击”。
百万大军驾驶着一艘战舰,朝周瑜这边驶来。
而那周瑜,只有区区十几艘小船,与那战舰一比,就像蚂蚁和大象。
曹操巨大的战舰向周瑜发动着猛烈的攻击。而那周瑜却不慌不忙,一面命令将士们顶住火力,另一面,暗中观察曹操那巨型战舰的火力分布。
他在寻找系统弱点。
突然,他发现曹操战舰的东北 45 度角火力有点慢,不像其他地方那么猛烈,一个火力开回比其他地方慢了 50ms。
是的,就是这转瞬即逝的 50ms,也瞒不过天才都督周瑜,他一声令下:“集火。”
由于周瑜的系统是基于微服务设计的,每个微服务都可以独立缩扩容。而系统又是用 Docker 部署。
周瑜军队需要做的就是将其他系统的 Docker 容器关闭,然后启动进攻东北 45 度的 Docker 容器。
两条命令,整个过程不超过半分钟。
05 逆转
半分钟后,周瑜军队完成了集火的操作,曹操战舰的东北 45 度火力模块突然遭受了巨大流量火力冲击,瞬间挂掉了。
这一挂不要紧,关键是系统其他模块都依赖于这个东北 45 度火力模块,结果很多模块都无法正常工作了,整艘战舰,只有很少的几个点还能输出,其他火力全都哑了。
那东北 45 度区是用 Python 写的,负责他的人正是曹军大将张辽。
张辽一看模块挂了,赶紧下令:“重启!重启这个模块!”
但是重启了之后,这个模块依然扛不住周瑜全军的火力,起来又挂了。
张辽:“不行了,必须要扩容,西北 45 度区夏侯敦那边没有火力,赶紧去那边调十台机器来扩容。”
那西北 45 度区是用 NodeJS 写的,首领夏侯敦收到张辽的救援请求,马上调拨了十台机器给张辽。
但是要在这新的十台机器上部署 Python 模块谈何容易,张辽部队全部上了,都在手动部署,装 Python 环境,设置环境变量,拷贝代码,设置配置文件,这一套流程下来,十几分钟过去了。
结果要启动的时候,报错,Python 依赖的一个系统库与之前 NodeJS 用的一个系统库冲突。
这下张辽是真的慌了:“重装,赶紧重装系统!”
嗯,整艘战舰的人都等着张辽在这重装系统,然后再装 Python 环境,设置环境变量,拷贝代码,设置配置文件。
06 曹操
曹操觉得此次胜利在握,正在战舰的监控室里一边喝酒,一边绣着十字绣。只见快一个小时了,十字绣已经绣了一半,还没有传来胜利的消息,便问身边人:“怎么还没有灭了周瑜?”
那身边人也是个欺上瞒下的主:“主公不必惊慌,咱们系统有一个小模块出了点问题,应该没有大碍。”
曹操:“我系统大大小小几十个模块,一个模块出问题算什么?”
他哪里知道,自己的系统早已被庞统全部连了起来,由于级联的效应,一个模块挂掉,已经足矣让整个系统 80% 功能不可用。
07 破曹
张辽这边还在重装系统,周瑜的火力已经透过那东北 45 度火力模块打到了系统缓存层,缓存层很快出现了热点,一下子战舰着起了火,缓存层很快被击穿了,火力到达了数据库,数据库瞬间挂掉了。
张辽见情势不妙,赶紧连滚带爬去监控室里找曹操,只见曹操还在那优哉游哉喝着小酒,绣着十字绣。
张辽大喊:“主公,求求你别绣了。周瑜的火力已经打过来了,赶紧从后门逃走吧。”
曹操一开始还不相信,但见那火势很快烧到了监控室,自己只能带着将士们连滚带爬逃出战舰,朝那华容小道逃去。
周瑜登上曹操的战舰,没有寻得曹操,将士们都准备追击,周瑜却不慌不忙:“别忙着追那曹操,你们赶紧去那七星台,把诸葛亮先给我软禁起来。”
将士们来到七星台,只见台上早已空无一人,诸葛亮已经离开了东吴。
赤壁之战惊天大逆转,微服务加 Docker 战胜了耦合严重的曹军战舰,曹操会这样善罢甘休吗?
08 复盘
曹操自从赤壁之战大败之后,一蹶不振,本来的绝对优势变成了天下三分的局势。
曹操有个习惯,每次吃了败战,都要面壁思过一段时间。吃了这么大一个败战,曹操已经面壁思过了一年时间。
一年后的今天,曹操准备好 PPT,想着召集众将士们一起复盘。
曹操:“一年,一年了,我没有发动过战争,就是因为赤壁之战对我的打击太大。”
众将士不语。
曹操:“若郭奉孝在,不使我至此啊!”
郭奉孝名郭嘉,是曹操军中第零大谋士,可惜天天 996,身体不好,赤壁之战前就病逝了。
众谋士听闻,都羞愧难当。
曹操:“你们谁能说说,赤壁之战失败的根因是什么?”
谋士荀彧先发言:“依我看都怪那庞统,献个什么连环计,把我们系统改得乱七八糟,没有考虑稳定性和容灾情况,才导致一个模块挂了,整个系统都挂了。”
曹操:“庞统何在?”
程昱:“庞统早已离职。”
曹操恨那庞统也是恨得牙痒痒,这种 Low 逼谋士,技术渣,上来胡乱在系统里写些垃圾代码,把系统搞臭了就离职。
但是回头想想,也是自己先同意了让庞统去做改造,自己也有不可推卸的责任。
曹操:“还有其他原因吗?”
武将张辽也发言:“我们系统要缩扩容非常麻烦,要手动重装系统,再装环境。”
曹操:“其他人不也一样吗?”
荀彧:“非也,我听说那周瑜,用的是什么 Docker,系统缩扩容半分钟就完成了,所以才导致我东北 45 度火力模块瞬间被集火挂掉。”
曹操一听,原来还有这段战况,开始后悔自己不应该盲目自信,坐在监控室里喝酒,他把那绣到一半的十字绣扔进了垃圾桶:“以后我再也不绣了。”
曹操:“我这一年来一直在反思,庞统那厮提出把系统改成分布式,用 RPC 互相调用,这并没有什么错,只是没考虑系统稳定性和容灾能力,例如网络不通,负载均衡,限流降级,服务发现等等才致此大败。我也有个疑问,为什么孙刘那边把容灾做得这么好呢!”
这时座下一人大喜:“时机已到!”
他站起身来:“这主要是因为刘备那里用的是 Java,有很多'限流降级','服务发现'的系统可以直接使用。比如著名的 Hystrix。”
09 司马懿
站起来这位不是别人,正是曹营第一大谋士,与那郭嘉齐名的司马懿。
曹操:“那我们也可以拿过来用啊!”
司马懿:“主公,现在是不可能的,因为这些工具和 Library 很多都是用 Java 语言写的,和微服务密切绑定。”
司马懿一边说一边展示了一张图:
曹操立刻明白了:“这些微服务所依赖的库实际上和服务本身有了深度绑定,而我们有五种语言,每个语言都去实现一遍同样的工具和库,不但需要两三年时间,还是巨大的重复和浪费啊!”
司马懿道:“这些能力确实是每个服务都需要,但是并不需要每种语言都去实现这些能力。”
曹操和众臣表示不解。
司马懿开始放大招:“我们需要一个思维的升级,大家想想,这些微服务系统需要的特性其实是公共的,为什么不能把这些公共的特性做到底层平台中呢?想想看,我们做一个 HTTP 调用并不需要理解 TCP 的细节,那里边可是有流量控制,失败重传啊。”
荀彧恍然大悟:“软件业的所有问题果然是可以通过增加一个中间层来解决啊!”
曹操瞪了荀彧他一眼,这种总结的台词通常都是我来说的。
不过曹操老谋深算:“你能修改网络协议栈,来增加一个层来实现这些限流降级和服务发现的功能吗?”
司马懿道:“主公明鉴,确实不能,所以我们得改用代理的模式,服务本身不直接连接到其他的服务,而是将所有的流量导送到一个小的代理,由代理来实现需要的特性。这个代理是通用的,所以我们可以用各种语言写微服务了。”
注:这个代理被称为 Sidecar,即边车,摩托车旁边的那个座位
10 Service Mesh
司马懿:“我们的微服务都可以使用这种模式,这样就组成了一个网格,就是 Service Mesh。”
司马懿:请看看上图,浅蓝色部分代表咱们现在各个语言的业务模块,灰色部分代表代理(Sidecar),你可以看到,业务模块只和自己的代理通信,而真正实现相互之间通信的是代理。
程昱:“哦,我明白了,这倒是一种方法。那么实现 Service Mesh 需要多长时间呢?”
司马懿:“不用自己造轮子了,现在已经有一些现成的方案,比如 Istio。”
曹操一听大喜:“行,就按照你说的来改造,但是这次改造完成,我们要执行严格的灾难测试。”
司马懿将代码回滚到庞统来之前,然后改造系统,把系统搭在了 K8S 之上,用上了 Istio,整个系统改造花了不到半年时间。
11 测试
系统改造完毕,曹操安排了张辽对系统进行灾难测试,主要就是把一些模块搞挂。
而那 Service Mesh+K8S 搭载的系统,已经完全能够承受这种级别的灾难了。
曹操看到测试结果以后大喜,在铜雀台摆上了酒席宴请众将士。
曹操:“来,把甄姬叫来给大家跳个舞。”
众将士都沉浸在甄姬美妙的舞蹈当中,而曹操心里却已经盘算着如何灭掉孙刘。
参考文章:
https://philcalcado.com/2017/08/03/pattern_service_mesh.html