戳破微服务的七大谎言( 二 )


问题在于,大多数新功能都需要一些跨多个服务的补丁 。

戳破微服务的七大谎言

文章插图
 
许多功能需要在两个或多个服务上开发
开发多服务功能需要在具有不同优先级和能力的团队之间安排大量会议 。考虑到他们从事的多个不同项目,这些团队可能需要异步协作 。你现在还需要交付经理来分配工作和管理迭代 。
从技术角度来看,实现多服务功能可能需要编辑多个存储库 。至少,它需要一种方法来测试在多个服务上运行的代码 。
对许多公司而言,这种多服务测试的需求是事后才会意识到的 。架构师在设计技术栈时会假设大多数开发工作都将在单个服务上进行 。多服务功能将很少见 。你如何手动测试多服务功能?你需要在机器上启动多个容器,并仔细设置每个容器的状态 。那单元测试呢?你将在哪里对多服务功能进行单元测试?是仓库 A 还是仓库 B?文档写好了吗?部署往往会破坏未调整好的服务 。很容易想象,数据流中的一个小错误会破坏多个下游服务 。我们应该期望工程师理解所有可能依赖其代码的下游服务吗?
如果你的组织没有投入大量的工程资源来构建多服务测试流程,那么除了最常见的功能之外,开发新功能的速度会像蜗牛般缓慢 。如果没有质量测试框架,看似简单的任务(例如“添加分页”)也可能会变成历时数月、跨多个团队的工作 。
3谎言三:部署众多小型服务比部署整个应用更安全“回滚”是现代软件工程需要面对的现实 。作为工程师,当你部署的代码会破坏某些功能时,必须回滚部署并还原提交 。没有人想要回滚——尤其是部署代码的工程师 。但是,好的公司知道错误的部署总有可能出现,因此必须对其进行管理 。
微服务架构的一个观点是,部署多个独立服务比部署整个应用更安全 。当一项服务中断时,其他服务还有回退可用 。整个应用程序将继续运行,客户不会有什么感觉 。
这种方法存在多个问题 。
首先,这要假设你的服务可以容忍其他任何服务的随机消失 。这是 Netflix 的“Chaos Monkey”方法 。但是,将其构建到服务中并非易事,测试它需要资源,并且除非这是工程的最优先事项,否则实践中人们多大程度上会遵守这一要求就不一定了 。
https://netflix.github.io/chaosmonkey/
其次,部署多服务功能时,服务的上线时间会有所不同 。在一段时间里,你的那些服务将有不同的版本 。对此有多种处理方法 。你是否在半夜部署?你是否并行维护不同的 API 版本?你是否使用托管流?所有解决方案都需要额外的工程资源 。如果部署意外破坏了(甚至不是部署的一部分)服务中的状态,会发生什么情况?你是否有针对任何意外情况的预案?
虽然单体部署也会出错,但是有多种方法可以缓解这种情况(蓝色 / 绿色、金丝雀等等) 。虽然这些方法也可用于微服务,但是设置和管理安全部署并非易事,应对一项服务总比应对多个服务要容易些 。
4谎言四:分开扩展服务通常是有利的在每个应用程序中,都有经常运行的部分和很少运行的部分 。很少运行的部件比频繁运行的部件需要的资源要少一些 。那么分开扩展这些部件是否有意义?
从根本上讲,扩展软件的原因是因为你的软件需要更多的核心资源 。这些资源可能是 CPU 周期、内存、磁盘空间或网络 。例如,当 CPU 以 100%运行时,可以启动另一个服务来减轻压力 。
对于大多数应用,水平扩展(克隆单体)就足够了 。水平扩展的复杂度较低,许多云服务都可以用很少的配置来做到这一点 。
相比之下,选择分开扩展许多微服务有两个常见原因 。首先,如果你的代码具有实质上并行的部分,则在某些情况下将计算块分配给不同的“worker”可能会有些意义 。重要的是,相对于每个任务的总计算量,数据传输和加速的开销必须够低 。因此,将十个计算块(每个计算耗时 10ms)发送到服务器,开销却为 100ms 就没有并行的价值了 。因为顺序执行耗时是 10x10ms=100ms,而并行却是 10ms+100ms=110ms 。但是,如果每次计算都花费 100 毫秒,则将它们并行化就能节省时间 。
其次,如果资源需求在整个请求中出现变化,则单独扩展各个微服务可能是有意义的 。例如,如果一个请求在开始时是受内存限制的,而在结束时是 CPU 限制的,那么就可以将请求的开始部分放在高内存服务中,将结束部分放在高 CPU 服务中 。即便如此,除非你是独角兽级别的企业,否则分开扩展服务带来的财务优势可能也无法抵消额外的复杂性 。


推荐阅读