如何在从单体架构过渡到微服务架构之间管理多个暂存环境

Posted

技术标签:

【中文标题】如何在从单体架构过渡到微服务架构之间管理多个暂存环境【英文标题】:How to manage multiple staging environment in between transition from monolithic to microservice architecture 【发布时间】:2019-07-17 04:08:50 【问题描述】:

我的公司最近开始将平台架构从单体架构转变为微服务架构。整个迁移可能需要数年时间,因此到目前为止,我们仍然需要维护当前的单体应用程序,同时缓慢地拆除应用程序。

我们通过面向服务的架构临时为某些模块拆除单体应用程序(其中数据库仍然连接到单体应用程序的数据库),而有些我们直接过渡到微服务(微服务如果适用,拥有自己的数据库)。

我们会在功能准备就绪时练习发布功能,而不是遵循发布窗口。每个团队都有自己的 staging 来管理这一点,因此我们有多个 staging 环境(总共 11 个),每个环境都有自己的一组遗留单体应用程序。

在过渡到微服务架构时(虽然我知道当我们完全过渡到微服务架构时,整个公司只会有 1 个阶段),我们需要维护所有那些意味着我们需要在每个暂存环境中拥有微服务的副本。

(并不是要引导答案朝着这个解决方案的方向发展。如果有任何不同方向的答案最好,这样我们就可以有更多的选择和变化来考虑利弊) 我们的想法之一是,对于每个 db,我们有一个额外的列来标记这行数据的暂存位置。因此,我们可以为多个阶段维护 1 个微服务实例。问题是对于每个 API 调用,客户端都需要指定它用于哪个阶段。它使每个服务的开发变得复杂(需要满足要过滤掉哪个暂存数据库),使端点更难调用(因为您需要指定您需要访问哪个暂存数据库),更重要的是这些是冗余代码,不应该在生产环境中存在。

我们面临的问题是随着微服务数量的增长,这将占用大量服务器资源(我们决定使用本地服务器来托管我们的 kubernetes 和 Proxmox VM 以用于传统的单体应用)。是否有任何基础架构架构可以减少为此所需的资源

【问题讨论】:

【参考方案1】:

我并不完全了解您可能面临的所有可能细节,但以下几点是:

当按照 Strangler 模式迁移到新的微服务架构时,您必须确定数据的真实来源是谁/在哪里(不必对所有数据都相同)。 对于不改变数据状态的微服务 (MS)(例如新的搜索微服务),我通常将数据从真实来源(例如单体的 RDS 表)流式传输到其他更灵活/微服务友好的介质(在我们的案例中,我们选择了 Apache Kafka,而该媒介是 Kafka 主题)。 MS 从主题中读取事件并创建其内部世界视图(即搜索示例将事件流式传输到 Elastic Search)。 对于同时改变真相来源状态的 MS,它更复杂。在我看来,一种好的方法是在新的微服务环境中保持“真实来源”的状态(例如,在表示订单的主题中累积事件)并异步流回单体数据库。 不同的团队(专注于不同的新微服务)将拥有自己的主题。

【讨论】:

【参考方案2】:

您可以通过为每个微服务保留相对较少的内存和 cpu 来使您的微服务的服务质量可突增。然后,您可以过度使用您的节点,并假设并非所有暂存区域都需要同时以最佳性能运行。

如果许多或所有微服务共享相同的数据库版本,也许您可​​以在单个高可用性数据库部署上将它们托管在单独的数据库模式中,从而减少资源占用。

当然,这取决于暂存环境的计划使用情况。如果所有团队同时完成 sprint 演示,则集群可能会在此之前的高峰时段过载。

【讨论】:

【参考方案3】:

如果我正确理解您的担忧,那么您计划在基于微服务的部署图中为每个六边形、矩形和 DB 节点使用专用服务器。

