微服务架构的思想已经被广泛接受,各种最佳实践也层出不穷。虽然有各种方法论的指导,但到了具体实践的过程中,还是会有诸多的困惑。本文试图剖析从单体架构到微服务架构演化背后的深刻原因,从而更好地理解微服务的精髓。
从服务化谈起
软件的协作方式并不是凭空而来,而是依据很多我们实际生活中的既有规则来设计的。理解软件架构模式演化背后的动机,可以从我们实际生活中的场景寻找答案。传统的农耕社会,大家的协作方式是以物换物。很容易出现需要一张羊皮,却换回来一只羊的情况,如果这只羊携带了某种病毒,那问题就麻烦了。依赖软件包进行开发就非常类似这种情形,某个软件包有n个方法,而使用者通常仅需要少数几个,一旦未被使用的部分有漏洞,则非常尴尬了。
可不可以仅仅按需使用呢?对,答案就是服务化。某个服务用或者不用,都在那里。当然,依赖软件包还有跨语言的问题,也存在大量资源浪费的问题。通过一种“契约式协议”,确定了输入和输出的逻辑关系,然后就可以按照需要进行使用。这就像银行的存取款业务,服务一直在那里,何时用、用哪些由您的需要决定。
服务化带来的最大好处是可替代性增强。只要遵守“契约协议”,那么就可以作为服务提供者。从设计角度来说,如果需要支持提供相同标准的多个服务提供者,那么就需要考虑从需求出发,设计满足需求的最小功能集的服务。
软件分层架构
早期的时候,三层架构非常流行,展现层、逻辑层和数据库层各司其职。每一层把各个功能的逻辑集中到一起,但是功能和功能之间没有边界。为了更好地体现“契约”,通常业务逻辑会由接口和实现接口的方法组成。但是功能边界的问题依然没有解决。
边界不明确带来的问题则是任何一个改动,几乎整个大的功能都必须进行一次全面测试,因为无法确定这个改动的影响范围。软件规模越大,带来的潜在风险越大,事故所造成的影响也越大。分层并不能使得开发人员在业务逻辑上聚焦,反而随着业务越来越复杂,开发人员的负担也会越来越重。
边界的划分
有一种模式在较长一段时间内被认为是很好的解决方案,那就是 MVC。这种模式最突出的特点就是数据和展现存在某种对应关系,控制层只做请求的转发。比如某个页面做列表展示,那么只需要通过业务逻辑层获取数据,然后绑定到数据对象上即可,展现层会根据数据去渲染。
这种通过页面功能进行的边界划分,对于开发来说,通过不同的控制器可以较好地实现功能边界隔离。但是,在某些场景下,某个功能的处理速度成为瓶颈,就会成为整个系统的瓶颈。然而,又无法针对某些场景下才用到的逻辑进行水平扩容。所以,必须从业务的角度去识别某些需要具备“弹性”的逻辑,然后从“物理”上进行隔离。
上云与云原生
应用上云是一个曾经很热的话题,这个问题最关键的不是能不能上云,而是上云之后怎么办。如果没有使用云的“弹性”,那么上云也就失去了意义。对既有系统的改造成为了重中之重,但是这个过程是非常痛苦的,涉及的方方面面太多,风险也会很大。于是,大家希望直接从设计之初就充分考虑云的特性,然后再开发适应云环境的应用。
当划分好了业务边界之后,每一个部分的职位就会相对单一,当然,这些部分都是服务化的。服务之间的交互采用标准的基于消息的协议,所有动作都是基于事件驱动。那么当服务的职责足够明确、单一,是否就是我们通常所说的微服务呢?其实,还不是!服务在云上,必须具备一些特定属性。
微服务特性
能够称之为微服务,则需要满足云原生的要求,这样即使上云也是很简单的一个步骤。作为分布式系统中的一个组件,必须满足:
-
具备熔断机制
某个服务可能依赖另一个服务,当被依赖的服务无法访问时,则外部请求直接返回。当被依赖的服务恢复时,服务必须能够自动更新熔断状态,外部请求可以直接访问被依赖服务。
-
能够独立构建、测试和部署
微服务开发通常由某个微型团队负责,由于业务边界比较清晰,业务逻辑也非常固定,所以可以按照自己的节奏进行迭代和升级。
-
支持健康检查 微服务启动后,可能是被依赖的服务,那么被其他服务调用时,熔断器可能会通过健康检查结果设置自身容器状态,所以必须具备健康检查相关的接口。
-
支持重试机制
服务在访问被依赖服务时,很可能由于网络延迟等原因获取不到结果,但是重试机制可以确保,在一定的时间内获取到结果。所以,分布式系统访问的结果为:成功、失败和超时。
-
配置注入
微服务实例在运行时,可能会根据负载进行弹性伸缩,所以,依赖必须在运行时注入,而不能在编译打包时固定,更加不能依赖基础设施信息,比如IP地址等。
Kubernetes
Kubernetes 已经成为容器编排的事实标准,提供了很多特性来支持云原生应用的部署。比如 Service、ReplicaSet、Deployment、ConfigMap&Secret 等等,其强大的社区已经逐渐影响到了其他容器编排引擎,比如 Mesos、Swarm 等等。基于 Kubernetes 打造企业轻量级 Paas 平台已经成为了趋势。
总结
微服务并不是凭空而来的,更不只是规模小。了解微服务的诞生过程,理解了背后的动机就能够准确把握微服务拆分的粒度,以及在实践微服务过程中要把握的要点。
作者:付辉,JFrog 资深工程师/DockOne社区翻译
欢迎转载,但转载请注明作者与出处。谢谢!