dotnet Core 调用HTTP接口,系统大量CLOSE_WAIT连接问题的分析,尚未解决。
环境:
dotnet core 1.0.1
CentOS 7.2
今天在服务器巡检的时候,发现一个服务大量抛出异常
异常信息为:
LockStatusPushError&&Message:One or more errors occurred. (An error occurred while sending the request. Too many open files)&InnerMessageAn error occurred while sending the request. Too many open files& at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
at System.Threading.Tasks.Task.Wait()
at CommonHelper.HttpHelper.HttpRequest(String Url, String Method, String ContentType, Byte[] data, Encoding encoding)
at CommonHelper.HttpHelper.PostForm(String Url, Dictionary` para, Encoding encoding)
at CommonHelper.HttpHelper.PostForm(String Url, Dictionary` para)
at DeviceService.Program.LockStatusPushMethod()
首先推断,是程序打开文件(端口或者管道)太多导致的超过系统最大限制
使用 ulimit -n 查看最大限制 发现 系统最大限制为65535 为正常值
使用 lsof | wc -l 查看当前打开文件数 发现执行非常缓慢,执行结果显示系统当前打开文件数500w++。。。。。
继而查看dotnet程序打开文件数,发现为400w++
lsof>>/tmp/lsof.log 把当前打开文件列表保存 以供问题判断。
文件导出后,发现 dotnet 程序有大量状态为 CLOSE_WAIT 的socket连接 目的地址为程序访问的HTTP服务器的80端口
dotnet root 216r FIFO , 0t0 pipe
dotnet root 217w FIFO , 0t0 pipe
dotnet root 218u IPv4 0t0 TCP txk-web:->txk-web:http (CLOSE_WAIT)
dotnet root 219r FIFO , 0t0 pipe
dotnet root 220w FIFO , 0t0 pipe
dotnet root 221u IPv4 0t0 TCP txk-web:->txk-web:http (CLOSE_WAIT)
dotnet root 222r FIFO , 0t0 pipe
dotnet root 223w FIFO , 0t0 pipe
dotnet root 224u IPv4 0t0 TCP txk-web:->txk-web:http (CLOSE_WAIT)
dotnet root 225r FIFO , 0t0 pipe
dotnet root 226w FIFO , 0t0 pipe
dotnet root 227u IPv4 0t0 TCP txk-web:->txk-web:http (CLOSE_WAIT)
dotnet root 228r FIFO , 0t0 pipe
dotnet root 229w FIFO , 0t0 pipe
dotnet root 230u IPv4 0t0 TCP txk-web:->txk-web:http (CLOSE_WAIT)
dotnet root 231r FIFO , 0t0 pipe
dotnet root 232w FIFO , 0t0 pipe
dotnet root 233u IPv4 0t0 TCP txk-web:->txk-web:http (CLOSE_WAIT)
定位原因出现在HTTP访问上
继而查看程序的日志,发现需要程序访问的HTTP接口报500错误,
出现错误后程序会重试请求(逻辑上要求重试),重试间隔为100ms,太短导致短时间内有太多请求
首先解释CLOSE_WAIT

