saminigod 2020-03-05
【51CTO.com快译】引言:微服务架构虽然有着诸多优势,但是贸然从单体架构切换过去,可能导致成本的激增,以及灾难性的意外错误。本文和您一起讨论十二种值得遵循的,从单体架构向微服务转型的设计原则与优秀实践。
不知您是否还记得,过去传统的应用程序往往是作为一个整体被开发出来,然后被打包成为一个代码包,进而作为一个整体单元被部署的。一直以来,这种单体架构本身和与之相关的维护极具复杂性,而且开发与迭代速度也相当缓慢。这些都在促进软件开发企业去不断地寻求具有可持续性、灵活性、以及易于集成的新型替代方案。
微服务架构(请参考:https://dzone.com/articles/microservices-architecture-what-when-how)的出现打破了这样的僵局。它代表了众多小型、自动化和自包含的服务的单一集合。下图展示了系统如何通过一个API网关(请参考:https://dzone.com/articles/what-are-api-gateways-1),去访问多个微服务的逻辑。
微服务架构虽然有着诸多优势,但是贸然从单体架构切换过去,可能会让许多企业由于低估了整体的复杂性,而导致成本的激增,以及在研发的关键时刻出现灾难性的意外错误。下面让我们一起讨论十二种值得遵循的,从单体架构向微服务转型的设计原则与优秀实践。
1. 提供单独的数据存储
在考虑迁移之前,请事先弄清楚将会如何根据各种微服务组件来分离数据的存储。您可以通过使用诸如“命令与查询责任隔离”(Command and Query Responsibility Segregation,CQRS,请参考:https://dzone.com/articles/microservices-with-cqrs-and-event-sourcing)之类的架构模式来实现,以使得数据对每一个微服务都是私有的。
如果各个服务都无法成为其数据的唯一所有者,那么就会导致多个服务需要访问同一个私有数据库的情况,即:产生了耦合问题。也就是说,我们最好不要在微服务之间直接共享数据,而是要通过API来实现。
2. 建立专门的团队
微服务的主要优势体现在云原生的应用上。这就意味着:任何更新,都需要相对快速且实时的发布。也就是说,任何停机都会给业务造成重大的损失。因此,如果您想进行线性且高效的扩展,就需要为每个微服务分配专门的开发团队。
不过,光靠开发人员则很难掌控大型应用全面的端到端方案。我们需要拥有一支专业的团队,在熟悉管理细微差别的基础上,凭借转换技术与开发效率,进而遵循微服务的各项优秀实践。
3. 使用自动化进行独立部署
为了将单体架构分解成为多个单独的微服务,我们需要确保实现“构建和发布”的自动化结构。这样不仅可以有助于减少总体的交付时间,而且可以加快发布的速度,进而改善部署的整个过程。可以说,有了自动化,微服务就能够被妥善地封装到容器中,并能够有效地部署到包括云端在内的任何环境里。
4. 利用REST API的好处
开发人员在创建REST(Representational State Transfer,表示性状态传输)API时无需安装任何其他的软件与库,因此它为微服务提供了巨大的灵活性,数据也不再绑定到任何特定的方法或资源之上。通过REST API,微服务可以处理多种类型的调用,返回不同的数据格式,以及具有通过正确地实施超媒体,来修改结构的能力。
5. 了解文化的转变
对于传统的开发人员而言,他们习惯了端到端的测试环境。而随着从单体架构迁移过渡到基于微服务的架构,他们必须突然从大的格局转为关注一小部分的功能,而且管理层对此还充满了期望。可见,这更大程度上是文化上的转变,而不仅仅是开发技术上的变化。也就是说,开发人员需要理解和平衡公司愿景与自身工作方式的转换。
6. 将迁移分解为多步骤
如果您过去从未处理过此类迁移,那么请您做好无法一蹴而就的准备。单体架构通常会涉及一个包含有存储库、部署、监控、以及其他复杂任务的协作网络。因此,最好的方法之一就是:在暂时保留单体结构的基础上,并行开发其他作为微服务的功能。一旦实现了新的服务,同时团队也已对新的流程有所了解,我们就可以在厘清如何将旧的架构分解成为相关组件的基础上,开始逐一进行迁移。
7. 在混合系统上构建分离系统
定义不同复杂部分之间的交互作用和过程,是微服务的关键设计原则与优秀实践之一。因此,我们在迁移项目的初始阶段,就应当考虑到拆分系统。每个拆分系统都应当对于正在构建的架构来说是唯一的。我们可以通过检查单体结构,来持续监控各个组件的性能,以便了解各个组件之间的差异性,以及在微服务转换时可能出现的问题。
我们可以参考如下监视过程的工具:
8. 隔离运行时(Runtime)进程
由于我们往往针对不同的垂直细分领域有着不同的流程,因此我们需要在运行时的级别上也具有一定的隔离性。例如,您可以通过某种形式的分布式计算,来分别实现容器化、事件架构、各种HTTP管理方法、服务网格和断路器(circuit breakers)等。
9. 将正确的技术与正确的微服务相配对
正所谓殊途同归。也许在您的团队中,不同的成员会偏好使用不同的技术和编程语言来实现微服务,但是请尽量选用那些易于日后方便更改或替换的技术,来实现快速上手与直接迭代。当然,如果您并不确定哪种技术最适合自己的项目,那么请在决策过程中考虑以下方面:
10. 考虑使用域驱动式设计(Domain-Driven Design)
域驱动式设计(请参见:https://dzone.com/refcardz/getting-started-domain-driven)在某种程度上可以被理解为:应用于业务模型的面向对象编程。作为一种设计原则,它利用实践规则和思想来表达面向对象的模型。简单来说:我们需要围绕着自己的业务领域来设计微服务。例如,Netflix等平台就是使用不同服务器上的微服务,来进行内容交付和相关的跟踪服务。
11. 区分专用资源和按需资源
如果您的主要目标是提供卓越的客户体验,那么请考虑将专用资源和按需资源区分开来。例如,针对某个电子商务平台,我们可以通过构建其微服务和云架构,来实现快速且安全地在内部平台和云环境之间,部署并转移不同的工作负载。这样不仅缩短了资源的响应时间,也使得迁移到云端的流量与资源更加直观。
12. 治理对开源工具的依赖
对于开发人员来说,使用开源的微服务工具进行安全性、监控、调试、以及日志记录,可谓“家常便饭”。但是,请确保不会以过分依赖某些库和工具的方式,去干扰架构的性能或安全性。我们可以参考如下方面,同时根据实际的开发需求和所用到工具的类型,来实施各种适当的组织策略。
总结