微服务——同一个服务应该有多个实例吗?

Microservices - should there be multiple instances of the same service?

我一直在做一些关于微服务的研究,我有一个没有很好解决的问题是微服务是否应该有多个实例,如果是的话,如何处理?

假设我有一个名为 filewatcher 的微服务,它从 FEED 文件夹中的某个共享驱动器中获取文件并在 table 中创建一条记录并将有效负载消息发送到 kafka。

这里,如果 filewatcher 服务的多个实例 运行 在不同的服务器(逻辑或物理服务器)上并从同一位置获取文件,它将创建重复的记录。

这里我已经实现了数据库端的验证。但我正在寻找一些架构解决方案。为什么 filewatcher 服务从 FEED 文件夹读取重复文件。

我认为来自 spring 引导的@Transactional 将解决交易问题。它没有解决重复文件上传问题。

如何处理这种情况?

一般问题:

Microservices - should there be multiple instances of the same service?

这取决于您考虑使用它们的原因以及替代方案。例如,您可能有多个实例用于冗余,或者因为单台机器上的单个实例没有容量。或者您可以 运行 多个实例,因为服务 and/or 服务堆栈是单线程的。

但是 运行 如果服务在设计时没有考虑到这一点,那么微服务的多个实例可能会破坏事情。显然,在那种情况下你不应该这样做。

注意:如果微服务(真正)是无状态的,那么从“功能”的角度来看,复制它不太可能破坏事物。但这几乎不是一个有用的观察,因为它仍然可以可以“在操作上”破坏事物;例如由于消耗资源...

简而言之,您需要了解上下文来决定您应该还是不应该复制服务。


一个例子:

Here if multiple instance of filewatcher service running on different server (logical or physical server) and fetching file from same location than it will create the duplicate records.

这可能是您 运行 多个实例的情况,因为它会破坏事物。 (如果多个文件观察者监视同一个位置,您会取得什么成就?)

或者,您可以实施文件观察器实例,以便在将记录放入数据库时​​删除重复记录(假设您使用的是数据库)。或者你可以稍后处理重复的记录。

任何一种方法 都可能 是正确的。这取决于上下文。


底线:我想不出任何一般架构原则、技术或建议,除了您需要了解上下文并根据需要决定做什么的明显建议

注:There are no Best Practices

高级别

我喜欢你的问题,希望我的 2 美分对你有所帮助。 您绝对可以同时拥有微服务 运行ning 的多个 实例 ,但它们在逻辑上不应分开。它们必须作为一个逻辑实例运行。因此,您尝试扩展的单个微服务应该构建 stateless,其中所有微服务有状态数据都跨共享数据库结构持久化。如果您打算 运行 多个实例,则不应在单个微服务实例上保留任何内部状态。

出于多种原因,您可能希望跨多个实例分布一个微服务。

  1. 可靠性浮现在脑海中。为了获得 99.99999% 的黄金可用性,您需要微服务的多个实例 运行ning 以防一个实例崩溃。

  2. 可扩展性在这里也很重要。使用多个微服务实例 运行ning,您可以垂直扩展您的请求容量

  3. 在大数据系统中,可能需要将微服务共同定位在物理距离遥远的不同区域以减少延迟。

数据库同步

因此,问题主要是:我们如何确保微服务实例在对共享数据进行操作时不会相互越过?答案是你必须同步数据库交互和与外部系统的交互。

可以使用 Spring Boot 的 JDBC 库来同步微服务中的数据库交互。在存储库查找上带有 PESSIMISTIC_WRITE 锁定的 @Transactional 注释可用于确保只有一个微服务实例可以创建数据库 table 条目。要阅读有关交易和传播方法的更多信息,请查看 https://www.baeldung.com/spring-transactional-propagation-isolation. To understand more about Locking databases, read up on JDBC locking here : https://www.baeldung.com/jpa-pessimistic-locking。总的来说,您需要考虑微服务实例之间同步的数据库层策略。

如果您需要 运行 外部实体上的同步作业,我推荐 Quartz-Scheduler,它可以使用数据库事务来同步作业。请务必使用 @DisallowConcurrentExecution 注释。参见 http://www.quartz-scheduler.org/

领导人选举

可以创建领导者选举算法来同步微服务实例。在 Leader Election 中,一个微服务被共享算法“选出”来指挥所有其他微服务实例。因此,领导实例可以指示从属实例执行临界区任务。但是,如果您选择这种模式,则需要注意不要让领导者实例成为系统的瓶颈。 https://docs.microsoft.com/en-us/azure/architecture/patterns/leader-election