对方主动关闭连接或者网络异常导致连接中断,这时我方的状态会变成CLOSE_WAIT 此时我方要关闭连接来使得连接正确关闭。
初步判断可能有如下原因:
1.程序抛出异常后没有释放资源
2.dotnet core 底层的 bug
3.nginx代理强制关我的连接,又没有给我关闭的确认包
4.HTTP请求超时(这个基本没可能,HTTP接口在本机)
接下来首先看代码,我的HTTP访问方法代码如下:
private static byte[] HttpRequest(string Url, string Method, string ContentType, byte[] data, Encoding encoding)
{
WebResponse response = null;
HttpWebRequest request = null;
byte[] result = null;
try
{
request = (HttpWebRequest)WebRequest.Create(Url);
request.Headers["UserAgent"] = @"Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)";
request.Accept = @"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8";
request.Method = Method;
request.ContentType = ContentType;
if (data != null)
{
var reqStreamAsync = request.GetRequestStreamAsync();
//reqStreamAsync.Wait();
using (Stream reqStream = reqStreamAsync.Result)
{
reqStream.Write(data, , data.Length);
reqStream.Dispose();
}
}
var reqAsync = request.GetResponseAsync();
//reqAsync.Wait();
using (response = reqAsync.Result)
{
using (Stream stream = response.GetResponseStream())
{
List<byte> byteArr = new List<byte>();
int tmp = -;
while ((tmp = stream.ReadByte()) >= )
{
byteArr.Add((byte)tmp);
}
result = byteArr.ToArray();
stream.Dispose();
}
response.Dispose();
}
}
catch (Exception ex)
{
throw;
}
finally
{
if (request != null)
{
request.Abort();
request = null;
}
if (response != null)
{
response.Dispose();
response = null;
}
}
return result;
}
看到代码 第一想法是 HttpWebRequest 没有套using也没有Dispose(),
但是尝试后发现,这个类根本就没有实现IDisposable接口,也没法手工释放,
百度之后得到结论,只能Abort(),添加到finally,顺便给WebResponse增加Dispost(),重新尝试 -------- 无效。
之后修改了Centos的/etc/sysctl.conf
增加对keepalive相关配置进行尝试
net.ipv4.tcp_keepalive_time=60
net.ipv4.tcp_keepalive_probes=2
net.ipv4.tcp_keepalive_intvl=2
然后 sysctl -p 重新加载配置,再次尝试 -------- 问题依旧。
之后又感觉是程序没有释放HttpWebRequest,
在HTTP访问方法的finally中加入GC.Collect(),希望强制回收 -------- 还是没用。
最终已经放弃寻找问题,直接把重试的地方增加延时,如果http请求出错,Thread.Sleep(10000);
临时解决此问题。
问题最终没有完美解决。
希望各位如果谁能知道问题原因,与我讨论,谢谢
2017.04.07 更新
今天更换HttpClient进行HTTP通讯
发现问题解决了。。。。
代码如下,欢迎指正~
private async static Task<byte[]> HttpRequest(string Url, HttpMethodEnum HttpMethod, string ContentType, byte[] data)
{
byte[] result = null;
try
{
using (HttpClient http = new HttpClient())
{
http.DefaultRequestHeaders.Add("User-Agent", @"Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)");
http.DefaultRequestHeaders.Add("Accept", @"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"); HttpResponseMessage message = null;
if (HttpMethod == HttpMethodEnum.POST)
{
using (Stream dataStream = new MemoryStream(data ?? new byte[]))
{
using (HttpContent content = new StreamContent(dataStream))
{
content.Headers.Add("Content-Type", ContentType);
message = await http.PostAsync(Url, content);
}
}
}
else if (HttpMethod == HttpMethodEnum.GET)
{
message = await http.GetAsync(Url);
}
if (message != null && message.StatusCode == System.Net.HttpStatusCode.OK)
{
using (message)
{
using (Stream responseStream = await message.Content.ReadAsStreamAsync())
{
if (responseStream != null)
{
byte[] responseData = new byte[responseStream.Length];
responseStream.Read(responseData, , responseData.Length);
result = responseData;
}
}
}
}
}
}
catch (Exception ex)
{ throw;
}
return result;
}
dotnet Core 调用HTTP接口,系统大量CLOSE_WAIT连接问题的分析,尚未解决。的更多相关文章
- 详解C#泛型(二) 获取C#中方法的执行时间及其代码注入 详解C#泛型(一) 详解C#委托和事件(二) 详解C#特性和反射(四) 记一次.net core调用SOAP接口遇到的问题 C# WebRequest.Create 锚点“#”字符问题 根据内容来产生一个二维码
详解C#泛型(二) 一.自定义泛型方法(Generic Method),将类型参数用作参数列表或返回值的类型: void MyFunc<T>() //声明具有一个类型参数的泛型方法 { ...
- 一次接口压力测试qps极低原因分析及解决过程
一次接口压力测试qps极低原因分析及解决过程 9-2日在做内部的性能测试相关培训时,发现注册接口压力测试qps极低(20左右),这个性能指标远不能达到上线标准 ,经过一系列调试,最后定位 98%的时间 ...
- 记一次.net core调用SOAP接口遇到的问题
背景 最近需要将一些外部的Web Service及其他SOAP接口的调用移到一个独立的WebAPI项目中,然后供其他.Net Core项目调用.之前的几个Web Service已经成功迁 ...
- 探索 dotnet core 为何在 Windows7 系统需要补丁的原因
在一些 Windows 7 系统上,根据 dotnet 官方文档,需要安装上 KB2533623 补丁,才能运行 dotnet core 或 .NET 5 等应用.尽管非所有的设备都需要安装此,但这也 ...
- dotnet core开源博客系统XBlog介绍
XBlog是dotnet core平台下的个人博客开源系统,它只需要通过Copy的方式即可以部署到Linux和windows系统中:如果你有安全证书那只需要简单配置一下即可提供安全的Https服务.接 ...
- dotnet core 调用electron来开发UI的探索
先上仓库地址 https://github.com/lightszero/webwindow.netcore dotnet core 很喜欢,问题dotnet core 不包含GUI,经过一些尝试,觉 ...
- 调用支付宝接口Android客户端没有支付宝APP的情况下解决无法调用支付宝页面的问题
这几天一直研究支付宝接口调用,因为当前应用中需要调用支付宝接口作移动支付. 遇到一个问题困扰几天,就是当我们的手机端未安装支付宝APP的时候,需要在自己应用中调用支付宝的登陆网页进行支付.我是Andr ...
- DotNet Core 2.2 MVC Razor 页面编译为 View.dll 文件的解决方法
使用文本文件编辑器打开项目文件,找到: <PropertyGroup> <TargetFramework>netcoreapp2.0</TargetFramewo ...
- 64位系统web项目导出excel问题分析及解决方法汇总
最近在web项目中做了一个导出Excel功能.在导出的时候报错:检索 COM 类工厂中 CLSID 为 {00024500-0000-0000-C000-000000000046} 的组件时失败. 一 ...
随机推荐
- struts2中Action到底是什么,怎么理解
struts2中Action到底是什么,怎么理解 1.配置完web.xml2.创建视图页面login.jsp3.创建业务控制器LoginAction类(解释说:创建业务控制器LoginAction类, ...
- 【WCF】错误处理(一):FaultException 与 FaultReason 的搭配
这里所说的错误处理主要是指服务代码中抛出的异常,即开发人员主动抛出的错误当然,由于网络问题或者配置不正确,会引发连接超时的错误,但这里老周要说的是,我们在实现服务逻辑时主动抛出的异常,尤其是对客户端传 ...
- 读书笔记 effective c++ Item 29 为异常安全的代码而努力
异常安全在某种意义上来说就像怀孕...但是稍微想一想.在没有求婚之前我们不能真正的讨论生殖问题. 假设我们有一个表示GUI菜单的类,这个GUI菜单有背景图片.这个类将被使用在多线程环境中,所以需要mu ...
- TypeScript设计模式之门面、适配器
看看用TypeScript怎样实现常见的设计模式,顺便复习一下. 学模式最重要的不是记UML,而是知道什么模式可以解决什么样的问题,在做项目时碰到问题可以想到用哪个模式可以解决,UML忘了可以查,思想 ...
- 使用php ajax写省、市、区、三级联动
题目要求: 要求:写一个省市区(或者年月日)的三级联动,实现地区或时间的下拉选择. 实现技术:php ajax 实现:省级下拉变化时市下拉区下拉跟着变化,市级下拉变化时区下拉跟着变化. 使用china ...
- 会话控制之session和cookie(20161107)
注:除了登录页面,每个页面,包括处理页面也要加,为了提高安全性 session尽量不用,因为很占内存 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML ...
- Maven项目搭建(一):Maven初体验
今天给大家介绍一个项目管理和综合工具:Maven. Maven: maven读作 ['meivin],本意是指可以被信任的领域专家,致力于传播知识(来自于http://en.wikipedia.org ...
- JavaWeb之Filter、Listener
昨天和大家介绍了一下JSON的用法,其实JSON中主要是用来和数据库交互数据的.今天给大家讲解的是Filter和Listener的用法. 一.Listenner监听器 1.1.定义 Javaweb中的 ...
- 初用Linux, 安装Ubuntu16.04+NVIDIA387+CUDA8.0+cudnn5.1+TensorFlow1.0.1
因为最近Deep Learning十分热门, 装一下TensorFlow学习一下. 本文主要介绍安装流程, 将自己遇到的问题说明出来, 并记录自己如何处理, 原理方面并没有能力解释. 由于本人之前从来 ...
- springmvc框架原理
1. 用户发送请求至前端控制器DispatcherServlet 2. DispatcherServlet收到请求调用HandlerMapping处理器映射器. 3. 处理器映射器根据请求url ...