踏上保持活力的道路

在现代IT解决方案的体系结构中,增加微服务之间的数据交换活动通常是一个问题。最大限度地发挥作用并不惜一切代价生存-这对任何开发都是一个严峻的挑战。因此,寻求最佳解决方案是一个不间断的过程。本文总结了使用高负载的http请求和绕过它们的方法时可能出现的问题。


这个故事始于一个错误。我们以某种方式进行了负载测试,其主要元素是执行大量的简短http请求。从netcore 2.2编写的客户端(从某个时刻开始)会抛出System.Net.Sockets.SocketException:地址已在使用中。很快变得很清楚,这些端口没有时间释放给客户端,因此有时系统拒绝打开新端口。现在,如果我们去看代码,问题就在于将旧方法与HttpWebRequest和构造一起使用:


var request = WebRequest.CreateHttp(uri);
using(var resp = request.GetResponse()){ … }

似乎我们正在释放资源,应该及时释放端口。但是,netstat表示处于TIME_WAIT状态的端口数量迅速增加。此状态意味着等待连接关闭(并可能接收丢失的数据)。结果,端口可能会在其中停留1-2分钟。这个问题在一些细节上的许多文章讨论(与TIME_WAIT队列问题历史约TIME_WAIT)。尽管如此,这意味着dotnet正 “诚实地”试图关闭连接,并且由于系统超时设置的错误而进一步发生了。


为什么会发生这种情况以及如何处理


我不会谈论保持活跃。您可以自己阅读。本文的目的是尝试绕过耙子,将其小心地布置在开发人员的路上。根据msdn默认情况下HttpWebRequestKeepAlive属性true。也就是说,一直以来,HttpWebRequest都 “欺骗”了服务器,让他维护连接,然后他自己将其断开。更确切地说,具有默认设置的HttpWebRequest不会发送“ Connection:keep-alive”标头,而HTTP / 1.1标准中仅暗含了此模式要尝试的第一件事是强制禁用KeepAlive。如果设置HttpWebRequest.KeepAlive = false,则请求将获得标头“ Connection:close”。诚然,这完全解决了测试台上的问题。作为服务器,nginx配置了静态页面。


测试了以下代码:


while (true)
{
  var request = WebRequest.CreateHttp(uri);
  request.KeepAlive = false;
  var resp = await request.GetResponseAsync();
  using (var sr = new StreamReader(resp.GetResponseStream()))
  {
    var content = sr.ReadToEnd();
  }
}

但是,当尝试在服务器硬件上启动时,在高负载(每秒超过1000个请求)下,此代码再次开始产生相同的错误。仅现在端口处于CLOSE_WAIT,LAST_ACK状态。这些是客户端等待关闭发起方确认时连接的预关闭状态。这种行为表明客户端开始用新打开的连接““住”。


不要关闭,重复使用


, , . keep-alive HttpClient. .


, , ? keep-alive nginx:


  • keepalive_timeout – ( 15)
  • keepalive_requests – ( 100)

netstat wireshark, . keepalive_requests (> 1000) , .



http , . . , , keep-alive. keep-alive , .


:


  • RunHttpClient – HttpClient "Connection: keep-alive"
  • RunHttpClientClosed – HttpClient "Connection: closed"
  • RunWebRequestClosed-使用类HttpWebRequest模式“连接:已关闭”

Nginx服务器配置有以下参数:


  • keepalive_timeout 60秒;
  • keepalive_requests 100000;

方法ñTheads意思
运行httpclient10001个963.3毫秒
RunWebRequestClosed10001个3,857.4毫秒
RunHttpClientClosed10001个1,612.4毫秒
运行httpclient10,0001个9,573.9毫秒
RunWebRequestClosed10,0001个37,947.4毫秒
RunHttpClientClosed10,0001个16,112.9毫秒

All Articles