好消息是,您可以在同一个物理设备中使用这些服务中的每一项,而无需太多操作开销,同时充分利用您的硬件资源。 Docker 容器就是对此的回答。您可以创建可以共享相同硬件资源的轻量级微容器。当然,您需要考虑多个方面,以确保您不会过度使用资源。 Here 很好地解释了影响可在 docker 主机上运行的最大容器数量的因素。您将受益于许多其他优势,例如易于部署新版本、回滚到旧版本、超快速的开发环境设置等。

通过使用容器编排系统(如 Kubernetes 或 DC/OS),Docker 部署甚至在生产中也越来越普遍。

【讨论】:

我们已经将 Docker 和 Kubernetes 用于新服务。我认为我们更关心的是当我们扩展我们创建的新服务的数量时,我们必须为每个服务创建 11 个(每个登台环境一个)。更新了问题以更好地反映现有的基础架构 我明白了。在基于微服务的架构中,如何部署每个服务容器?每个都在不同的硬件中吗?如果是这样,则不必为每个服务都拥有单独的硬件资源,只需在 1 个盒子中为 1 个暂存环境运行多个所有容器即可。我还缺少什么吗? 我们有多个硬件,但我们没有部署在任何特定的硬件中。 Kubernetes 负责这一点。我认为我们的问题是分期太多,最终会占用太多资源。 我们的一个想法是,对于每个 db,我们有一个额外的列来标记这行数据的暂存位置。因此,我们可以为多个阶段维护 1 个微服务实例。问题是对于每个 API 调用,我们都需要指定它用于哪个阶段。它使每个服务的开发变得复杂(需要满足要过滤掉哪个暂存数据库),使端点更难调用(因为您需要指定您需要访问哪个暂存数据库),更重要的是这些是冗余代码不应该在生产中出现 我不认为附加列是一个选项,因为我认为暂存环境的想法也可能是在不同的环境中部署不同版本的代码。我假设您无论如何都需要那些登台环境和每个服务的单独版本。您正在寻找某种方法来解决这个问题并减少它们?【参考方案4】:

就您而言,本地 Kubernetes 可以成为您和您的团队的解决方案。 您可以为您的基础架构创建 2 个或更多集群。我的建议是至少 2 个集群。第一个用于开发、测试和登台,第二个用于生产环境。

现在您可能会混淆 2 个集群如何管理您的 11 个不同的暂存环境。在 Kubernetes 环境中,您可以使用不同的名称创建命名空间,并且可以隔离这些命名空间。因此,在 1 个 Kubernetes 集群中,您可以拥有更多的暂存、测试或开发环境。

但是坑洞很少,你需要担心。你可以搜索一下,我可以给他们一些建议。首先,始终有备份计划来重新创建您的集群。在一些非常不幸的情况下,一些硬件问题或网络情况,Kubernetes 无法连接到工作节点,在这种情况下,您应该准备好在几分钟内从零开始创建集群。

关于你的单体应用,你的方法是最好的方法,慢慢拆解。关于数据库方面,如果可能的话,保留单体数据库并为微服务创建新的数据库会更好,因为您可以查看您的需求,并可能添加一些额外的字段用于分析或微服务数据库的指标。

在您拆除单体应用程序之前,您甚至可以尝试使用 Istio 或 Linkerd 在您的单体应用程序和微服务之间导航流量。

【讨论】:

我们已经将 Docker 和 Kubernetes 用于新服务。我认为我们更关心的是当我们扩展我们创建的新服务的数量时,我们必须为每个服务创建 11 个(每个登台环境一个)。更新了问题以更好地反映现有的基础架构

以上是关于如何在从单体架构过渡到微服务架构之间管理多个暂存环境的主要内容,如果未能解决你的问题,请参考以下文章

微服务实践:从单体式架构迁移到微服务架构

微服务实践:从单体式架构迁移到微服务架构

从单体架构到微服务的服务化演进之路

想从单体架构演进到分布式架构,SBA 会是一个不错的选择

漫谈何时从单体架构迁移到微服务?

微服务架构学习与思考(12):从单体架构到微服务架构的演进历程