跨微服务查询/分页

时间:2016-12-01 00:48:57

标签: web-services rest integration soa microservices

我们的工作室最近开始采用SOA方法进行应用程序开发。我们看到SOA /微服务的关注点,可重用性和其他好处分离带来了很多好处。

但是,我们坚持的一个项目是跨服务聚合,过滤和分页结果。让我用场景描述问题。

假设我们有3项服务:

  1. PersonService - 存储有关人员(姓名,地址等)的信息
  2. ItemService - 存储有关可购买商品的信息。
  3. PaymentService - 存储有关人们为不同商品付款的信息。
  4. 现在,我们想要构建一个可以汇总显示/报告多个服务的报告/管理工具。例如,我们希望显示付款的分页列表,以及每笔付款所针对的人员和项目。这非常简单:获取付款清单,然后查询PersonService和ItemService以获取相应的人员和项目记录。

    然而,当我们想要过滤掉这些数据时,问题就会发挥作用:例如,显示由姓名为“Bob”的人员制作的分段付款清单,他们购买了该项目'汽车&#39 ;.这使得事情变得更加复杂,因为我们需要从3个不同的服务中过滤结果,而不知道每个服务将返回多少结果。

    从性能角度来看,一遍又一遍地查询所有服务以缩小搜索结果的成本很高,因此我一直在研究更好的解决方案。但是,我找不到解决这个问题的具体方法(或者至少是一个"最佳实践")。在单个应用程序中,我们只是在不同的表中使用SQL连接。我很难搞清楚服务之间是否有类似的事情。

    我向社区提出的问题是:你的做法是什么?我考虑过的事情:

    1. 使用某种搜索索引( Elasticsearch Solr ),其中包含所有服务的所有数据(通过服务推出的事件更新),然后查询搜索结果索引。
    2. 尝试了解 GraphQL Neo4j 等项目如何帮助我们解决这些问题。

3 个答案:

答案 0 :(得分:3)

我坚持使用Sam Newman,他在第4章"共享数据库"他的书有点像:

  

还记得我们谈到好微服务背后的核心原则吗?强大的凝聚力和松散的耦合 - 随着数据库集成,我们失去了两件事。数据库集成使服务很容易共享数据,但对共享行为没有任何作用。我们的内部代表通过线路暴露给我们的消费者,并且很难避免做出突破性变化,这不可避免地导致对任何变化的恐惧。避免(几乎)所有费用。

这是我在Content-Management-Systems诅咒时所提出的观点。

在我看来,微服务是自治的,如果它分享东西或消费共享的东西就不可能。我在这里做的唯一例外是域对象,它们代表了对业务模型的共同理解,必须仅用于微服务之间的通信。

如果ER或AggregationOriented数据库(分为基于文档或基于图形)更适合需要,它取决于微服务本身。 有趣的是,通过loosley耦合和通过自治,你能够做到这一点!

如果PaymentService分享"对于A" 他需要知道人A才能满足这一要求。但他所知道的关于Person A的一切必须来自PersonService,可能是在运行时(PaymentService可能只是存储一个id)或基于事件(PaymentService将它需要的数据存储到Domain-Object用户,触发和提供更新的内容)由PersonService)。 PaymentService本身不共享用户。

答案 1 :(得分:1)

除了将SQL数据存储在 elasticsearch / solr / cognitivesearch 类型服务中,还可以帮助解决其中的一些问题。

在您给出的示例中,

在搜索索引(elasticsearch / solr / cognitivesearch)中,person对象将具有一个名为"items"的属性,其中将包含由该人支付的商品列表。

这样,您可以跨对象过滤,获得按人员的任何属性排序的分页列表。您可以在其他文档上添加类似信息,以更好地满足您的业务需求。

使用 GraphDatabase 似乎可以从10000英尺处解决您的问题,但是在大规模操作时会遇到分页问题。 GraphDatabases do not do pagination well(即使您需要分页列表,它们仍然必须访问所有节点),并且会导致超时/性能问题。

答案 2 :(得分:0)

您可以使用复制表。 所有数据库均具有复制功能 如果您有具有人员表的personService和具有付款表的PaymentService,则创建具有人员表和付款表的reportService,它们由复制功能填充。