在山姆·纽曼( Sam )的“构建微服务”(Building,O‘’Reilly)中,有一节名为“舱壁”(),它是一章的一部分,讨论了如何防止阻塞的微服务破坏整个系统。
如本节所述,舱壁的一个例子是有单独的连接池连接到每个下游服务。
作者讨论的是对下游服务的同步调用,因此我将上面的内容解读为“HTTP客户机池”。
但是,在.NET中,使用单例HTTP客户端以提高可伸缩性越来越被认为是最佳实践。
我是否直截了当地认为,在.NET中,这种舱壁是不适用的?
如果有其他的舱壁,我们应该更关注哪些?

发布于 2019-04-25 01:57:53
我想解释一些事情,这样你就可以有完整的图片来更好地理解这个模式。
套接字和Tcp
假设您有3项服务A,B,C。在每个客户请求中,您都需要使用http调用它们。每次创建http客户端时,都会创建tcp连接并打开套接字。套接字的数量有硬限制,如果您有非常多的http调用,您可能最终会咀嚼所有的套接字连接。这就是为什么需要重用单个http客户机的原因。在.net核心中,您可以使用HttpClientfactory来实现这一点。因此,如果您有3个服务要通过http调用,您可以打开3个单独的http连接(套接字),在下面将被重用。
线程池
另一部分是关于线程池的。即使在使用共享/单例http客户端连接调用时,仍然必须将线程分配给该连接。假设您有100个可用于容纳客户端请求的线程。任何超过100个请求的请求都会排队。现在假设您正在使用由100个线程组成的连接池独立调用三个服务。在愉快路径中,每个服务将及时返回,当线程完成工作(http请求完成)时,它将返回池以满足来自队列的下一个客户端请求。在此期间,100个线程使用3个共享的httpclient实例来调用外部服务,并且下面只有3个套接字。所以在这之前我们都很好。
失败服务
现在让我们假设一个服务是慢的还是慢的。由于线程池(在本例中为100)是共享的,并且您正在调用慢速/向下服务,但是线程需要更长的时间来响应。其他两个服务仍然正常,可以响应,但是由于降级服务,任何正在调用降级服务的线程都需要更长的时间来完成请求,或者在请求返回到线程池之前最终超时。这意味着越来越多的克林顿请求排队。此时,消费者对其他(健康)服务的请求就会受到影响。最终,使用者不能再向其他服务发送请求,而不仅仅是原始的没有响应的服务。所有可用的线程都被困在降级的服务中,队列仍在增长。其他使用者不再能够使用该服务,从而导致级联故障效应。
舱壁到救援
这就是舱壁来救援的地方。根据使用者负载和可用性需求将服务实例划分为不同的组。此设计有助于隔离故障,并允许您为某些消费者维护服务功能,即使在出现故障时也是如此。
使用者还可以对资源进行分区,以确保用于调用一个服务的资源不会影响用于调用另一个服务的资源。例如,调用多个服务的使用者可以为每个服务分配一个连接池。如果服务开始失败,它只会影响为该服务分配的连接池,从而允许使用者继续使用其他服务。
因此,从上面的例子中,您可以说,请为每个服务分配33个线程。现在,失败的服务只会影响分配给它的线程。健康的服务将继续使用它们分配的线程,而不会有任何问题,并将继续满足客户端请求。
.Net Core和Polly
波利是处理这种情况的非常著名的图书馆。Polly很自然地适合.Net核心,您可以为http客户端分配多个策略,包括舱壁。
您可以找到更多关于polly https://github.com/App-vNext/Polly的信息。
希望这能帮上忙!
https://stackoverflow.com/questions/55836600
复制相似问题