基于微服务的开发正在改变我们整个行业,超过70%的人正在尝试开发基于微服务的软件。微服务简化了业务、流程、技术和人员的集成,将大爆炸的整体问题分解为一个可以独立处理的小集合。然而,它也带来了管理这些小集合之间关系的问题。我们需要不同的过程、工具、培训、方法和团队来简化微服务开发。
我们一直在开发一个关于微服务体系结构的高度复杂的项目,我们每天导入大量的观测数据,并建立统计模型来预测未来的需求。最终用户可以交互影响统计模型和预测方法。用户可以通过模拟影响来分析需求。有大约50个有界的上下文,100多个独立的部署单元在REST和消息传递上进行通信。运行整个系统需要200多个流程实例。我们从零开始开始这个项目,在微服务方面几乎没有任何实践经验,我们在项目规划、培训、测试、质量管理、部署和操作方面面临许多问题。
我将分享帮助我们克服这些问题的五大经验。
敏捷开发方法被认为是微服务开发的最佳方法,但前提是一致性良好。单体开发有一个可交付的和一个流程管道,但是微服务不同,我们有多个可交付的,所以除非我们对每个可交付的流程管道进行对齐,否则我们将无法实现预期的微服务开发的有效性。
我们也面临着项目规划的问题,因为我们不能很好地规划产品和用户故事,这可以产生独立的产品,我们可以应用流程管道。我们无法向最终用户演示业务价值,因为我们的产品工作流只有在此之后才准备好。我们曾经有非常大的用户故事,它有时超越了多个sprint,并影响微服务的数量。
考虑项目规划的以下方面:
1、为需求定义、架构、开发、DevOps和基础设施运行并行的sprint管道。为常见的问题和集成点组织一个Scrum。
2、为架构和DevOps保留少量的初始冲刺,并且只有在架构的第一个稳定版本和DevOps建立之后才开始开发冲刺。
3、架构PoCs和决策任务应该在实际开发脚本之前计划好几个sprint。
3、为每个sprint定义度量,以定量地度量项目质量。
4、清楚地指出在待办事项列表中的架构变更,并将它们优先排序。根据项目的当前规模和对微服务的影响,考虑他们的适应工作。
5、制定基础设施资源(专家、软件、硬件或工具)计划。
6、配置管理。
7、在项目导入中包括敏捷培训。
8、在Ready (DoR)的定义和Done的定义中包含多个sprint工件依赖项。
9、培训产品负责人和项目计划人员计划需求定义、体系结构等方面的scrum,以便他们实现DoR。
10、有更小的用户故事,确保在sprint中选择的故事是真正的单元大小,这将影响很少的部署单元。
11、如果在一个特定的sprint中添加了一个新的微服务,那么考虑一下CI/CD、基础设施、DevOps的工作。
在一个单体的应用中,基础设施管理在项目开始时并不是那么重要,所以与相关的任务可能会被延迟,直到稳定的交付开始,但是,在微服务开发中,部署单元很小,部署单元的数量也很高,因此需要一个强大的基础设施管理策略。
在项目中,我们需要花费大量精力来简化项目的内部组件,这对实现的功能范围有很大的副作用。
这里的基础设施包括横切组件、支持工具和运行系统所需的硬件/软件。服务注册、发现、API管理、配置、跟踪、日志管理、监视和服务健康检查等可能需要单独的工具。
在基础设施管理中至少考虑以下几点:
1、能力计划——从项目开始就进行能力计划,然后定期检查/调整。
2、提前获得所需的基础设施(软件/硬件/工具),并在团队采用它们之前进行测试。
3、定义一个硬件/软件/服务入职计划,该计划涵盖不同物理环境中的工具的细节,如开发测试、QA测试、性能测试、登台、UAT、Prod等。
3、考虑多个扩展的开发测试/集成环境,因为多个开发人员需要测试他们的工件,并且他们的开发机器可能不能保存所需的服务。
4、在基础设施管理专家的基础上加速项目的设置。
5、在项目的早期阶段定义部署策略并计划其实现。不要采用中间部署方法。如果您想要使用Docker和基于kubernet的部署,那么从项目开始就执行它——不要等待并推迟它的实现。
6、定义访问管理和资源配置策略。
7、对基础设施进行自动、主动的监控。
8、跟踪与项目范围并行的基础设施开发。
微服务可以独立开发和部署,但最终,很难在整个服务开发过程中维护标准和实践。一个基本的体系结构需要遵循微服务,然后让体系结构演进,这在这里可能会有所帮助。
我们已经定义了一个非常基本的体系结构,其中包含了日志记录、引导和一些常见的方面的核心平台。但是,我们考虑了演进过程中的许多内容,如消息传递、数据库、缓存、文件夹结构、压缩/解压缩等,它导致平台与微服务的功能范围并行地进行了大量更改。在跳转到功能范围冲刺之前,我们没有给核心平台足够的时间。
在基本架构中考虑以下内容,并在功能范围实现之前很好地实现它。不要过于依赖“从制度中学习,然后随机应变”这句话。
1、提前定义体系架构,保持领先的情况下,尽快和获得知识。
2、定义一个涵盖横切关注点和抽象的核心平台。核心平台可以包括日志记录、跟踪、引导、压缩/解压缩、加密/解密、公共方面、拦截器、请求过滤器、配置、异常等。平台还可以包含消息传递、缓存和数据库的抽象。
3、微服务结构——定义具有命名转换的文件夹和代码结构。
4、为CI/CD构建一个机制——定义一个CD策略,甚至是本地QA环境,以避免在UAT/pre-UAT环境中直接遇到问题。
5、定义一个架构变更策略——如何交付架构变更以及如何调整它们。
6、源代码、API、构建、配置和文档的版本策略。
7、继续验证NFRs的设计。
8、定义测试架构以覆盖测试策略。
微服务世界需要一种与单体世界不同的思维方式。每个微服务可以被认为是独立的,因此不同微服务的开发人员也是独立的。这会带来了差异性的挑战:我们希望我们的开发人员来管理代码一致性单元,遵循同样的编码标准,并在上面建立核心平台。同时,我们希望他们不要信任其他microservices的代码,因为它可能是由一些其他公司的开发人员开发出来的。
在你的团队管理中考虑以下事项:
1、向负责维护配置和依赖信息的少数团队成员定义“配置管理”的职责。
2、定义由开发人员/架构师组成的“合同管理”团队,他们负责定义微服务之间的交互。
3、基于有界上下文分配模块所有者和团队。他们负责与所分配的模块相关的所有事情,并向“配置管理”团队通报公众关注的事项。
4、开发人员应该只通过合同进行交流,否则他们将是一个完全独立的团队。如果合同中需要任何变更,则应通过“合同管理”进行。
5、从开发团队定义DevOps团队。一个人可以轮班,让每个人都了解操作系统。
6、鼓励团队中掌握多种技能。
7、自我激励团队。
9、持续的培训计划。
微服务每天都在发展,会不断引入许多新的工具和概念。团队知识构成需要及时更新。由于微服务体系结构相对独立,如果需要,您可以更改微服务的技术栈。由于团队是独立的,我们需要在团队中不断地分享知识。
我们面临的问题是,相同/类似的问题正在被不同的团队复制,他们试图以不同的方式来解决它们。比如:团队在理解有界上下文、数据隔离等方面面临的问题。
考虑以下内容:
1、对团队进行领域驱动设计、有界上下文、数据隔离、集成模式、事件设计、持续部署等方面的培训。
2、创建一个学习数据库,每个团队可以在sprint回顾中提交条目。
3、训练团队遵循单元测试、模拟和集成测试。大多数时候,“单元”的定义被开发人员误解。“集成测试”是最低优先级。它必须遵循;如果处理得当,它应该是最简单的东西。
4、分享性能方面技术知识——例如:
不要过度循环
有效地利用缓存
使用RabbitMQ消息传递作为Flow,而不是作为数据存储
并发消费者和发布者
数据库分区和集群
不重复
微服务正以很快的速度普及,随着时间的推移,会变得越来越成熟。我已经分享了我们在基于微服务的项目中所经历的一些痛苦的教训。我希望这将有助于您的项目避免错误。