vlambda博客
学习文章列表

读书笔记《hands-on-docker-for-microservices-with-python》跨团队协作和沟通

Collaborating and Communicating across Teams

正如我们之前所讨论的,微服务的主要特征是能够并行开发它们。为了确保最大效率,我们需要成功地协调我们的团队以避免冲突。在本章中,我们将讨论我们需要了解的不同元素,以确保不同的团队成功地协同工作。

首先,我们将介绍如何在不同的微服务之间获得一致的愿景,不同的通信结构如何塑造软件元素中的通信,以及如何确保我们不会在软件中积累垃圾。然后,我们将讨论如何确保团队在发布上相互协调,并改进他们的流程和工具,使它们越来越可靠。

本章将涵盖以下主题:

  • Keeping a consistent architectural vision
  • Dividing the workload and Conway's Law
  • Balancing new features and maintenance
  • Designing a broader release process

在本章结束时,我们将了解如何组织和协调独立工作的不同团队,以便我们能够充分利用它们。

Keeping a consistent architectural vision

在基于微服务构建的系统中,每个团队都能够独立于其他团队独立执行大部分任务。设计服务以使它们尽可能独立并具有最小的依赖关系是实现良好开发速度的关键。

因此,微服务分离允许团队独立和并行工作,而对于单体应用,大多数从事微服务工作的人会跟踪正在发生的事情,甚至会因工作超出特定开发人员关注的领域而分心.他们会知道新版本何时发布,并看到新代码被添加到他们正在处理的同一代码库中。然而,在 微服务架构re 中并非如此。在这里,团队 专注于他们的服务,不会被其他功能分心。这带来了清晰度和生产力。

但是,仍然需要对该系统的全球视野。需要对 系统的架构应如何随时间变化以进行调整有长远的看法。这种愿景(在单体系统中)是隐含的。微服务需要对这些变化有更好的理解,这样才能有效地发挥作用,所以能够统一这种全球视野的领先架构师非常重要。

架构师的角色是软件行业中没有统一定义的职位。

在本书中,我们将把它定义为一个处理 API 和服务整体结构的角色。他们的主要目标是在涉及技术问题时协调团队,而不是直接处理代码。

明确指定负责系统全局架构的人员有助于我们保持对系统应该如何发展的长期愿景。

In small companies, Chief Technical Officers may fulfill the architect's role, though they will also be busy handling elements that are related to managerial processes and costs.

领先架构师的主要职责是确保微服务部门在其发展过程中保持有意义,并确保服务之间通信的 API 保持一致。他们还应该努力促进跨团队制定标准并在整个组织内共享知识。

架构师也应该是最终决策者,当涉及到关于什么特性与什么微服务相关的任何问题,以及可能出现的涉及多个团队的任何其他冲突时。这个角色在从单体架构到微服务架构的过渡过程中起到了很大的帮助,但是在这个过程完成之后,他们还可以确保组织能够适应新的挑战并控制技术债务。在微服务架构中工作的系统旨在创建独立的团队,但他们都真正受益于由外部人员创建的共享全球愿景。

为了更好地协调,如何划分团队非常重要。让我们了解当我们将系统开发分成不同的团队时出现的一些挑战。

Dividing the workload and Conway's Law

微服务架构系统对于大型软件系统来说已经足够了,尽管公司倾向于从单体应用程序开始。这对于任何拥有小团队的系统都是有意义的。随着系统的探索和调整,它会随着时间的推移而增长。

但是当单体系统增长到一定规模时,它们变得难以处理和开发。由于历史原因,内部结构相互交织,并且随着复杂性的增加,系统的可靠性可能会受到影响。在灵活性和冗余之间找到平衡可能很困难。

Remember that microservices are useful when the development team is big. For small teams, a monolith is easier to develop and maintain. It's only when many developers work on the same system that dividing the work and accepting the overheads of a microservice architecture makes sense.

