Follow me on GitHub

是否应该上微服务?

时至今日(2019 年),微服务已经飞入寻常百姓家,但关于微服务的争论却还没有停止(事实上早就该停止了),我在公司 espace 群里经常听到两种截然不同的观点:

  1. 微服务解决了很多问题,不上微服务就是不先进,就是技术落后;
  2. 微服务没有解决问题,反而引入了很多复杂性;

这两种说法各自阐述了微服务的一面,合起来才是对它的完整描述:

以增加复杂度为代价,微服务解决了很多问题。

至于该不该使用微服务,则需要先了解微服务解决了什么问题,又引入了什么问题,只有明确了它的优点和缺点,才能根据实际业务需求做出理智的权衡。

单体应用

首先,应用开发模式从单体应用到 SOA,再从 SOA 到微服务,是一个自然发生的演化过程,这里我把 SOA 和微服务统称为微服务,因为 SOA 相当于微服务的早期版本。

最早的时候,应用都是单体的(monolithic app),因此开发、部署、运维都围绕单体应用这个“太阳”运转,单体应用通常只有一个安装包(例如 jar 包),所以 开发、部署非常简单,这是它的优点。

单体应用内部由许多组件组成,但整体只有一个进程,导致 维护困难

  1. 一个组件修改,需要重新部署整个应用;
  2. 组件之间缺少 强边界(hard boundaries),组件之间的依赖复杂度不断增加,导致应用整体的复杂度增长过快、代码质量下降;
  3. 单体应用难以水平扩展,大多数只能通过更强的硬件进行垂直伸缩,但单台服务器的硬件能力有上限,且要考虑性价比;

水平扩展、垂直扩展各有利弊:

  • 垂直扩展:不需要改代码,无脑提升配置即可,但有上限,而且现在上限越来越容易达到;
  • 水平扩展:可能需要 大量改动代码,而且部分组件 几乎无法水平扩展(如关系型数据库),优点是成本较低,而且几乎没有上限;

微服务

这些缺点在“上古时期”并不明显,但随着时代发展,这些问题的影响越来越大,解决之道即微服务,微服务把单体应用中的组件拆分出来,形成一个个独立的微服务,从而解决前面的问题:

  1. 独立部署:每个微服务都是独立进程,因此单个微服务的修改只需要部署该服务即可,不影响整个应用;
  2. 复杂度:微服务之间存在明确的边界、依赖,可以很好的控制复杂度增长;
  3. 独立扩展:扩展粒度变成微服务,即使单体应用存在无法水平扩展的组件,拆分成微服务后可以扩展其他组件;

独立部署前提:未改变对外接口,或接口的修改 向后兼容,因为微服务的对外接口 相对稳定,所以该限制可以接受。

微服务不是银弹,带来优点的同时,有以下缺点:

  1. 分布式系统的固有问题
    • 服务注册、发现
    • 负载均衡
    • 限流、熔断
    • 动态扩展
  2. 部署困难:
    • 微服务本质是分布式系统,当应用由成百上千微服务组成时,部署极其困难:
      • 不同微服务环境要求不同,比如有的微服务需要强力 CPU,有的需要 SSD 盘,有的需要高性能网卡;
      • 部分微服务相互协作,整体作为一个子系统对外提供服务,它们需要部署在同一台主机上;
      • 微服务之间存在依赖,随着微服务数量增加,很快将无法手动处理这些依赖;
  3. 运维困难
    • 请求处理经过了哪些微服务,在哪个环境出错了?
    • 上百上千个服务的日志如何查看?

在微服务实践的早期,以上问题没有明确有效的处理方式,大家的微服务基本处于“裸奔”状态,后来针对分布式系统的各种问题,出现了很多对应的解决框架,例如用于服务注册与发现的 Zookeeper、etcd、Eureka、Consul 等,用于限流熔断的 Sentinel、Hystrix(已停止维护)、Resilience4j 等,以及集大成的 Spring Cloud 大礼包,到此为止,由分布式导致的问题基本解决。

但部署问题直到 Docker + K8S 出现后才得以解决,而且现在的趋势是将第一类问题下沉到基础设施层解决,因为诸如服务注册和发现、负载均衡之类的问题与业务并不相关,如果基础设施屏蔽这些问题,则应用开发者完全没必要关注它们,所以 Docker + K8S 可以解决第一、二两类问题。

第三类问题目前普遍的做法是:

  1. 借助 Zipkin/SkyWalking 等追踪分布式请求;
  2. 借助 ELK 构建日志分析系统;

可以看到,微服务的使用成本很高,需要很多支撑工具,如果完全从 0 开始,需要耗费大量的人力去做这些支撑工具。

权衡

总结一下微服务的优缺点:

  • 优点
    • 独立开发、部署、交付;
    • 独立扩展,水平扩展方便;
  • 缺点
    • 需要很多支撑工具;

我把微服务的优点分为两类,分别对应两类微服务的“鼓吹者”,即咨询公司和互联网公司:

  • 咨询公司喜欢微服务独立开发、部署、交付的优点,但他们的产品一般不存在所谓的大流量、高并发需求,因此对水平扩展能力相对关注较低;
  • 互联网公司产品的流量很大,因此他们对水平扩展能力更加关注,但同时也喜欢独立开发、部署、交付的能力(谁能不喜欢呢?);

至于要不要使用微服务?

如果单体应用能满足要求,就不要用微服务;如果单体应用已经无法满足,那么恭喜你,说明你的产品发展势头很好,大刀阔斧上马微服务吧,至于微服务的缺点,活人总不能被尿憋死吧。