我们使用的是Micro服务架构,其中顶级服务用于向最终用户公开REST API,后端服务用于查询数据库。
当我们收到1个用户请求时,我们会向后端服务发出约3万个请求。我们使用RxJava作为顶级服务,因此所有30K请求都可以并行执行。我们正在使用haproxy在后端服务之间分配负载。然而,当我们收到3-5个用户请求时,我们会收到网络连接异常、无主机路由异常、套接字连接异常。
这种用例的最佳实践是什么?
你最终遭遇了经典的微服务混乱。你使用什么技术完全无关——问题在于你应用微服务概念的方式!
在这个体系结构中,服务相互调用是很自然的(最好是异步调用!!)。由于我对您的服务API知之甚少,我将不得不对您的后端出现的问题做出一些假设:
我假设用户向一个服务发出请求。该服务现在将(显然是同步的)查询另一个服务,并接收您描述的这3万条记录。由于您可能需要了解更多关于这些记录的信息,因此现在必须为每条记录向第三个服务/端点发出另一个请求,以聚合前端所需的所有信息!
这向我表明,在有界上下文的情况下,你可能把整件事都搞错了!分析部分到此为止。现在是解决方案:
您的API应该返回所有信息以及枚举这些信息的查询!有时,这似乎与微服务模式指定的对数据/状态的隔离和授权相矛盾——但仅在一个服务中隔离数据/状态是不可行的,因为这会导致您当前遇到的问题——所有其他服务都必须每次查询该数据,才能将正确的数据返回到前端!但是,只要数据/状态的权限明确,就可以复制它!
让我举一个例子来说明这一点:假设你有一个经典的商店系统。文章被分组。现在,您可能会编写两个微服务——一个处理文章,另一个处理组!你这样做是对的!您可能已经决定组服务将保留与分配给组的文章的关系!现在,如果前端想要显示组中的所有项目,会发生什么:组服务接收请求,并在前端接收的漂亮JSON数组中返回30'000个文章编号。这就是问题的症结所在:前端现在必须查询文章服务,以获取从群服务收到的每一篇文章!!!啊,你完蛋了!
现在有多种方法可以解决这个问题:一种是(如前所述)将文章信息复制到组服务:因此,每次使用组服务将文章分配到组时,它都必须从文章服务中读取该文章的所有信息,并将其存储,以便能够通过get-me-all-the-articles-in-group-x查询返回。这很简单,但请记住,当文章服务中的信息发生变化时,您需要更新这些信息,或者您将从组服务中提供过时的数据。在这个用例中,Event Sourcing可能是一个非常强大的工具,我建议您仔细阅读!您还可以使用从一个服务(在本例中为文章服务)发送到您偏好的消息总线的简单消息,并使组服务侦听和响应这些消息。
对于您的问题,另一个非常简单、快速且肮脏的解决方案也可能只是在文章服务上提供一个新的REST端点,该端点接受一组文章ID并将信息返回给所有这些ID,这将更快。这可能很快就能解决你的问题。
在微服务的后端,一个很好的经验法则是希望有恒定数量的跨服务调用,这意味着你的跨服务边界调用数量永远不应该与请求的数据量直接相关!我们密切监控由于通过API发出的给定请求而进行的服务调用,以跟踪哪些服务调用了哪些其他服务,以及我们的性能瓶颈将在哪里出现或已在哪里造成。每当我们检测到一个服务对其他服务进行了多次调用(没有固定的阈值,但每次我看到>4时,我都会开始问问题!),我们就会调查为什么以及如何解决这一问题!有一些很棒的度量工具可以帮助您跨服务边界跟踪请求!
请告诉我这是否有帮助,以及您实施的任何解决方案!