[架构]单体和微服务

原文约1600字,阅读约需4分钟。发表于:

多大的服务 “宜小不宜微”,不宜过大的单体,也不宜滥用微服务,应保持在合适的大小。 (ps. 这里只讨论服务的大小。不讨论服务的手段,拆分解耦、服务发现、mesh、告警、限流、全链路建设,都是好的实践,任何服务都可以做的同样好) 什么样的服务大小属于合理的服务?核心有两点,合理划分服务边界,匹配组织结构。 团队视角:服务的规模应该尽量限制在最小团队,约3人左右的团队为宜 ❎ 过大!跨团队修改同一服务,风险大且不利于基础建设。没有人对整体的架构和质量负责。没有人有全局视角,写代码因为不了解改动范围容易出故障。 ❎ 过大!10人以上的团队不宜修改同一服务。很可能服务定位不清晰,10个人的信息交流会有很多gap,效率会大大降低 ❎ 过小!团队每个人管三四个服务,说明服务数量过多,无用工作会增加,效率也会降低 业务视角:保证产品需求变更如果只在本团队内,修改的服务1-2个即可 ❎ 过小!改一个小小的功能,牵扯4-5个服务。服务太小了,效率降低 ❎ 过大!同时有四五个业务需求,对应数十个研发同时修改一个服务,而这些功能看起来并不密切。这说明服务包揽的功能太多了,已经膨胀的太大了 更微=更好? 我们以一个模块划分合理、大小合适的单体服务为例,看看如果拆分的更微小,对比起来会有哪些点值得关注: 关注点 合理的单体 更微服务 性能 无劣化 约数ms的劣化 复用性 可以仓库内直接引用 不可复用其他仓库代码;所以也不会复用到bug 可读性 容易找代码 需要跨的仓库多,层次深,理解困难 研发成本 编译可能较慢 写代码、编译、调试、发布、部署都需要多仓库并行,成本高 部署成本 单机器 高,需要多台机器 代码合入 公共部分容易冲突 不容易冲突 微服务教 我们看下某网站对单体的批评,一一回应下: 开发效率低:所有的开发在一个项目改代码,递交代码相互等待,代码冲突不断 确实,代码冲突会变多。但在单体内部模块划分合理的情况下,冲突的只会是公共模块;如果这些代码冲突了,使用微服务也会冲突。 代码维护难:代码功能耦合在一起,新人不知道何从下手 耦合是模块设计的问题,不是单体的问题。而且单体断层更少,更容易阅读 部署不灵活:构建时间长,任何小修改必须重新构建整个项目,这个过程往往很长 没发现编译时间有显著区别。部分单体仓库会编译多个产物,建议针对性编译,效果更好。 稳定性不高:一个微不足道的小问题,可以导致整个应用挂掉 绝对意义上,微服务存在同样的问题,而且更难定位。相对意义上,如果说单体的复用代码带来了问题风险的扩大,这属于因噎废食,不可取。 微服务给我们带来了什么样的反思?拒绝盲目创新,提防吹牛皮但不切实际,小心滥用导致过犹不及。 再次回到起点:monorepo 有趣的是,越来越多人意识到了微服务的问题,最终又回归了单一的仓库,并发明了一新的词:monorepo。 Segment.com 提供活动收集和转发服务,每个客户都需要使用一种特殊格式的数据。因此,工程团队最初决定混合使用微服务和多代码库。这一策略效果很好——随着客户基数的增长,他们扩大了规模,没有出现问题。但是,当转发目的地的数量超过 100 个时,事情开始变得糟糕起来。维护、测试和部署超过 140 个代码库(每个代码库都有数百个日益分化的依赖关系)的管理负担太高了。最终,团队发现他们无法取得进展,三个全职工程师花费了大部分时间来维持系统的运行。 对于 Segment 来说,补救办法就是合并,将所有的服务和依赖迁移到一个单一代码库中。他们必须协调共享库并且测试所有内容,虽然花了很大的代价,但迁移非常成功,最终的结果是降低了复杂性,增加了可维护性。 每个团队的精力是有限的,当每个人管理的仓库>10个,团队管理的仓库>100个,会出现非常多的问题: 团队无法集中注意力管理。有很多的仓库大部分人并不知晓。这部分代码不再能被复用,也不再被了解 开发要打开很多IDE并发进行,容易出错。测试需要部署非常多的服务,也不能跨服务debug。发布时需要发布过多的仓库,发布容易遗漏;发布有很复杂的依赖,发布也会花费更久的时间。 无法发起整体性重构。重构一个服务和同时重构10个服务的难度不是一个级别。

合理的服务大小应保持在合适的范围内,不宜过大也不宜过小。团队视角下,服务规模应限制在最小团队,避免跨团队修改同一服务。业务视角下,保证产品需求变更只在本团队内修改的服务数量应为1-2个。拆分微服务会带来性能、复用性、可读性等方面的影响。微服务的盲目创新和滥用应引起警惕。Segment.com的案例表明,当微服务和多代码库的管理负担过大时,合并到单一代码库可以降低复杂性,增加可维护性。团队管理过多的仓库会导致问题增多。

[架构]单体和微服务
相关推荐 去reddit讨论