微服务——同一个服务应该有多个实例吗?
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.
这可能是您 不 运行 多个实例的情况,因为它会破坏事物。 (如果多个文件观察者监视同一个位置,您会取得什么成就?)
或者,您可以实施文件观察器实例,以便在将记录放入数据库时删除重复记录(假设您使用的是数据库)。或者你可以稍后处理重复的记录。
任何一种方法 都可能 是正确的。这取决于上下文。
底线:我想不出任何一般架构原则、技术或建议,除了您需要了解上下文并根据需要决定做什么的明显建议
高级别
我喜欢你的问题,希望我的 2 美分对你有所帮助。
您绝对可以同时拥有微服务 运行ning 的多个 实例 ,但它们在逻辑上不应分开。它们必须作为一个逻辑实例运行。因此,您尝试扩展的单个微服务应该构建 stateless,其中所有微服务有状态数据都跨共享数据库结构持久化。如果您打算 运行 多个实例,则不应在单个微服务实例上保留任何内部状态。
出于多种原因,您可能希望跨多个实例分布一个微服务。
可靠性浮现在脑海中。为了获得 99.99999% 的黄金可用性,您需要微服务的多个实例 运行ning 以防一个实例崩溃。
可扩展性在这里也很重要。使用多个微服务实例 运行ning,您可以垂直扩展您的请求容量
在大数据系统中,可能需要将微服务共同定位在物理距离遥远的不同区域以减少延迟。
数据库同步
因此,问题主要是:我们如何确保微服务实例在对共享数据进行操作时不会相互越过?答案是你必须同步数据库交互和与外部系统的交互。
可以使用 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
我一直在做一些关于微服务的研究,我有一个没有很好解决的问题是微服务是否应该有多个实例,如果是的话,如何处理?
假设我有一个名为 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.
这可能是您 不 运行 多个实例的情况,因为它会破坏事物。 (如果多个文件观察者监视同一个位置,您会取得什么成就?)
或者,您可以实施文件观察器实例,以便在将记录放入数据库时删除重复记录(假设您使用的是数据库)。或者你可以稍后处理重复的记录。
任何一种方法 都可能 是正确的。这取决于上下文。
底线:我想不出任何一般架构原则、技术或建议,除了您需要了解上下文并根据需要决定做什么的明显建议
高级别
我喜欢你的问题,希望我的 2 美分对你有所帮助。 您绝对可以同时拥有微服务 运行ning 的多个 实例 ,但它们在逻辑上不应分开。它们必须作为一个逻辑实例运行。因此,您尝试扩展的单个微服务应该构建 stateless,其中所有微服务有状态数据都跨共享数据库结构持久化。如果您打算 运行 多个实例,则不应在单个微服务实例上保留任何内部状态。
出于多种原因,您可能希望跨多个实例分布一个微服务。
可靠性浮现在脑海中。为了获得 99.99999% 的黄金可用性,您需要微服务的多个实例 运行ning 以防一个实例崩溃。
可扩展性在这里也很重要。使用多个微服务实例 运行ning,您可以垂直扩展您的请求容量
在大数据系统中,可能需要将微服务共同定位在物理距离遥远的不同区域以减少延迟。
数据库同步
因此,问题主要是:我们如何确保微服务实例在对共享数据进行操作时不会相互越过?答案是你必须同步数据库交互和与外部系统的交互。
可以使用 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