C# 静态HttpClient,但仍有太多打开的套接字
我使用的是C# 静态HttpClient,但仍有太多打开的套接字,c#,asp.net-mvc,iis,dotnet-httpclient,C#,Asp.net Mvc,Iis,Dotnet Httpclient,我使用的是static Lazy,它应该确保套接字被重用。() 然而,我的应用程序在数百次请求后冻结。我已经添加了跟踪日志记录,并且可以在MVC操作中重现该问题,该操作除了调用HttpClient之外什么都不做 显式地说,它读取web.config值,验证一些ViewModel值,并解析HttpClient响应,但这永远不会出现 netstat显示存在大量打开的套接字。即使是现在,几分钟后,在我停止请求并花了一些时间写这个问题之后,套接字的数量似乎并没有减少 C:\Users\me>n
static Lazy
,它应该确保套接字被重用。()
然而,我的应用程序在数百次请求后冻结。我已经添加了跟踪日志记录,并且可以在MVC操作中重现该问题,该操作除了调用HttpClient之外什么都不做
- 显式地说,它读取web.config值,验证一些ViewModel值,并解析HttpClient响应,但这永远不会出现
netstat
显示存在大量打开的套接字。即使是现在,几分钟后,在我停止请求并花了一些时间写这个问题之后,套接字的数量似乎并没有减少
C:\Users\me>netstat
Active Connections
Proto Local Address Foreign Address State
TCP 127.0.0.1:443 localhost:53730 CLOSE_WAIT
TCP 127.0.0.1:443 localhost:53731 TIME_WAIT
TCP 127.0.0.1:443 localhost:53732 TIME_WAIT
TCP 127.0.0.1:443 localhost:53733 TIME_WAIT
TCP 127.0.0.1:443 localhost:53734 TIME_WAIT
TCP 127.0.0.1:443 localhost:53736 TIME_WAIT
TCP 127.0.0.1:443 localhost:53737 TIME_WAIT
TCP 127.0.0.1:443 localhost:53738 TIME_WAIT
TCP 127.0.0.1:443 localhost:53739 TIME_WAIT
TCP 127.0.0.1:443 localhost:53740 TIME_WAIT
TCP 127.0.0.1:443 localhost:53741 TIME_WAIT
TCP 127.0.0.1:443 localhost:53743 TIME_WAIT
TCP 127.0.0.1:443 localhost:53751 CLOSE_WAIT
TCP 127.0.0.1:443 localhost:53752 TIME_WAIT
TCP 127.0.0.1:443 localhost:53753 TIME_WAIT
TCP 127.0.0.1:443 localhost:53754 TIME_WAIT
TCP 127.0.0.1:443 localhost:53755 TIME_WAIT
TCP 127.0.0.1:443 localhost:53760 TIME_WAIT
TCP 127.0.0.1:443 localhost:53765 CLOSE_WAIT
TCP 127.0.0.1:443 localhost:53766 TIME_WAIT
TCP 127.0.0.1:443 localhost:53767 TIME_WAIT
TCP 127.0.0.1:443 localhost:53768 TIME_WAIT
TCP 127.0.0.1:443 localhost:53769 TIME_WAIT
TCP 127.0.0.1:443 localhost:53773 CLOSE_WAIT
TCP 127.0.0.1:443 localhost:53776 TIME_WAIT
TCP 127.0.0.1:443 localhost:53777 TIME_WAIT
TCP 127.0.0.1:443 localhost:53778 TIME_WAIT
TCP 127.0.0.1:443 localhost:53779 TIME_WAIT
TCP 127.0.0.1:443 localhost:53780 TIME_WAIT
TCP 127.0.0.1:443 localhost:53784 CLOSE_WAIT
TCP 127.0.0.1:443 localhost:53787 TIME_WAIT
TCP 127.0.0.1:443 localhost:53788 TIME_WAIT
TCP 127.0.0.1:443 localhost:53789 TIME_WAIT
TCP 127.0.0.1:443 localhost:53790 TIME_WAIT
TCP 127.0.0.1:443 localhost:53791 TIME_WAIT
TCP 127.0.0.1:443 localhost:53795 CLOSE_WAIT
TCP 127.0.0.1:443 localhost:53798 TIME_WAIT
TCP 127.0.0.1:443 localhost:53799 TIME_WAIT
TCP 127.0.0.1:443 localhost:53800 TIME_WAIT
TCP 127.0.0.1:443 localhost:53801 TIME_WAIT
TCP 127.0.0.1:443 localhost:53802 TIME_WAIT
TCP 127.0.0.1:443 localhost:53806 CLOSE_WAIT
TCP 127.0.0.1:443 localhost:53808 CLOSE_WAIT
TCP 127.0.0.1:443 localhost:53809 TIME_WAIT
TCP 127.0.0.1:443 localhost:53810 TIME_WAIT
TCP 127.0.0.1:443 localhost:53811 ESTABLISHED
TCP 127.0.0.1:443 localhost:53812 ESTABLISHED
TCP 127.0.0.1:443 localhost:53813 ESTABLISHED
TCP 127.0.0.1:443 localhost:53814 CLOSE_WAIT
TCP 127.0.0.1:443 localhost:53815 CLOSE_WAIT
TCP 127.0.0.1:443 localhost:53816 CLOSE_WAIT
TCP 127.0.0.1:443 localhost:53817 CLOSE_WAIT
TCP 127.0.0.1:443 localhost:53818 CLOSE_WAIT
TCP 127.0.0.1:443 localhost:53819 CLOSE_WAIT
TCP 127.0.0.1:443 localhost:53820 CLOSE_WAIT
TCP 127.0.0.1:443 localhost:53821 CLOSE_WAIT
TCP 127.0.0.1:443 localhost:53822 CLOSE_WAIT
TCP 127.0.0.1:443 localhost:53823 CLOSE_WAIT
TCP 127.0.0.1:443 localhost:53824 CLOSE_WAIT
TCP 127.0.0.1:443 localhost:53825 CLOSE_WAIT
TCP 127.0.0.1:443 localhost:53851 ESTABLISHED
TCP 127.0.0.1:443 localhost:53852 ESTABLISHED
TCP 127.0.0.1:443 localhost:53853 ESTABLISHED
TCP 127.0.0.1:443 localhost:53854 ESTABLISHED
TCP 127.0.0.1:443 localhost:53855 ESTABLISHED
TCP 127.0.0.1:443 localhost:53856 ESTABLISHED
TCP 127.0.0.1:443 localhost:53857 ESTABLISHED
TCP 127.0.0.1:443 localhost:53858 ESTABLISHED
TCP 127.0.0.1:443 localhost:53859 ESTABLISHED
TCP 127.0.0.1:443 localhost:53860 ESTABLISHED
TCP 127.0.0.1:443 localhost:53861 ESTABLISHED
TCP 127.0.0.1:443 localhost:53862 ESTABLISHED
TCP 127.0.0.1:443 localhost:53863 ESTABLISHED
TCP 127.0.0.1:443 localhost:53864 ESTABLISHED
TCP 127.0.0.1:443 localhost:53865 ESTABLISHED
TCP 127.0.0.1:443 localhost:53866 ESTABLISHED
TCP 127.0.0.1:443 localhost:53867 ESTABLISHED
TCP 127.0.0.1:443 localhost:53868 ESTABLISHED
TCP 127.0.0.1:443 localhost:53869 ESTABLISHED
TCP 127.0.0.1:443 localhost:53870 ESTABLISHED
TCP 127.0.0.1:44117 localhost:53301 ESTABLISHED
TCP 127.0.0.1:44117 localhost:53838 ESTABLISHED
TCP 127.0.0.1:44117 localhost:53839 ESTABLISHED
TCP 127.0.0.1:44117 localhost:53840 ESTABLISHED
TCP 127.0.0.1:44117 localhost:53841 ESTABLISHED
TCP 127.0.0.1:44117 localhost:53842 ESTABLISHED
TCP 127.0.0.1:49676 localhost:49677 ESTABLISHED
TCP 127.0.0.1:49677 localhost:49676 ESTABLISHED
TCP 127.0.0.1:50498 localhost:50501 ESTABLISHED
TCP 127.0.0.1:50501 localhost:50498 ESTABLISHED
TCP 127.0.0.1:53301 localhost:44117 ESTABLISHED
TCP 127.0.0.1:53697 localhost:53698 ESTABLISHED
TCP 127.0.0.1:53698 localhost:53697 ESTABLISHED
TCP 127.0.0.1:53699 localhost:53700 ESTABLISHED
TCP 127.0.0.1:53700 localhost:53699 ESTABLISHED
TCP 127.0.0.1:53701 localhost:53702 ESTABLISHED
TCP 127.0.0.1:53702 localhost:53701 ESTABLISHED
TCP 127.0.0.1:53703 localhost:53704 ESTABLISHED
TCP 127.0.0.1:53704 localhost:53703 ESTABLISHED
TCP 127.0.0.1:53705 localhost:53706 ESTABLISHED
TCP 127.0.0.1:53706 localhost:53705 ESTABLISHED
TCP 127.0.0.1:53707 localhost:53708 ESTABLISHED
TCP 127.0.0.1:53708 localhost:53707 ESTABLISHED
TCP 127.0.0.1:53709 localhost:53710 ESTABLISHED
TCP 127.0.0.1:53710 localhost:53709 ESTABLISHED
TCP 127.0.0.1:53711 localhost:53712 ESTABLISHED
TCP 127.0.0.1:53712 localhost:53711 ESTABLISHED
TCP 127.0.0.1:53713 localhost:53714 ESTABLISHED
TCP 127.0.0.1:53714 localhost:53713 ESTABLISHED
TCP 127.0.0.1:53715 localhost:53716 ESTABLISHED
TCP 127.0.0.1:53716 localhost:53715 ESTABLISHED
TCP 127.0.0.1:53717 localhost:53718 ESTABLISHED
TCP 127.0.0.1:53718 localhost:53717 ESTABLISHED
TCP 127.0.0.1:53719 localhost:53720 ESTABLISHED
TCP 127.0.0.1:53720 localhost:53719 ESTABLISHED
TCP 127.0.0.1:53721 localhost:53722 ESTABLISHED
TCP 127.0.0.1:53722 localhost:53721 ESTABLISHED
TCP 127.0.0.1:53723 localhost:53724 ESTABLISHED
TCP 127.0.0.1:53724 localhost:53723 ESTABLISHED
TCP 127.0.0.1:53725 localhost:53726 ESTABLISHED
TCP 127.0.0.1:53726 localhost:53725 ESTABLISHED
TCP 127.0.0.1:53727 localhost:53728 ESTABLISHED
TCP 127.0.0.1:53728 localhost:53727 ESTABLISHED
TCP 127.0.0.1:53730 localhost:https FIN_WAIT_2
TCP 127.0.0.1:53735 localhost:https TIME_WAIT
TCP 127.0.0.1:53742 localhost:https TIME_WAIT
TCP 127.0.0.1:53744 localhost:https TIME_WAIT
TCP 127.0.0.1:53745 localhost:https TIME_WAIT
TCP 127.0.0.1:53746 localhost:https TIME_WAIT
TCP 127.0.0.1:53747 localhost:https TIME_WAIT
TCP 127.0.0.1:53748 localhost:https TIME_WAIT
TCP 127.0.0.1:53749 localhost:https TIME_WAIT
TCP 127.0.0.1:53750 localhost:https TIME_WAIT
TCP 127.0.0.1:53751 localhost:https FIN_WAIT_2
TCP 127.0.0.1:53758 localhost:https TIME_WAIT
TCP 127.0.0.1:53761 localhost:https TIME_WAIT
TCP 127.0.0.1:53762 localhost:https TIME_WAIT
TCP 127.0.0.1:53763 localhost:https TIME_WAIT
TCP 127.0.0.1:53765 localhost:https FIN_WAIT_2
TCP 127.0.0.1:53770 localhost:https TIME_WAIT
TCP 127.0.0.1:53771 localhost:https TIME_WAIT
TCP 127.0.0.1:53772 localhost:https TIME_WAIT
TCP 127.0.0.1:53773 localhost:https FIN_WAIT_2
TCP 127.0.0.1:53775 localhost:https TIME_WAIT
TCP 127.0.0.1:53781 localhost:https TIME_WAIT
TCP 127.0.0.1:53782 localhost:https TIME_WAIT
TCP 127.0.0.1:53783 localhost:https TIME_WAIT
TCP 127.0.0.1:53784 localhost:https FIN_WAIT_2
TCP 127.0.0.1:53786 localhost:https TIME_WAIT
TCP 127.0.0.1:53792 localhost:https TIME_WAIT
TCP 127.0.0.1:53793 localhost:https TIME_WAIT
TCP 127.0.0.1:53794 localhost:https TIME_WAIT
TCP 127.0.0.1:53795 localhost:https FIN_WAIT_2
TCP 127.0.0.1:53797 localhost:https TIME_WAIT
TCP 127.0.0.1:53803 localhost:https TIME_WAIT
TCP 127.0.0.1:53804 localhost:https TIME_WAIT
TCP 127.0.0.1:53805 localhost:https TIME_WAIT
TCP 127.0.0.1:53806 localhost:https FIN_WAIT_2
TCP 127.0.0.1:53808 localhost:https FIN_WAIT_2
TCP 127.0.0.1:53811 localhost:https ESTABLISHED
TCP 127.0.0.1:53812 localhost:https ESTABLISHED
TCP 127.0.0.1:53813 localhost:https ESTABLISHED
TCP 127.0.0.1:53814 localhost:https FIN_WAIT_2
TCP 127.0.0.1:53815 localhost:https FIN_WAIT_2
TCP 127.0.0.1:53816 localhost:https FIN_WAIT_2
TCP 127.0.0.1:53817 localhost:https FIN_WAIT_2
TCP 127.0.0.1:53818 localhost:https FIN_WAIT_2
TCP 127.0.0.1:53819 localhost:https FIN_WAIT_2
TCP 127.0.0.1:53820 localhost:https FIN_WAIT_2
TCP 127.0.0.1:53821 localhost:https FIN_WAIT_2
TCP 127.0.0.1:53822 localhost:https FIN_WAIT_2
TCP 127.0.0.1:53823 localhost:https FIN_WAIT_2
TCP 127.0.0.1:53824 localhost:https FIN_WAIT_2
TCP 127.0.0.1:53825 localhost:https FIN_WAIT_2
TCP 127.0.0.1:53838 localhost:44117 ESTABLISHED
TCP 127.0.0.1:53839 localhost:44117 ESTABLISHED
TCP 127.0.0.1:53840 localhost:44117 ESTABLISHED
TCP 127.0.0.1:53841 localhost:44117 ESTABLISHED
TCP 127.0.0.1:53842 localhost:44117 ESTABLISHED
TCP 127.0.0.1:53851 localhost:https ESTABLISHED
TCP 127.0.0.1:53852 localhost:https ESTABLISHED
TCP 127.0.0.1:53853 localhost:https ESTABLISHED
TCP 127.0.0.1:53854 localhost:https ESTABLISHED
TCP 127.0.0.1:53855 localhost:https ESTABLISHED
TCP 127.0.0.1:53856 localhost:https ESTABLISHED
TCP 127.0.0.1:53857 localhost:https ESTABLISHED
TCP 127.0.0.1:53858 localhost:https ESTABLISHED
TCP 127.0.0.1:53859 localhost:https ESTABLISHED
TCP 127.0.0.1:53860 localhost:https ESTABLISHED
TCP 127.0.0.1:53861 localhost:https ESTABLISHED
TCP 127.0.0.1:53862 localhost:https ESTABLISHED
TCP 127.0.0.1:53863 localhost:https ESTABLISHED
TCP 127.0.0.1:53864 localhost:https ESTABLISHED
TCP 127.0.0.1:53865 localhost:https ESTABLISHED
TCP 127.0.0.1:53866 localhost:https ESTABLISHED
TCP 127.0.0.1:53867 localhost:https ESTABLISHED
TCP 127.0.0.1:53868 localhost:https ESTABLISHED
TCP 127.0.0.1:53869 localhost:https ESTABLISHED
TCP 127.0.0.1:53870 localhost:https ESTABLISHED
snip
我有两次出现HttpClient,都有一个单独的基地址。我尝试用Easy.Common.RestClient替换HttpClient,但没有成功
我准备好了
var servicePoint = ServicePointManager.FindServicePoint(new Uri(webApiAddress));
servicePoint.ConnectionLeaseTimeout = (int)TimeSpan.FromMinutes(1).TotalMilliseconds;
但这也没用。
我已将超时设置为15秒。我已尝试设置CloseConnection=true
或设置标题“Connection”:“Close”
我不知道该试什么了。。。有人能提供指导吗
更新
让我们详细讨论一下。我在类库中的类MyClientWrapper
中有一个静态惰性
(示例)。我的Asp.NETMVC5应用程序包括这个类库,并实例化了MyClientWrapper
我的MVC控制器调用myClientWrapper.GetData()
。在GetData
内部,创建了一条HttpRequestMessage
,并使用HttpClient
发送到我的API。读取HttpResponseMessage
。请求和响应都被释放,数据从GetData
返回
我正在使用Gatling向20个用户发出20个请求,请求MyController/MyAction
。在某个时刻(有时更早,有时更晚),不再有任何请求到达API。在MyController中放置调试断点将显示命中了GetData()
。wait
调用被命中,就这样<代码>netstat已满
我已经试着解决这个问题了
场景1:使用PostMan ping API(在我遇到任何问题之前)。没有问题
场景2:从GetData()
中删除所有代码,并替换为returnsomedummydata
public async Task<Data> GetData()
{
// No call to HttpClient, no issues
return new Data();
}
更新
- 将
从HttpClient
更改为static
(Castle Windsor IoC)没有任何区别PerThread
- 有趣的是,每当出现挂起时,IIS中WorkerProcess下正好有三个请求。每一次。正好三个。这是否与HttpClient的最大连接数(默认值2)有关
- 我已经验证了我的API的
方法内部没有逻辑。事实并非如此ping
可能与此相关:换句话说,这种用法正在破坏您的软件的稳定性?J/k,我肯定没问题。您在开始测试之前是否运行了
netstat
?有几件事。。。您正在从同一台计算机上的客户端连接到服务器,因此所有连接都将列出两次。。。从/到同一台机器的任何其他连接也将列出两次(就像每次在浏览器中打开页面以确保服务器仍在响应时一样)。。。仅仅因为你关闭了“你的终端”上的连接并不意味着服务器会。从您链接的文章中,您应该针对他们的Azure服务器进行测试。感谢您的回复,并指出他们已列出两次。我以前确实运行过netstat
。我回收了所有的应用程序池,重新启动了我的应用程序,重新启动了我的笔记本电脑。在netstat
中仅使用了1个套接字。然后,开始了我的测试,砰的一声。我不使用Azure,但今天晚些时候我可能可以在单独的服务器上进行测试。作为见证,我在几周前的搜索历史记录中添加了一些说明。。我有点担心。我承认我没有深入研究MVC和AppPool中的静态
行为。你有什么建议吗?或者这主要是一种预感?充其量只是一种预感。。。基于我对IIS应用程序池的有限(几乎不存在)理解。我要向上投票,因为我也想知道,并添加一些标签,可能会吸引正确的人回答这个问题。换句话说,这种用法正在破坏你的软件的稳定性?J/k,我肯定没问题。您在开始测试之前是否运行了netstat
?有几件事。。。您正在从同一台计算机上的客户端连接到服务器,因此所有连接都将列出两次。。。从/到同一台机器的任何其他连接也将列出两次(就像每次在浏览器中打开页面以确保服务器仍在响应时一样)。。。仅仅因为你关闭了“你的终端”上的连接并不意味着服务器会。从您链接的文章中,您应该针对他们的Azure服务器进行测试。感谢您的回复,并指出他们已列出两次。我以前确实运行过netstat
。我回收了所有的应用程序池,重新启动了我的应用程序,重新启动了我的笔记本电脑。在netstat
中仅使用了1个套接字。然后,开始了我的测试,砰的一声。我不使用Azure,但今天晚些时候我可能可以在单独的服务器上进行测试。作为见证,我在几周前的搜索历史记录中添加了一些说明。。我有点担心。我承认我没有深入研究MVC和AppPool中的静态
行为。你有什么建议吗?或者这主要是一种预感?充其量只是一种预感。。。基于我对IIS应用程序池的有限(几乎不存在)理解。我将向上投票,因为我也想知道,并添加一些标签,以吸引正确的人回答这个问题。
public async Task<Data> GetData()
{
// Issue occurs as soon as HttpClient is used for GET or POST. In this example, GET.
await _client.GetAsync("pseudocode/Ping");
// In reality I properly HttpRequestMessage/HttpResponseMessage read and dispose, this is just pseudocode really...
return new Data();
}