.NET微服务中的隔板示例

问题描述 投票:1回答:1

在Sam Newman的“建立微服务”(O'Reilly)中,有一个名为Bulkheads的部分,它是一章中的一部分,讨论如何防止堵塞的微服务搞乱整个系统。

如本节所述,隔板的一个示例是具有单独的连接池以连接到每个下游服务。

作者正在讨论对下游服务的同步调用,因此我将上述内容称为“HTTP客户端池”。

但是,在.NET中,使用单例HTTP客户端以提高可伸缩性已被越来越多地视为最佳实践。

我是否直截了当地认为,在.NET中,这种舱壁是不适用的?

如果有的话,我们应该更关注哪些其他类型的舱壁?

Bulkheads page

.net architecture microservices dotnet-httpclient
1个回答
1
投票

我想解释一些事情,这样你就可以更好地了解这种模式。

套接字和Tcp

假设您有3项服务A,B,C。在每个客户端请求您需要使用http调用它们。每次创建http客户端时,都会在tcp连接下创建并打开套接字。套接字的数量有硬限制,如果你有很多的http调用,你最终可能会咀嚼所有套接字连接。这就是为什么需要重用单个http客户端的原因。在.net核心中,您可以使用HttpClientfactory来实现此目的。因此,如果您有3个服务通过http调用,您可以在其下打开3个单独的http连接(套接字),这些连接将被重用。

线程池

另一部分是关于线程池。即使使用shared / singleton http客户端连接进行调用,您仍然必须为该连接分配线程。假设您有100个总线程可用于满足客户端请求。超过100个请求的任何内容都将排队。现在假设您使用连接池为100个线程的http独立调用三个服务。在快乐路径中,每个服务都将及时返回,当线程完成工作(http请求完成)后,它将返回池以完成从队列中的下一个客户端请求。在这段时间内,100个线程正在使用3个共享的httpclient实例来调用外部服务,并且下面只有3个套接字。所以我们一直很好,直到这一点。

服务失败

现在让我们说一项服务要么很慢,要么已经停止。由于线程池(在这种情况下为100)是共享的,并且您正在调用慢/降服务,但线程需要更长的时间来响应。其他两个服务仍然很好并且可以响应但是由于服务质量下降,任何调用降级服务的线程将花费更长的时间来完成请求,或者最终在它返回线程池之前超时。这意味着越来越多的clinet请求正在排队。此时,消费者对其他(健康)服务的请求受到影响。最终,消费者不再能够向其他服务发送请求,而不仅仅是原始无响应的服务。所有可用线程都停留在降级服务上,队列仍在增长。其他消费者不再能够使用该服务,从而导致级联故障效应。

隔板拯救

这就是舱壁来救援的地方。根据用户负载和可用性要求将服务实例分区到不同的组中。此设计有助于隔离故障,并允许您为某些消费者维持服务功能,即使在故障期间也是如此。

消费者还可以对资源进行分区,以确保用于调用一个服务的资源不会影响用于调用另一个服务的资源。例如,可以为每个服务分配一个呼叫多个服务的消费者。如果服务开始失败,它只会影响为该服务分配的连接池,从而允许使用者继续使用其他服务。

所以从上面的例子中你会说请为每个服务分配33个线程。现在,失败的服务只会影响分配给它的线程。健康的服务将继续使用他们分配的线程没有任何问题,并将继续履行客户端请求。

.Net Core和Polly

Polly是处理这种情况的非常着名的图书馆。 Polly自然适合.Net Core,您可以为http客户端分配多个策略,包括隔离。

你可以找到更多关于polly https://github.com/App-vNext/Polly的信息

希望有所帮助!

© www.soinside.com 2019 - 2024. All rights reserved.