微服务架构中如何处理网络调用 [英] How to handle network calls in Microservices architecture

查看:42
本文介绍了微服务架构中如何处理网络调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们使用微服务架构,其中顶级服务用于将 REST API 暴露给最终用户,后端服务执行查询数据库的工作.

We are using Micro services architecture where top services are used for exposing REST API's to end user and backend services does the work of querying database.

当我们收到 1 个用户请求时,我们会向后端服务发出大约 30k 个请求.我们将 RxJava 用于顶级服务,因此所有 30K 请求都可以并行执行.我们使用 haproxy 在后端服务之间分配负载.然而,当我们收到 3-5 个用户请求时,我们会收到网络连接异常、无路由到主机异常、套接字连接异常.

When we get 1 user request we make ~30k requests to backend service. We are using RxJava for top service so all 30K requests gets executed in parallel. We are using haproxy to distribute the load between backend services. However when we get 3-5 user requests we are getting network connection Exceptions, No Route to Host Exception, Socket connection Exception.

这种用例的最佳实践是什么?

What are the best practices for this kind of use case?

推荐答案

好吧,您最终遇到了经典的微服务混乱.你使用什么技术完全无关 - 问题在于你应用微服务概念的方式!

Well you ended up with the classical microservice mayhem. It's completely irrelevant what technologies you employ - the problem lays within the way you applied the concept of microservices!

在这种架构中,服务相互调用是很自然的(最好应该异步发生!!).由于我对您的服务 API 知之甚少,因此我必须对您的后端出了什么问题做出一些假设:

It is natural in this architecture, that services call each other (preferably that should happen asynchronously!!). Since I know only little about your service APIs I'll have to make some assumptions about what went wrong in your backend:

我假设用户向一项服务发出请求.该服务现在将(显然是同步的)查询另一个服务并接收您描述的这 30k 条记录.由于您可能需要了解更多关于这些记录的信息,您现在必须对每条记录向第三个服务/端点发出另一个请求,以汇总您的前端所需的所有信息!

I assume that a user makes a request to one service. This service will now (obviously synchronously) query another service and receive these 30k records you described. Since you probably have to know more about these records you now have to make another request per record to a third service/endpoint to aggregate all the information your frontend requires!

这告诉我,您可能在 有界上下文 的问题上搞错了!分析部分就这么多.现在来解决:

This shows me that you probably got the whole thing with bounded contexts wrong! So much for the analytical part. Now to the solution:

您的 API 应该返回所有信息以及枚举它们的查询!有时,这似乎与微服务模式指定的对数据/状态的隔离和权限的类型相矛盾 - 但仅在一个服务中隔离数据/状态是不可行的,因为这会导致您当前遇到的问题 - 所有其他服务必须每次都查询该数据才能将正确的数据返回给前端!但是,只要对数据/状态的权限明确,就可以复制它!

Your API should return all the information along with the query that enumerates them! Sometimes that could seem like a contradiction to the kind of isolation and authority over data/state that the microservices pattern specifies - but it is not feasible to isolate data/state in one service only because that leads to the problem you currently have - all other services HAVE to query that data every time to be able to return correct data to the frontend! However it is possible to duplicate it as long as the authority over the data/state is clear!

让我用一个例子来说明这一点:假设您有一个经典的商店系统.文章被分组.现在您可能会编写两个微服务——一个处理文章,一个处理组!你这样做是对的!您可能已经决定 group-service 将保存与分配给 group 的文章的关系!现在,如果前端想要显示组中的所有项目 - 会发生什么:组服务接收请求并在前端接收的漂亮 JSON 数组中返回 30'000 个文章编号.这就是一切向南的地方:前端现在必须为从 group-service 收到的每篇文章查询 article-service!!!Aaand 你完蛋了!

Let me illustrate that with an example: Let's assume you have a classical shop system. Articles are grouped. Now you would probably write two microservices - one that handles articles and one that handles groups! And you would be right to do so! You might have already decided that the group-service will hold the relation to the articles assigned to a group! Now if the frontend wants to show all items in a group - what happens: The group service receives the request and returns 30'000 Article numbers in a beautiful JSON array that the frontend receives. This is where it all goes south: The frontend now has to query the article-service for every article it received from the group-service!!! Aaand your're screwed!

现在有多种方法可以解决这个问题: 一种是(如前所述)将文章信息复制到组服务:因此每次使用组服务将文章分配到组时,它必须阅读该文章的所有信息形成文章服务并将其存储以便能够使用 get-me-all-the-articles-in-group-x 查询返回它.这相当简单,但请记住,当文章服务中的信息发生变化时,您需要更新此信息,或者您将从组服务中提供陈旧数据.在这个用例中,事件溯源是一个非常强大的工具,我建议你阅读它!您还可以使用从一项服务(在本例中为文章服务)发送到您偏好的消息总线的简单消息,并使组服务侦听这些消息并做出反应.

Now there are multiple ways to solve this problem: One is (as previously mentioned) to duplicate article information to the group-service: So every time an article is assigned to a group using the group-service, it has to read all the information for that article form the article-service and store it to be able to return it with the get-me-all-the-articles-in-group-x query. This is fairly simple but keep in mind that you will need to update this information when it changes in the article-service or you'll be serving stale data from the group-service. Event-Sourcing can be a very powerful tool in this use case and I suggest you read up on it! You can also use simple messages sent from one service (in this case the article-service) to a message bus of your preference and make the group-service listen and react to these messages.

针对您的问题的另一个非常简单的快速解决方案也可能只是在文章服务上提供一个新的 REST 端点,该端点接受一组文章 ID 并将信息返回给所有这些,这会更快.这可能会很快解决您的问题.

Another very simple quick-and-dirty solution to your problem could also be just to provide a new REST endpoint on the articles services that takes an array of article-ids and returns the information to all of them which would be much quicker. This could probably solve your problem very quickly.

在使用微服务的后端中,一个好的经验法则是希望这些跨服务调用的数量保持不变,这意味着跨服务边界的调用数量不应与请求的数据量直接相关!我们密切监视由于通过我们的 API 发出的给定请求而进行的服务调用,以跟踪哪些服务调用了哪些其他服务以及我们的性能瓶颈将在何处出现或已经造成.每当我们检测到一个服务产生很多(没有固定的阈值,但每次我看到 >4 我开始问问题!)调用其他服务时,我们会调查为什么以及如何解决这个问题!有一些很棒的指标工具可以帮助您跨服务边界跟踪请求!

A good rule of thumb in a backend with microservices is to aspire for a constant number of these cross-service calls which means your number of calls that go across service boundaries should never be directly related to the amount of data that was requested! We closely monitory what service calls are made because of a given request that comes through our API to keep track of what services calls what other services and where our performance bottlenecks will arise or have been caused. Whenever we detect that a service makes many (there is no fixed threshold but everytime I see >4 I start asking questions!) calls to other services we investigate why and how this could be fixed! There are some great metrics tools out there that can help you with tracing requests across service boundaries!

告诉我这是否有帮助,以及您实施的任何解决方案!

Let me know if this was helpful or not, and whatever solution you implemented!

这篇关于微服务架构中如何处理网络调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