扩展开发团队可能会变得很困难,因为那里会有太多的旧代码,并且学习如何浏览它很困难并且需要很多时间。开发人员(已经存在很长时间的开发人员)知道警告可以提供哪些帮助,但它们会成为瓶颈。增加团队的规模并没有帮助,因为做出任何改变都会变得复杂。因此,每个新开发人员都需要大量培训,然后才能跟上进度并成功处理错误修复和新功能。

团队也有自然的规模限制。超出该限制可能意味着必须将它们分成更小的部分。

The size of a team is highly variable, but normally, the 7 ±2 components are considered as a rule of thumb for the ideal number of people who should be in a team.

Bigger groups tend to generate smaller groups on their own, but this means there will be too many to manage and some may not have a clear focus. It's difficult to know what the rest of the team is doing.

Smaller teams tend to create overhead in terms of management and inter-team communication. They'll develop faster with more members.

在一个庞大的单体系统中,多个独立的团队往往会在没有清晰的长远眼光的情况下乱搞。这可以通过设计一个强大的内部结构来缓解,但这需要大量的前期规划和强有力的监管以确保其得到遵守。

微服务架构是一种解决这些问题的设计,因为它在系统的各个部分之间建立了非常严格的界限。但是,这样做需要开发团队具有一定的规模,以便他们可以作为几个主要独立工作的小团队工作。这是微服务架构系统的主要特点。构成它的每一个微服务都是一个独立的服务,可以独立开发和发布。

这种工作方式允许团队并行工作,不受任何干扰。他们的行动领域是明确的,任何依赖都是明确设置的。因此,微服务之间的边界很牢固。

仅仅因为一个微服务是独立发布的,并不意味着一个版本就足以发布一个完整的功能。正如我们已经看到的,有时,微服务中的功能需要在部署之前处理另一个微服务。在这种情况下,需要处理几个微服务。

在计划如何划分团队时要牢记的最重要的想法是团队的结构如何反映在软件中。这由康威定律描述。

Describing Conway's Law

