Service 如何在微服务体系结构中建模服务依赖关系?

Service 如何在微服务体系结构中建模服务依赖关系?,service,architecture,message-queue,soa,Service,Architecture,Message Queue,Soa,我们正试图以尽可能解耦的方式构建我们的系统。理想情况下,我们希望微服务只做一件事,并且做好一件事。他们不应该知道依赖关系。他们应该从队列中获取作业,完成作业,并以某种方式发出一个作业完成事件(我将回到这里) 我们的系统包含“快照”(图像)作为基本的原子单元。“事件”是一组快照,最大长度为5分钟 一旦我们将快照接收到系统中,并确定它们属于哪个事件,我们就将这些快照排队到RabbitMQ实例,以便执行一些图像分析。然后我们有“快照分析器”“微服务从这个队列中取出并执行图像分析。这些微服务直接写入数据

我们正试图以尽可能解耦的方式构建我们的系统。理想情况下,我们希望微服务只做一件事,并且做好一件事。他们不应该知道依赖关系。他们应该从队列中获取作业,完成作业,并以某种方式发出一个作业完成事件(我将回到这里)

我们的系统包含“快照”(图像)作为基本的原子单元。“事件”是一组快照,最大长度为5分钟

一旦我们将快照接收到系统中,并确定它们属于哪个事件,我们就将这些快照排队到RabbitMQ实例,以便执行一些图像分析。然后我们有“快照分析器”“微服务从这个队列中取出并执行图像分析。这些微服务直接写入数据库,向图像对象添加更多元数据。它们也是无状态的,并且易于水平扩展

问题是,快照分析器完成其工作后需要执行一些任务。如果我们检测到快照上的某些属性,我们希望使用事件分析器“对该事件执行操作。我们不希望对该事件执行多次操作(因此,如果多个快照具有这些属性,这无关紧要-我们仍然只希望对该事件执行一次操作)。事实证明,这对工程师来说是相当具有挑战性的,尤其是在分布式环境中,我们有几个这样的图像分析仪在排队。我们目前所做的是,如果我们在快照上检测到这些属性(意味着我们希望在包含此快照的事件上完成工作),我们会将其写入事件。如果是第一次写入事件,我们将其排入第二个队列进行事件处理。这确保事件最多只排队一次

上述方法的问题如下:

  • 快照分析器和事件分析器之间的依赖关系存在于快照分析器内部。理想情况下,我希望快照分析器不了解事件分析器。它应该只做它的工作,而不关心排队的事情。我不确定这个依赖项应该编码在哪里
  • 当同时处理某个事件的多个快照时,确定将该事件排队。如何仅将事件的工作排队,仅一次。我们“滥用”MongoDB的原子更新,在调用$set时返回是否成功

是否有人对如何声明类似的依赖项有任何想法或示例?我是否需要一个调度器服务,负责排队到正确的位置,并从“已完成的工作”队列或其他地方提取

最终,您的问题是需要全局同步分布式处理系统。这是一个非常古老的问题,大多数人都会按照您正在解决的方式来解决它,通过使用他们数据库的内置功能来处理分布式系统的同步。还有很多其他的方法,但是如果您已经在使用一个做得很好的基础架构(大多数数据库都是这样),那么就继续使用它

对于另一个问题(将快照分析器与事件分析器分离),您必须让快照分析器知道只分析一次事件的要求(就像您一样),或者让事件分析器知道该要求。如果您让snapshot Analyzer盲目地将消息排入事件分析器的队列,并且让事件分析器执行数据库工作以避免双重处理,那么您将很好地封装需求,并警告您要向队列中添加额外的消息。这有一个好处,因为您有一个瓶颈,您可以在一个瓶颈处将这些内容累积到内存中,而不必进行外部数据库调用