为什么选微服务而不是动态扩容单体
动态扩容单体能不能做能。单体应用部署成集群前面挂个负载均衡流量大了加机器。问题在于选微服务的驱动力从来不是吞吐量。如果你面临的问题只是「流量扛不住了」代码性能又不错加机器就行根本不需要微服务。选微服务是因为有些问题你把单体复制100份也解决不了。动态扩容单体能解决什么集群的本质是多台相同的机器做同样的事。用户请求进来负载均衡器分发到后面的某一台服务器上。后面这几台服务器跑的代码一样数据也一样。集群解决两个问题单机扛不住的流量加机器分摊和单点故障挂一台还有别的顶着。这两个问题用集群解决是对的。对相当一部分的公司来说动态扩容单体够用。那为什么还有那么多公司走向微服务因为他们遇到的问题不是吞吐量。核心模块被边缘模块拖垮单体应用所有功能跑在同一个进程里共享同一份资源线程池、内存、CPU、数据库连接池。我之前在的公司订单、支付、库存这些核心链路和后台报表、运营活动页面跑在同一个服务里。报表模块有个慢SQL执行时间几十秒把数据库连接池占满了。结果不只是报表不能用订单接口也拿不到连接整个服务全部超时。这种情况下你扩容到10台机器有用吗没用。因为每台机器上都跑着同样的代码每台机器上的订单模块都可能被同一台机器上的报表模块拖垮。你复制了10份完全相同的风险。订单这种核心模块本来就是靠后的、应该是稳定的、有自己发布节奏的。它不应该因为一个运营活动页面的问题而不可用。把核心模块拆成独立服务之后边缘模块出问题核心链路完全不受影响。这是进程级别的隔离不是加机器能解决的。我们当时把订单、支付、结算、库存、商品拆出来之后稳定性提升了很多你是没见过订单服务被无端端影响后CTO那个脸色恨不得马上把你裁掉。能理解的毕竟下单是赚钱的入口不能随意出事的。开发协作的效率瓶颈这个问题和技术无关纯粹是人多了之后的协作问题。几十号开发在同一个代码仓库、同一个服务上改代码提交的时候冲突不断。合并一次代码要花不少时间解决冲突。上线更麻烦A组的功能测完了B组的还没好整个服务没法单独发布只能一起等。你加再多机器也不会让代码冲突变少不会让发布排队消失。拆服务是在拆团队的工作边界。每组负责自己的服务独立开发、独立测试、独立部署。代码不再互相干扰上线也不用互相等。这个逻辑和康威定律说的是一回事系统架构最终会趋向于组织的沟通结构。我的经验是团队超过15到20人的时候这个问题就会变得很明显。不到这个规模单体上协作的摩擦还在可接受范围内。资源特征差异导致配置矛盾有一类操作特点是执行时间长、吃内存、吃CPU、占连接。比如PDF解析、大文件上传、邮件拉取、OCR识别。这些操作和核心业务的CRUD放在同一个服务里配置是矛盾的。核心服务的接口超时设在3秒就够了超过3秒的请求大概率已经有问题了。但大文件上传需要30分钟的HTTP超时。核心服务的JVM堆内存2G就够了但PDF解析需要4G甚至8G。你不可能给核心服务设30分钟的HTTP超时那样一个慢请求会占住线程半小时。你也不可能给核心服务配8G堆内存来应对偶尔出现的大文件解析。更严重的是稳定性风险。一个PDF解析任务跑两三分钟5个并发一来Tomcat线程池被占住一大块。加上PDFBox解析100MB的PDF在内存里要展开好几倍几个并发堆内存直接打满OOM核心服务整个进程挂掉。把这些操作拆到独立的资源微服务之后两个服务可以用完全不同的配置。资源微服务堆内存配8G、超时配30分钟、文件大小限制放开到500MB。核心服务保持轻量配置快进快出。即使资源微服务OOM了核心服务完全不受影响。动态扩容解决不了这个问题。你给每台机器配8G堆内存来应对偶尔的大文件解析平时全是浪费。你给每台机器配30分钟超时核心接口的异常请求也会占住线程半小时。什么时候该拆微服务给一个判断标准对照着看信号具体表现加机器能解决吗建议核心链路被边缘模块连累非核心功能的故障导致核心接口不可用不能风险被复制到每台机器核心模块独立部署团队协作效率下降代码冲突频繁、发布互相等待、新人上手成本高不能这是人的问题不是机器的问题按团队边界拆服务资源特征差异大某些操作执行超过10秒、内存占用超100MB、需要特殊超时不能配置矛盾无法调和按资源消耗特征拆分不同模块发布节奏不同核心模块求稳少发边缘模块迭代频繁不能单体只能整体发布各模块独立服务独立发布流量扛不住QPS超过单机承载能力能集群扩容就行不需要微服务最后一行是关键。如果你的问题只是流量代码性能又不错集群扩容确实是更简单的方案。微服务要解决的不单单是流量问题。什么时候不需要微服务团队5到10个人业务量不大单体应用跑得好好的没有出现上面那些信号就不要拆。分布式不会让慢的代码变快只会让它更慢。原来进程内纳秒级的方法调用拆成微服务后变成毫秒级的网络请求。一个业务流程串四五个服务每个服务慢50ms到用户那里就多了200多ms。拆了之后还有新的代价网络通信、数据一致性、分布式事务、链路追踪、服务治理。每一项都需要额外的基础设施和人力投入。没有专门的基础架构团队兜底的话服务治理跟不上、调用关系理不清故障只会比单体的时候更多。小结回头看这个问题提问者的困惑在于把微服务和扩容放在了同一个维度上比较。它们解决的是不同层面的问题集群扩容解决吞吐量微服务解决隔离和协作。两者不是替代关系实际生产中是叠加使用的先拆成微服务然后每个微服务各自部署成集群。很多公司走向微服务不是提前规划好的是核心链路被拖垮了几次、亏了钱才下决心拆。技术选型这件事没有绝对的好坏只有适不适合当前阶段。团队10个人以内、业务简单、没出过稳定性事故单体加集群是最省心的选择。等到上面那张表里的信号开始出现了再考虑拆也不迟。架构演进应该是业务驱动的不是技术信仰驱动的。最近在知乎出了「应付6000万会员的秒杀系统专栏」和「几亿用户,百万并发的C端商品系统实战」专栏感兴趣的可以订阅一下。至于知识星球的可以搜老码头的技术浮生录它是一个能实际帮你解决难题的星球。有问题的找知心的Sam哥支持无限次语音一对一解决你遇到的难题。「另外后续我新写的所有对外的付费专栏在星球内都是免费的且可以拿到所有源代码。」知识星球内后续将推出20个付费专栏覆盖电商全链路选购线用户会员营销线中后台购物车服务营销系统订单系统商品服务用户系统支付系统菜单服务结算服务从前台选购到中后台结算星球成员全部免费后续新增也不额外收费。我的知乎账号:SamDeepThinking