.NET微服务中的隔板示例

时间:2019-04-24 18:39:38

标签: .net architecture microservices dotnet-httpclient

在Sam Newman撰写的“ Building Microservices”(O'Reilly)中,有一个名为 Bulkheads 的部分,该部分讨论了防止阻塞的微服务干扰整个系统的方法。

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

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

但是,在.NET中,越来越多的人认为使用单例HTTP客户端来提高可伸缩性是一种最佳做法。

我是不是真的想过,在.NET中,这种舱壁不适用?

我们还要关注其他哪些类型的舱壁?

Bulkheads page

1 个答案:

答案 0 :(得分:1)

我想解释几件事,以便您可以全面了解该模式。

套接字和Tcp

假设您有3个服务A,B,C。在每个客户请求中,您都需要使用http对其进行调用。每次创建http客户端时,都会在下面创建一个tcp连接并打开套接字。套接字的数量有硬性限制,如果您有大量的http调用,您可能最终会消耗掉所有的套接字连接。这就是为什么需要重用单个http客户端的原因。在.net core中,您可以使用HttpClientfactory实现此目的。因此,如果您有3个通过http呼叫的服务,则可以在下面打开3个单独的http连接(套接字),以供重用。

线程池

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

服务失败

现在,可以说一项服务速度缓慢或下降。由于线程池(在这种情况下为100)是共享的,因此您正在调用慢速/慢速服务,但是线程需要更长的响应时间。其他两个服务仍然可以正常工作,并且可以响应,但是由于降级的服务,任何正在调用降级服务的线程都将花费更长的时间来完成请求,或者最终将超时,然后再返回线程池。这意味着越来越多的客户端请求正在排队。那时,消费者对其他(健康)服务的请求受到影响。最终,消费者不能再将请求发送到其他服务,而不仅仅是原始的无响应服务。您所有可用的线程都停留在降级的服务上,并且队列仍在增长。其他使用者不再能够使用该服务,从而导致级联失败的后果。

要抢救的隔板

这是舱壁救援的地方。根据使用者负载和可用性要求,将服务实例划分为不同的组。这种设计有助于隔离故障,并使您即使在故障期间也能为某些使用者维持服务功能。

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

因此,从上面的示例中,您会说请为每个服务分配33个线程。现在,服务失败只会影响分配给它的线程。健康的服务将继续使用分配的线程,而不会出现任何问题,并将继续满足客户端的请求。

.Net Core和Polly

Polly是处理此类情况的非常著名的图书馆。 Polly很自然地适合.Net Core,并且您可以将多个策略分配给http客户(包括隔板)。

您可以找到有关波莉https://github.com/App-vNext/Polly

的更多信息

希望有帮助!