本文转载自微信公众号《脑子是炸鱼》,作者陈建宇。转载本文请联系脑筋急转弯公众号。《微服务之战》是一系列关于微服务设计思维的主题,主要针对微服务后出现的一些矛盾/冲突点,并不涉及具体的知识点深入。如果您有任何问题或建议,欢迎随时交流。上古开天辟地的时候,大单体转化为微服务后,服务的数量就增加了。每次上线新服务,项目的目录结构和基础代码都要重新整理,而且很有可能是通过ctrl+c、ctrl+v从原来的模板复制过来的,如下:但是基于模板模型,你很快就会遇到各种新的问题:随着跨业务部门/业务群使用的增多,你不知道框架的模板是什么时候复制粘贴的,你不知道对应的commit-id是多少,也不知道之前的BUG有没有修复,也不知道有没有其他开发者私改复制的模板。简单来说就是不可维护,相对独立。BUG可能相同,但没有版本规定。这时候你可以选择做一个内部基础框架和相应的内部工具(已经有用户市场),形成一个脚手架闭环:通过基础工具+基础接口,可以解决项目A、B、C。..基本的框架版本管理和公共维护问题,遇到框架BUG直接升级即可。在框架维护者层面,也可以通过注册机制了解基础框架当前的使用情况(例如:版本分布),方便后续的迭代和规划。同时,如果内部微服务有复杂的依赖关系,可以直接“升级”脚手架,再增加一层基础平台,通过CI/CD平台等关联创建应用,选择应用类型等基础信息,然后关联创建相应的应用模板,构建工具、网关、数据库、接口平台、初始化自动化用例等:此时可以通过结合基础平台(如:CI/CD)实现流程的标准化管控,以及成为提高效率的好帮手。万众创新但是,一切都像“开天辟地”那么顺利吗?事实上,在很多公司中,大部分都是在不同的时间、不同的团队同时进行多项创作。更现代地说,就是在一个公司里,不同的团队做出了各种各样的基础工具和基础框架。更糟糕的是,其中几个的规格可能并不完全相同。例如:框架对gRPC错误码的标准化处理的差异:业务错误码放在grpc.status.details中。业务错误代码放在grpc-status中。业务错误代码放在grpc-message中。或者HTTP状态码的区别:HTTPStatusCode是金标准,主体中没有定义业务错误码。HTTPStatusCode为200OK(宕机导致的500、503等除外),业务错误码由主体单独定义。一目了然,只要使用错误码/状态码就可以玩花样了。这将导致各种问题。比如在监控平台上,由于不同团队定义的状态码规范不同,即使是最基本的监控易用性也会出现问题。比如有的小伙伴会将业务错误码放在grpc-status属性中,而在标准的gRPC规范中,grpc-status和HTTPStatusCode一样有具体的状态码映射。这时,监控报警系统的实施难度就会很大。一般告警规则是基于哪个状态码?往往最终的演进路线与企业的组织结构有关,即康威定律,反映了一个系统的技术边界组织结构。业内常见的情况有两种:A合并B,B与A一致。从例子来看,基本是一个通用的集合(维度是公司/事业部/事业群层面的,跟公司的情况有关).A和B都独立发展。从一个例子来看,他们各自独立搭建,各自管理自己,偶尔也会触及彼此的界限,或者是公开分享,暗中讨论。显然,这其中的利弊得分开来判断。工厂里有多少框架,也有基本称霸江湖的血汗工厂。可能做基础设施适配的小伙伴印象会比较深刻。不同框架的header规范是不一样的,以至于连Mesh都免不了一顿ifelse。更何况在类似的服务发现/注册,限流熔断,基础拦截器,各种SDK的同厂内部框架各重新实现。假借名曰框架支持这些,就让他用,但这可能会造成未来新一波的技术债。同时,框架维护人员可能会离职去其他公司。这也发生在前端行业。他们带着自己修炼过的经文离开,在群里留下一个无人维护的架构。这个时候,他们只能硬着头皮找B/C角接受,上来的人可能想法不一样。单从公司的角度来看,这是一个巨大的危害,长此以往,就是一场灾难。综上所述,本文主体分为“创造世界”和“万众创新”两个部分。理想很丰满,但现实大概很骨感。微服务是一把双刃剑。在带来好处的同时,它们也常常带来负面影响。架构的复杂性很难预测。所以,本质上,需要一个脚手架团队不忘初心,不断发现问题,不断解决问题。但无论如何,尽快基本统一主要语言和基础技术栈,做好产品闭环,会是一个很好的方向。
