【问题标题】:One microservice doing many transformations or many microservices doing one transformation?一个微服务做多个转换还是多个微服务做一个转换?
【发布时间】:2019-01-15 18:12:33
【问题描述】:

我有一个转换 XML 文档的服务。 它从 N 个队列接收消息,并根据从哪个队列获取消息,运行其中一种转换。

现在我将它重构为在 docker 容器中运行的微服务。 我认为我可以通过两种方式做到这一点,但我不知道在使用容器时哪种方式会更好。

我在 .NET Core 2.2 中执行此操作。我还不知道我们是否会在生产环境中使用 docker-swarm 或 kubernetes。

  1. 我可以将大部分代码保留为现在的样子,并将其作为一个容器运行。 AppSettings.config 将包含每个队列转换对的设置。

    我看到的优点: 需要更少的代码更改和更简单的 docker-compose - 一项服务而不是 N。只有一个配置文件。

    缺点: 如果对其中一种转换有更高的需求,或者它有 更高的优先级我不能只是扩展它的容器。新副本 将从所有队列中提取消息,而不仅仅是我想要扩展的队列。

  2. 我可以重构代码并构建 N 个不同的容器映像。 他们每个人都会听一个队列并运行一个转换。我可以重构它,以便 代码的唯一区别在于注册服务时的启动。根据配置我可以 注册 IXmlTransformers 之一。

    优点: 我可以扩展一个队列转换。 如果其中一个转换出现问题并且容器重新启动,则所有其他转换都将正常工作。 我认为它更清洁 - 一个图像进行一个转换 - 单一责任规则。

    缺点: 因此在某些环境中会有大约 10 种不同的转换 会有很多配置文件 - 可能使用卷添加到每个正在运行的容器中? Docker compose 会很长。

    有什么更好的方法来做到这一点?或者也许还有其他更好的选择?

编辑:

我认为我的问题并不清楚,所以我尝试更好地解释它。 在这两个选项中,我都会有一个容器图像。区别在于运行时。只有配置会有所不同。 假设我正在使用 XSLT 将 XML 转换为 CSV 或 XML 转换为 XML。 CSV 格式和 XSLT 是配置的一部分。我可以有许多 CSV 格式(许多配置)和许多不同的 XSLT(同样是许多配置) 所以我有两个 ITransformer 实现(CSV、XSLT),它们读取配置来运行它们的转换。 我的问题是,最好为一个配置运行一个容器实例,还是将所有这些配置放入一个容器中,该容器监控 N 个队列或监控一个队列并读取某种元数据来决定运行哪种转换。

【问题讨论】:

  • 先做,但是暴露队列配置,这样你就可以启动一个只监听这个队列的容器(或者在所有其他队列之前处理来自这个队列的消息)
  • 这里有很大的“视情况而定”。正如您所指出的,可扩展性和单一职责原则会建议选项 2,但请尝试考虑有多少人将维护这些服务,他们有多少共同点以及他们可能多久改变一次经历所有这些,显然运行 N 服务的成本与 1 相比。如果它是一个小项目或不太可能改变,我会选择选项 1,只要它不会变得非常复杂。
  • 我认为我使用了错误的词汇。我在选项 2 中说过,我将构建 N 个不同的容器映像。但我的意思是,在运行时我会运行其中 N 个,但它们会共享图像。只有配置会有所不同。在选项 1 中,将有一个图像和一个正在运行的容器。

标签: docker kubernetes .net-core microservices docker-swarm


【解决方案1】:

缺点:如果对其中一种转换有更高的需求,或者如果 它具有更高的优先级我不能只是扩展它的容器。新副本 将从所有队列中提取消息,而不仅仅是我的一个 想要扩展。

为什么所有队列都被拉出是个问题?是因为您通常在队列中有大量积压,还是因为您害怕提供过多的容量?当所有队列都是最新的并处理时,无论如何都应该选择您想要扩展的一个队列。

如果您无法做到这一点,我仍然会使用可以从所有队列中提取的通用服务,但请尝试根据队列长度、队列条目的时间戳或您的case 来规范以什么优先级拉取什么队列。如果此逻辑的正确结果参数被公开,它也可用于自动扩展您的集群(如果太落后)。

基于队列的手动扩展替代方案听起来可能会变成管理员的噩梦。

【讨论】:

  • 我想到了进入其中一个队列的消息率大于其他队列的情况。假设两个不同队列之间的比例是 1:3。如果我有一项服务可以同时收听它们或每个服务都收听,那么即使我处理它们,队列中具有较高消息比率的消息数量也可能会增加。但是现在当我想到它时,我不确定它是否有意义。如果其中一个队列中有更多消息,它们将被更频繁地处理,对吗?
【解决方案2】:

当您知道应该以队列或事件的名称运行哪个作业的上下文时,在多个容器中使用相同的代码并且具有相同的配置应该不是问题。我不知道您的设置,但我会避免将一个容器绑定到一个队列。当您可以避免时,不应使用状态部署容器。

根据您拥有的文件数量和资金,您还可以使用 amazon lambda 和 S3 的方法。当您使用 S3 和不同的存储桶名称时,不需要任何消息队列或自己的基础设施,这些名称在上传时会触发 lambda 函数。这不是一种更好的方法,它只是一种不同的方法,几乎​​不取决于您的需求。它可能比您的方法更便宜或贵得多,这也取决于您的用例。

【讨论】:

猜你喜欢
  • 2022-01-20
  • 1970-01-01
  • 2020-06-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多