2015 年底,Segment 博客刊登了一篇文章, Why Microservices Work For Us(下文简称为《Work》) ,三年多,又来了一篇更具话题性的新作: Goodbye Microservices: From 100s of problem children to 1 superstar(下文简称为《Bye》) ,两相比较,感觉还是有一定的代表性的,这里做一点整理和记录。
《Work》中提到,主要是因为原有架构中,故障处理不力,需要有更快的诊断和处理方法,这里提到了两个途径:
要针对某个功能加入监控指标,在原有单体架构中可能会造成不必要的影响,范围不易控制;而源码方面,越小的服务,通常也代表着相对易读的代码;这两个主要需求都指向了同样的解决方案:微服务。
将原有单体应用拆分为微服务之后,不但解决了监控和排错的问题,还带来了一些额外的好处:
这里只是原文中提到的好处,更多的照本宣科内容这里就不赘述了。
《Work》一文中提到了两次,新建微服务应该如何如何。作者似乎认为,微服务有必要更快的创建起来。但按照我的理解,微服务仅是通过进程隔离的强制手段使得模块之间的边界更加清晰,事实上,因为缺乏单体应用强大的上下文支持,同一系统内的不同微服务,往往会因为上下文问题,导致更加复杂的开发过程。
单代码库阶段
因为缺乏有效的时间说明,这一操作让人很迷惑,不知道是不是在《Work》发表的时候,各个服务还是在共用同一套代码。也在共用同一套测试方案。《Bye》中提到,一个失败的提交会导致整体测试失败,因此我们大致可以说,这一阶段里,CI/CD 过程也没能完成分割,个人认为,这种情况不太应该算作微服务。
多代码库阶段
为微服务独立创建各自的代码库,并享用各自的测试组件。
共享库阶段
我认为这一阶段呼应了前面的隐忧,在微服务落地之处,为了更快的建立微服务,开始出现了跨服务的共享代码库。
《Bye》的共享代码库一节,罗列了不少遇到的问题:
我眼中的微服务,务虚的角度上来说,有两个关键字:妥协,怀疑。
这里所说的妥协指的是,我们的系统是存活于一个非“理想状态”中的,不管是“拥抱变化”,还是“面向故障”,都是对不完美世界的具体应对方式。
而怀疑的设计态度,最简单的证据就是对隔离的强调,系统资源、数据的隔离都如此强调,我想,代码的隔离是不言自明的。
反观 Segement 的重构之路,(可能)在宣称微服务的时候,各个服务还躺在同一个仓库里,还在共享同样的测试过程。
在进行代码分离之后,又出现了两个不太容易理解的纰漏:
此处内容给人一种感觉:“今天是个好日子”。给我的感觉是,一些原本应该在微服务阶段完成的工作,甚至是在微服务阶段之前的单体阶段完成的工作,终于完成了——例如改进的测试方案,这能算是半渡而击么?
流水账写到这里,有两个深刻的印象就是,这个团队从来没想过这些微服务是彼此独立的,也从来没把每个服务作为一个单独的交付物进行完善。从这个印象出发,回到单体形态,可以说是——得其所哉。