闻香识微服务

微服务已经成为了后端开发的主流,也成为了后端初次见面打招呼的内容.
微服务三个字从这字面上可以理解,但它的内涵确实是各人有各人的理解,因为微服务本身并没有被严格的定义.噢,不, 它有被定义,只是在不同的时间段被不同的权威的人定义了,据可查的资料,大概有4位专家前后给出了不同的定义,所以大家都不知道真正的定义是什么了, 也不知道未来微服务的定义会变成什么样. 因为它没有像数学公式被严格的定义。


这篇文章不试图搞清楚微服务的确切含义是什么,因为这这样做是徒劳无功的。
本文试图探索

  • 微服务大概是什么?
  • 为什么是微服务?
  • 要实现一个微服务,它应该具备哪些行为和特征?
  • 微服务的未来
  • 微服务带来的副作用

微服务大概是什么?

名不正,则言不顺,言不顺,则事不成。一个事物的准确定义是讨论这个事物的前提以及是后续对这个事物采取行动的基础. 正如上面所说,微服务没有被严格的定义。所以这里不能采取学院派的手法来讨论微服务。

现在假设有个用户服务,这个用户服务支持:添加,删除,修改和查询用户。用户的信息包括姓名,电话,性别,职位,地址等等.
那这个用户服务是不是微服务, 至少现在它看来是微服务。但这还不够,它还需要支持

  • 从实现的角度来看,代码在物理上是隔离的.
    • 如果代码不是物理上隔离的,这就会导致用户服务,地址服务,订单服务在同一个 jar文件里,这样服务就不能扩展了。 所以代码必须是物理上隔离的,这才有动态扩展的可能行。动态扩展了多个实例之后,也就有了容错性。
  • 从设计上来说,微服务职责是有边界的。如果想从用户服务获取用户的工作单位呢?不好意思,没有,请去地址服务里拿。怎么确定这个边界呢?这是另外一个大的话题.

上面这两点是我认为微服务必须具备的。这两点其实隐含了一些前提和衍生了一些必然的结论. 比如,代码库是隔离的,意味着用Java语言写的微服务可以被用Js写的微服务替代. 如果一个服务职责边界清晰且足够小的话,那们意味着这个服务是可以被组合的。

应该不会有比用户服务更简单的服务, 但不是说所有微服务都应该像用户服务这么简单。


一家饭店有一个厨房,两个服务员.
厨师的主要职责是:烧菜。
服务员的主要职责:切菜,上菜,收拾桌子。
如果以后客流量激增,那么可以再招一个厨师和三个服务员, 很显然如果上面的职责集中到一个人身上,是无法做到细力度的控制的.
这里有个问题,切菜应该服务员负责还是厨师负责?没有标准答案,这个需要领域专家从统计学上给出建议. 这也大概是软件设计的魅力吧

为什么是微服务?

因为微服务的本质就是拆分一个系统,系统拆解的越小,这一小部分就更容易被理解和控制。 分解的具体讨论可参考博文《分解》

要实现一个微服务,它应该具备哪些行为和特征?

理想的情况应该是:

  • 弹性扩展
    量变引起质变。 当用户的数量上升到一定的规模之后,只需要增加相应的机器实例就可以解决问题,这是最理想的解决方案。
    • 如何让一个服务可以有多个一模一样的实例? - docker或者虚拟机
    • 请求一个服务的时候,如何选择某一个服务实例?- 负载均衡
    • 不同的请求如何对应到不同的服务实例? - 路由
    • 一些服务会有各种各样不同的参数,比如JVM参数,数据库连接字符串,如何管理这些参数?- 配置中心
    • 这些服务的网络地址是动态变化的,如何管理动态变化的网络地址? - 服务注册中心.
    • 一个用户进来,哪些服务他可以访问,哪些服务他不可以访问 - 鉴权
    • 用户的请求很多,如何限制用户的请求? - 限流
    • 如果一个服务因为某种原因不可用了,即使增加实例也没用,那么就应当让请求不要继续这个服务了 - 熔断
    • 服务A调用服务B,然后调用服务C, 如何知道这个调用链? - 监控
  • 业务演化
    业务的改变大体有两个
    • 维护现有系统
    • 开发新的功能

但无论是维护现有还是开发新的功能,我们不希望看到下面场景

  • 开发一个新的功能很难,不知道怎么和现有系统集成。
  • 维护一个功能很难, 就好像拆炸弹一样,生怕碰到不该碰的东西,一碰就爆炸,就是这个系统太脆弱了。

微服务的未来

  • 从分解的角度来说,基本上不可能拆的更小了,再拆连裤子都拆没了。上面提到的用户服务可以算是最小的微服务.
  • 从规范的角度来说,对鉴权,限流,网关,负载均衡,配置中心等等形成一个标准。每个实现都遵循相同标准的时候,可以有效地降低开发者的认知成本,符合开发者的心智模型.
    • 正例:Java对依赖注入有JSR330的规范,这样不同的依赖注入框架可以遵守相同的标准
    • 反例:JS模块化方案AMD和CMD.
  • 一切可以自动化都应该自动化或者必将自动化。当然,这个结论不仅仅适用于微服务。
  • 更好的性能. 比如性能更高的传输协议。

微服务带来的副作用

当大家沉浸在微服务真香的状态中,不要忘记微服务是有代价的.

  • 网络之间的通信。比如服务A调用服务B的时延是50ms, 如果调用链是A, B, C, D,那么这个时延就更长了,只要有网络之间通信,就存在不确定性.
  • 当微服务数量很多,且有不同团队维护的时候,这个沟通成本和维护成本是非线性的.
  • 需要一个掌握全貌的人,如果不能掌握业务全貌,出了问题都不知道根源在哪里. 根据鸡蛋不能放在一个篮子的原则,掌握全貌的人最好多于一个.
  • 相比于传统MVC开发团队,微服务对开发者的要求要高些.