康威定律是一句软件格言(https:// www.nagarro.com/en/blog/post/76/microservices-revisiting-conway-s-law)。换句话说,在任何生产软件的组织中,软件都会复制组织的通信结构。例如,以一种非常简化的方式,一个组织分为两个部门:采购和销售。这将生成两个软件块:一个专注于购买,另一个专注于销售。他们会在需要时进行沟通。

In this section, we will talk about software units. This is a generic term that describes any software that's treated as a single cohesive element. It can be a module, a package, or a microservice.

In the microservice architecture, these software units are mainly microservices, but in some cases, there can be other types. We will see examples of this in the Dividing the software into different kinds of software units section.

这可能不足为奇。团队之间以及同一团队内部的沟通水平不同是很自然的。然而,团队合作的影响是巨大的,其中一些如下:

  • Inter-team APIs are more expensive than intra-team APIs, both in terms of operating them as well as developing them since their communication is more complicated. It makes sense to make them generic and flexible so that they can be reused.
  • If the communication structures replicate the human organization, it makes sense to be explicit. Inter-team APIs should be more visible, public, and documented than intra-team APIs.
  • When designing systems, dividing them across the lines of the layered team structure is the path of least resistance. Engineering them any other way would require organizational changes.
  • On the other hand, changing the structure of an organization is a difficult and painful process. Anyone that has gone through a reorg knows this. The change will be reflected in the software, so plan accordingly.
  • Having two teams working on the same software unit will create problems because each one will try to pull it to their own goals.
The owner of a software unit should be a single team. This shows everyone who's responsible for who has the final say on any change and helps us focus on our vision and reduce technical debt.
  • Different physical locations impose communications restrictions, such as time differences, which will produce barriers when we're developing software across them. It is common to split teams by location, which creates the need to structure the communication (and therefore the APIs) between these teams.

请注意,DevOps 运动与康威定律有关。划分工作的传统方式是将 正在开发的软件与其运行方式分开。正如康威定律所描述的那样,这在两个团队之间造成了差距,从而产生了与两个团队之间缺乏理解相关的问题。

对这个问题的反应是创建可以开发和操作自己的软件以及部署它的团队。这称为 DevOps。它将运营问题转移给了开发团队,目的是创建一个反馈循环来激励、理解和修复它们。

康威定律不是一件坏事,要克服。这反映了任何组织结构都会对软件结构产生影响。

Remembering this may help us design the system so that the communication flow makes sense for the organization and existing software.

DevOps 运动的关键组成部分之一是推进构建系统的技术,以简化生产环境的运行方式,从而简化部署过程。这使我们能够以新的方式构建团队,从而使多个团队能够控制发布。

现在,让我们谈谈如何将软件构造成不同的部门。

Dividing the software into different kinds of software units

虽然本书的主要目标是讨论微服务中的软件划分,但这并不是唯一可能的划分。其他部门可以包括微服务或共享包中的模块。

The main characteristic of a microservice is that it is independent in terms of development and deployment, so full parallelization can be achieved. Other divisions may reduce this and introduce dependencies.

Ensure that you justify these changes.

在本书介绍的示例系统中,我们介绍了一个模块来验证请求是否由用户签名。 Users Backend 生成一个签名的 header,Thoughts Backend 和 Frontend 通过 token_validation.py 模块独立验证它。

该模块应该由拥有用户后端的同一团队所有,因为它是它的自然扩展。我们需要验证它是否生成了用户后端生成的相同令牌。

避免重复并使其始终保持同步的最佳方法是生成一个可以安装在相关微服务上的 Python 包。然后,可以像对待 requirements.txt 文件中的任何其他外部依赖项一样对待这些包。

要在 Python 中打包库,我们可以使用多种工具,包括官方 Python 打包用户指南中的工具(https://packaging.python.org/) 到较新的工具,例如 Poetry (https://poetry .eustace.io),它更容易用于新项目。

如果我们希望它公开可用,可以将包上传到 PyPI。或者,我们可以使用 Gemfury 等工具将其上传到私有存储库,或者在需要时托管我们自己的存储库。这在包及其维护者以及将其用作依赖项的团队之间进行了明确的划分。

划分软件单元对团队划分有影响。现在,让我们看看如何组织团队。

Designing working structures

考虑到康威定律,划分软件应该反映组织的结构。当我们从单体架构迁移到微服务架构时,这一点非常重要。

请记住,从单体架构到微服务的转变对于我们的运营方式来说是一个巨大的变化。这既是技术变革,也是组织变革。主要风险在于人为因素,包括培训人们使用新技术以及让开发人员对他们将从事的新领域感到满意等挑战。

对组织结构进行彻底的改变可能非常困难,但需要进行一些小的调整。在从单体架构迁移到微服务时进行重大更改时,需要重组团队。

请记住,大规模重组可能会激怒人们并引发政治问题。人类不喜欢变化,任何决定都需要有意义。预计必须解释和澄清这一举动。对新结构要实现的目标有明确的目标将有助于赋予它目标。

让我们看一些团队划分的例子,以及它们的优缺点。

Structuring teams around technologies

在某些情况下,与技术相关的不同技能可能是相关的。系统的某些部分可能会处理与其他任何东西完全不同的技术。

一个很好的例子是移动应用程序,因为它们在使用的语言方面受到限制(Android 的 Java 和 iOS 的 Objective-C 或 Swift)。具有网站和移动应用程序的应用程序可能需要特定的团队来处理移动应用程序的代码。

一个更传统的例子是数据库团队,它是围绕数据库管理员(DBA)建立的。他们将控制对数据库的访问并对其进行操作以使它们保持良好状态。但是,这种结构正在消失,因为现在数据库操作更容易并且通常由大多数开发人员处理,并且近年来数据库的基础架构管理已大大简化。

这可以让我们证明围绕某些领域创建特定团队是合理的。该技术的障碍确保系统之间的通信是结构化的。

下图是我们将遇到的团队类型的示例。它们按技术和通信方式分组。数据库团队将与创建 Web 服务后端的团队进行沟通,他们将与 Web 和移动团队进行沟通:

读书笔记《hands-on-docker-for-microservices-with-python》跨团队协作和沟通

该模型的主要缺点是新功能可能需要多个团队共同开发。对面向客户的代码所做的任何更改,以便我们可以在数据库中存储新值,都需要每个团队的工作投入。这些功能需要额外的协调,这可能会限制开发速度。

Structuring teams around domains

另一种结构是围绕不同知识领域的结构,通常与公司的业务领域相关。每个知识领域都有自己的独立系统,但它们相互通信。某些部分可能具有外部可访问的接口,而其他部分可能没有。

这种结构通常出现在成熟的组织中,这些组织具有多年来成功工作的不同领域。

例如,一家在线零售商可以分为三个领域:

  • Sales: Handles the external website and marketing.
  • Inventory: Purchases the merchandise so that it can be sold, and also handles stock.
  • Shipping: Delivers the product to the customers. The tracking information is displayed on the website.

在这种情况下,每个区域都有自己的数据库,以便可以存储相关数据及其服务。它们通过定义的 API 相互通信,并且最频繁的更改发生在域内。这允许在域内快速发布和开发。

跨域具有新功能也是可能的。例如,运输跟踪信息的更改可能需要我们匹配销售产生的更改。但是,这些变化应该不那么频繁地发生。

在此示例中,每个团队将相互通信,如下图所示:

读书笔记《hands-on-docker-for-microservices-with-python》跨团队协作和沟通

这种结构的主要不便之处在于可能会创建孤立的团队和筒仓心态。每个系统都有自己的做事方式,因此它们可能会分歧到不共享相同基本语言的程度。当需要跨域功能时,可能会导致讨论和摩擦。

Structuring teams around customers

在某些组织中,主要目标是为客户创建定制工作。也许客户需要以定制的 B2B 方式与产品集成。在这种情况下,能够开发和运行自定义代码至关重要。

该结构以客户为中心。三个团队(称为红色、金色和蓝色)分配给客户,并为每个客户维护一项特殊服务,包括他们的自定义代码。每个客户团队处理几个客户。另一个团队处理产品的后端,其中包含系统的通用代码和基础设施。该团队与客户分开工作,但在共享客户团队时会添加来自客户团队的功能,以便将它们包含在产品中。还分享了一般改进。

这在组织中创造了两种速度。客户团队专注于客户的短期需求,而产品团队专注于客户的长期需求。

在这里,产品团队将与客户团队进行交流,但客户团队之间不会进行太多交流。如下图所示:

读书笔记《hands-on-docker-for-microservices-with-python》跨团队协作和沟通

这种结构适用于高度定制的服务,因此它们可以包含为单个客户生成的代码,这可能会使他们失去对一般产品的关注。这里的主要问题是客户团队在面对苛刻的客户时可能面临的高压,这可能会给开发人员带来负担。产品团队需要确保他们对产品进行有用的补充,并尽可能减少他们的长期问题。

Structuring teams around a mix

前面的三个示例是综合用例。现实生活更加复杂,可能需要将所有这些混合在一起,或者完全采用新的结构。

如果组织足够大,可能会有几十个不同的团队和软件单元。请记住,如果足够大,一个团队可以处理多个软件单元。但是,两个团队不应该拥有相同的软件单元,以避免所有权和注意力不集中。

分析组织中的通信流程,以了解在迁移到微服务时要解决的痛点,并确保人员结构正在考虑设计微服务和软件单元。

团队的另一个重要元素是在添加新功能所花费的时间和维护现有代码的时间之间找到适当的平衡。

Balancing new features and maintenance

每个软件服务都需要维护以保持良好状态,但不会增加明显的外部价值。但是,维护任务对于良好的运行至关重要,可以分为两类:定期维护和管理技术债务。

技术债是使用时间最多的债,需要进一步讨论,但在此之前,我们先来看看定期维护。

Regular maintenance

这种维护以软件服务性质固有的任务形式出现。通过运行依赖于其他组件(例如底层操作系统或 Python 解释器)的服务,我们需要使它们保持最新并将它们升级到新版本。

在使用容器和 Kubernetes 的情况下,我们需要考虑两个充当操作系统的系统。一是来自容器的操作系统;在这里,我们使用了 Alpine。另一个是处理Kubernetes节点的OS,AWS EKS是自动处理的,但需要升级到Kubernetes版本。

使依赖项保持最新的主要原因如下,按重要性顺序排列:

  • New versions fix security problems.
  • General performance improvements.
  • New features can be added that enable new functionality.

如果我们为这些任务做好计划,就可以减轻这些任务。例如,使用标有 Long-Term Support (LTS) 的操作系统版本可以减少更新系统时出现的问题。

操作系统的 LTS 版本是在较长周期内接收支持和关键更新的版本。例如,一个常规的 Ubuntu 版本每 6 个月发布一次,并在 9 个月内接收更新(包括关键安全更新)。 LTS 版本每 2 年发布一次,并获得 5 年的支持。

运行服务时,建议使用 LTS 版本,以尽量减少所需的维护工作。

所有这些包和依赖项都需要更新以确保操作系统运行良好。另一种方法是打开安全漏洞或留下过时的系统。

更新依赖项可能需要我们调整代码,具体取决于代码的某些部分是否被弃用或被删除。在某些情况下,这可能代价高昂。在撰写本文时,最著名的迁移是 Python 社区从 Python 2 升级到 Python 3,这项任务需要数年时间。

不过,大多数升级通常都是非常常规的,只需要很少的工作。尝试制定一个以合理的方式跟上步伐并产生可靠指导的升级计划;例如,新的操作系统 LTS 版本何时发布所有系统应在接下来的 3 个月内迁移等规则。这产生了可预测性,并为每个人提供了一个可以跟进和执行的明确目标。

Continuous integration tools can help in this process. For example, GitHub automatically detects dependencies in files such as requirements.txt and notifies us when a vulnerability is detected. It's even possible to automatically generate pull requests when updating modules. Check out the documentation for more information: https://help.github.com/en/github/managing-security-vulnerabilities/configuring-automated-security-fixes.

升级依赖可能是最常见的定期维护任务,但还有其他可能性:

  • To clean up or archive old data. These operations can normally be automated, saving a lot of time and reducing problems.
  • To fix operations that are dependent on business processes, such as generating monthly reports, and so on. These should be automated when possible, or tools should be designed so that users can produce them automatically instead of relying on technical staff doing bespoke operations.
  • To fix permanent problems that are produced by bugs or other errors. Bugs sometimes leave the system in a bad state; for example, there may be a corrupted entry in the database. While the bug is being fixed, we may need to resolve the situation by unblocking a process or a user.

这些过程可能很烦人,特别是如果它们是重复的,但通常很好理解。

另一种处理技术债务的维护形式更复杂,因为它引入得更缓慢,更难以清楚地检测到。正确解决技术债务是最具挑战性的维护任务,但在我们做任何事情之前,我们需要了解它。

Understanding technical debt

技术债务是软件开发中使用的一个概念,用于描述将来实施非最佳解决方案时将增加的额外成本。换句话说,选择快速或简单的选择意味着以后的功能需要更长的时间并且更难开发。

作为一个比喻,技术债务自 90 年代初就已经存在,但在此之前已经描述了这个概念。

就像任何隐喻一样,它很有用,但也有局限性。特别是,非技术人员倾向于将其与金融债务联系起来,尽管它们具有不同的含义。例如,大多数技术债务是在我们甚至没有注意到的情况下产生的。确保你不要把比喻看得太远。

技术债务在一定程度上是不可避免的。在实施一项功能之前,没有无限的时间来研究所有可能性,在做出任何决定时也没有完美的信息。它也是任何复杂系统中熵增长的结果。

除了无法避免之外,也可以是经过深思熟虑的选择。 开发受到时间的限制,因此一个不完美的快速市场解决方案可能比错过最后期限更可取。

技术债务的另一个迹象是专注于某些知识。无论如何,技术债务会随着时间的推移而不断增加,这会为新功能带来摩擦。复杂性的增加也会产生可靠性问题,因为错误将越来越难以理解和修复。

简单是可靠系统最好的朋友。简单的代码易于理解和纠正,并使错误变得明显或快速检测到。微服务架构旨在通过创建更小的独立服务来降低单体应用的固有复杂性,这些服务具有明确的职责分配,并在它们之间创建显式接口。

技术债务可能会增长到需要大型架构的地步。我们已经看到从单体架构转变为微服务架构可能是这些时刻之一。

An architectural migration such as this is a big effort and will require time to deliver. New microservices that are reproducing the features that already exist in the monolith may conflict with new features being introduced.

This creates a moving target effect that can be very disruptive. Ensure that you identify these conflicting points and try to minimize them in your migration plan. Some new features may be able to be delayed until the new microservice is ready, for example.

然而,与其等到技术债务如此之大以至于只有彻底的改变才能解决它,我们需要能够更早地解决技术债务。

Continuously addressing technical debt

减少技术债务需要是一个持续的过程,并且需要引入到事物的日常运营中。专注于持续改进的敏捷技术试图引入这种心态。

检测技术债务通常来自开发团队内部,因为他们更接近代码。 团队应该考虑哪些方面的操作可以更顺畅,并预留时间来执行这些改进。

A great source of information that allows us to detect technical debt is metrics, such as the ones we set up in Chapter 10, Monitoring Logs and Metrics.

忽视修复这些问题的风险是当已经存在的功能慢慢变慢和不可靠时陷入软件腐烂。随着时间的推移,它们对客户和外部合作伙伴会越来越明显。在此之前,在这种环境中工作会使开发人员的生活变得困难,并且存在倦怠的风险。新开发的延迟也很常见,因为代码本身就很难使用。

为了避免陷入这种情况,需要分配时间以持续减少技术债务,并加入新功能和其他工作。应该在维护和技术债务减少以及新功能之间找到平衡。

我们在本书中谈到的很多技术都可以帮助我们以持续的方式改进系统,这些技术来自我们在中描述的持续集成技术。 第四章, 创建管道和工作流,我们在中描述的代码审查和批准 第 8 章使用 GitOps 原则

分布可能高度依赖于系统的当前形态,但它确实有助于明确和强制执行。诸如用于减少技术债务的特定时间百分比可能会有所帮助。

减少技术债务成本高昂且困难重重,因此尽可能少地引入技术债务是有道理的。

Avoiding technical debt

处理技术债务的最好方法是一开始就不要引入它。然而,这说起来容易做起来难。有多种因素会影响导致技术债务的决策质量。

最常见的原因如下:

  • Lack of a strategic, high-level plan to give direction: This produces inconsistent results because each time the same problem is found, it will be resolved in a different way. We talked about how coordination across teams needs to address standards across the organization and ensure they are followed. Having someone acting as a software architect, looking for creating consistent guidelines across the board, should greatly improve this case.
  • Not having the proper knowledge to choose the right option: This is quite common. Sometimes, the people that need to make a decision don't have all the relevant pieces of information due to miscommunication or simply lack of experience. This problem is typical of structures that lack experience in the problems at hand. Ensuring that you have a highly trained team and are creating a culture where more experienced members help and mentor junior members will reduce these cases. Documentation that keeps track of previous decisions and simplifies how to use other microservices will help us coordinate teams so that they have all the relevant parts of the puzzle. This helps them avoid making mistakes due to incorrect assumptions. Another important element is to ensure that teams have proper training in the tools they're using so that they are fully aware of their capacities. This should be the case for external tools, such as being skilled in Python or SQL, and in any internal tool that requires training materials, documentation, and appointed points of contact.
  • Not spending enough time investigating different options or planning: This problem is created by pressure and by the need to make quick progress. This can be ingrained in the organization culture, and slowing down decision-making could be a challenging task when the organization grows since smaller organizations tend to require a faster process. Documenting the decision process and requiring it to be peer-reviewed or approved can help slow this down and ensure that work is thorough. It's important to find a balance in terms of what decisions require more scrutiny and which ones don't. For example, everything that fits neatly inside a microservice can be reviewed inside the team, but features that require multiple microservices and teams should be reviewed and approved externally. In this scenario, finding the proper balance between gathering information and making a decision is important. Document the decisions and the inputs so that you understand the process that got them there and refine your process.

避免这些问题的最好方法是反思以前的错误并从错误中吸取教训。

Designing a broader release process

虽然独立部署每个微服务的能力确实是系统的关键要素,但这并不意味着不需要协调。

首先,还有一些特性需要部署在多个微服务中。我们已经研究了如何在开发过程中工作,包括处理版本控制和显式检查依赖项等细节。所以现在怎么办?

在这些情况下,需要团队之间的协调以确保实现依赖关系并且以适当的顺序执行不同的部署。

虽然首席架构师可以帮助进行一些协调,但架构角色应该专注于长期目标,而不是短期发布。允许团队进行自我协调的一个好工具是在会议中通知其他团队有关发布的信息。

Planning in the weekly release meeting

当发布过程是新的并且仍在从单体迁移时,最好提供对每个团队正在做的事情的洞察力。每个团队的代表都参加的每周发布会议可能是传播有关其他团队正在发生的事情的知识的绝佳方式。

发布会议的目标应如下:

  • Planned releases for the next 7 days and rough times for when; for example, we plan to release a new version of the Users Backend on Wednesday.
  • You should provide a heads-up for any important new feature, especially if other teams can use it. For example, if the new version improves authentication, make sure that you redirect your teams to the new API so that they can get these improvements as well.
  • State any blockers. For example, we can't release this version until the Thoughts Backend releases their version with feature A.
  • Raise any flags if there's critical maintenance or any changes that could affect the releases. For example, on Thursday morning, we need to do database maintenance, so please don't release anything until 12 o'clock. We will send an email when the work is done.
  • Review the release problems that happened the week prior. We'll talk about this in more detail later.

这类似于在许多敏捷实践(例如 SCRUM)中出现的通常的站立会议,但侧重于发布。为了能够做到这一点,我们需要提前指定发布的时间。

鉴于 微服务 发布的异步性质,以及随着持续集成实践的实施和加速这一过程,将会有很多例行发布不会提前这么长时间计划。这很好,意味着发布过程正在改进。

当涉及到风险更高的发布时,请尝试提前计划一点,并利用发布会议与其他团队进行有效沟通。会议是保持对话畅通的工具。

随着时间的推移,随着持续集成实践越来越成熟,发布越来越快,每周的发布会议会慢慢变得越来越不重要,以至于可能不再需要这样做了- 至少不那么有规律。这是反思持续改进实践的一部分,这也是通过识别发布问题来实现的。

Reflecting on release problems

并非每个版本都会完美无缺。有些会因为工具或基础设施的问题而失败,或者可能是因为过程中容易犯的错误。事实是某些版本会有问题。不幸的是,无法避免这些情况。

为了随着时间的推移减少和最小化发布问题,每次发现问题时,都需要记录并在每周发布会议或同等论坛中提出。

有些问题很小,只需要一点额外的工作就可以成功发布;例如,错误配置导致新版本在修复之前无法启动,或者一个服务在其依赖之前部署的协调问题。

其他的问题会更大,甚至可能因为一个问题而导致停机。在这里,回滚将很有用,以便我们可以快速回到已知状态并重新计划。

在任何情况下,它们都应该被适当地记录下来,即使这只是简短的,然后共享,以便可以改进过程。分析出了什么问题是不断改进版本的关键,以便它们更快、更简单。

对这些问题持开放态度。如果您希望发现每一个问题并快速评估解决方案,那么创建一种公开辩论和承认问题的文化非常重要。

Capturing problems is not, and should never be, about assigning blame. It's the organization's responsibility to detect and correct problems.

If this happens, not only will the environment become less attractive to work in, but problems will be hidden by teams so that they don't get blamed.

Unaddressed problems tend to be multiplicative, so reliability will suffer greatly.

能够顺利发布对于快速部署和提高速度至关重要。当我们处理这类问题时,只需要简单的文档,因为它们通常是轻微的,在最坏的情况下,会延迟一两天的发布。

对于更大的问题,当外部服务中断时,最好有一个更正式的流程来确保问题得到妥善修复。

我们可以改进流程的另一种方法是正确理解在实时系统中中断服务的问题的原因。对此最有效的工具是事后会议。

Running post-mortem meetings

不限于发布,有时会有大事件中断服务,需要进行重大工作才能修复。在这些紧急情况下,首要目标是尽快恢​​复服务。

在服务再次稳定后,为了吸取这次经验并避免再次发生,参与事件的每个人都应该参加一个事后会议。事后分析会议的目的是根据紧急情况期间的经验教训制定一系列后续任务。

要记录这一点,您需要创建一个模板。这将在验尸会议期间填写。该模板应捕获以下信息:

  • What problem was detected? Include how it was detected if this isn't evident; for example, the website was down and was returning 500 errors. This shows that there was an increase in errors.
  • When did it start and finish? A timeline of the incident; for example, Thursday from 3PM to 5PM.
  • Who was involved in remediating the incident? Either detecting the problem or fixing it. This helps us collect information about what happened.
  • Why did it fail? Go to the root cause and the chain of events leading to that; for example, the website was down because the application couldn't connect to the database. The database was unresponsive because the hard drive was full. The hard drive was full because the local logs filled up the disk.
  • How was it fixed? Steps were taken to solve the incident; for example, logs older than a week were deleted.
  • What actions should follow up from this incident? Actions that should remediate or fix the different issues. Ideally, they should include who will perform the action; for example, no local logs should be stored and they should be sent to the centralized log. The amount of hard disk space should be monitored and alert if less than 80% of the space is available.

其中一些元素可以在紧急情况发生后立即填写,例如涉及的人员。不过,最好在事后一到三天安排事后会议,让每个人都消化和处理这些数据。根本原因可能与我们最初的想法不同,花一些时间思考发生的事情有助于我们提出更好的解决方案。

As we discussed in the Reflecting on release problems section, be sure to encourage open and candid discussion when you're dealing with service interruption incidents.

Post-mortem meetings are not there to blame anyone, but to improve the service and reduce risks when you're working as a team.

后续行动应在会议上决定,并据此确定优先顺序。

尽管检测根本原因非常重要,但请注意应针对其他原因采取措施。即使根本原因是一个,也有其他预防措施可以最大限度地减少它再次发生时的影响。

事后会议的行动通常是高度优先的,应该尽快完成。

Summary

在本章中,我们研究了跨团队协调的不同方面,以便我们能够成功地管理运行微服务架构的组织。

我们首先讨论了如何保持全球视野和各部分之间的协调是好的。我们谈到了有一个明确任命的首席架构师来监督系统并拥有允许他们确保团队不会相互冲突的高级视图。

我们描述了康威定律以及通信结构如何最终塑造软件的结构,因此对软件所做的任何更改都应该以某种方式反映在组织中,反之亦然。然后,我们学习了如何划分职责范围,并根据不同的组织提供了一些可能划分的示例。

接下来,我们介绍了技术债务如何减慢正在进行的开发过程,以及引入一种持续解决它的心态以避免降低内部团队和使用它们的客户的体验的重要性。

最后,我们解决了发布可能导致的一些问题,包括团队之间的充分协调,特别是在使用 GitOps 的早期阶段,以及在发布失败或服务关闭时进行回顾性分析。

Questions

  1. Why is a leading architect convenient for a microservice-architecture system?
  2. What is Conway's Law?
  3. Why does technical debt get introduced?
  4. Why is it important to create a culture where we can work continuously to reduce technical debt?
  5. Why is it important to document problems in releases and share them with every team?
  6. What is the main objective of a post-mortem meeting?

Further reading