环境:

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连接问题的分析,尚未解决。的更多相关文章

  1. 详解C#泛型(二) 获取C#中方法的执行时间及其代码注入 详解C#泛型(一) 详解C#委托和事件(二) 详解C#特性和反射(四) 记一次.net core调用SOAP接口遇到的问题 C# WebRequest.Create 锚点“#”字符问题 根据内容来产生一个二维码

    详解C#泛型(二)   一.自定义泛型方法(Generic Method),将类型参数用作参数列表或返回值的类型: void MyFunc<T>() //声明具有一个类型参数的泛型方法 { ...

  2. 一次接口压力测试qps极低原因分析及解决过程

    一次接口压力测试qps极低原因分析及解决过程 9-2日在做内部的性能测试相关培训时,发现注册接口压力测试qps极低(20左右),这个性能指标远不能达到上线标准 ,经过一系列调试,最后定位 98%的时间 ...

  3. 记一次.net core调用SOAP接口遇到的问题

    背景        最近需要将一些外部的Web Service及其他SOAP接口的调用移到一个独立的WebAPI项目中,然后供其他.Net Core项目调用.之前的几个Web Service已经成功迁 ...

  4. 探索 dotnet core 为何在 Windows7 系统需要补丁的原因

    在一些 Windows 7 系统上,根据 dotnet 官方文档,需要安装上 KB2533623 补丁,才能运行 dotnet core 或 .NET 5 等应用.尽管非所有的设备都需要安装此,但这也 ...

  5. dotnet core开源博客系统XBlog介绍

    XBlog是dotnet core平台下的个人博客开源系统,它只需要通过Copy的方式即可以部署到Linux和windows系统中:如果你有安全证书那只需要简单配置一下即可提供安全的Https服务.接 ...

  6. dotnet core 调用electron来开发UI的探索

    先上仓库地址 https://github.com/lightszero/webwindow.netcore dotnet core 很喜欢,问题dotnet core 不包含GUI,经过一些尝试,觉 ...

  7. 调用支付宝接口Android客户端没有支付宝APP的情况下解决无法调用支付宝页面的问题

    这几天一直研究支付宝接口调用,因为当前应用中需要调用支付宝接口作移动支付. 遇到一个问题困扰几天,就是当我们的手机端未安装支付宝APP的时候,需要在自己应用中调用支付宝的登陆网页进行支付.我是Andr ...

  8. DotNet Core 2.2 MVC Razor 页面编译为 View.dll 文件的解决方法

    使用文本文件编辑器打开项目文件,找到: <PropertyGroup>     <TargetFramework>netcoreapp2.0</TargetFramewo ...

  9. 64位系统web项目导出excel问题分析及解决方法汇总

    最近在web项目中做了一个导出Excel功能.在导出的时候报错:检索 COM 类工厂中 CLSID 为 {00024500-0000-0000-C000-000000000046} 的组件时失败. 一 ...

随机推荐

  1. PKUSC2015总结

    突然发现这是自己第100篇博客...写下总结庆祝一下好啦 首先就是..D类狗果真没人权啊啊啊.考的辛辛苦苦结果因为D类拿不到一个好协议真的是哭瞎辣QAQ 然后就是..自己真的是太弱啊啊啊..各种傻逼题 ...

  2. 开源OSS.Social微信项目进阶介绍

    在开源OSS.Social微信项目解析的随笔中,我简单给大家分享了进行中微信项目的概要设计,主要在讲述解决思路和过程,没有详细实现和使用介绍.本着不能马虎的态度,这篇文章我来给大家分解一下项目结构,使 ...

  3. VUE2.0实现购物车和地址选配功能学习第五节

    第五节 单件商品金额计算和单选全选功能 1.vue精髓在于操作data模型来改变dom,渲染页面,而不是直接去改变dom 2.加减改变总金额功能: html:<div class="c ...

  4. windows container (docker) 容器资料笔记

    背景 业务需求:简化公司私有云,公有云的部署,尝试寻找更好的,更优化的技术方案替换现有的虚拟机部署方案. 技术背景: .net Docker 学习资料 Docker中文社区: http://www.d ...

  5. Vuex 学习总结

    好在之前接触过 flux,对于理解 vuex 还是很有帮助的.react 学到一半,后来因为太忙,就放弃了,现在也差不多都忘记了.不过感觉 vuex 还是跟 flux 还是有点区别的. 对于很多新手来 ...

  6. ELK日志套件安装与使用

    1.ELK介绍     ELK不是一款软件,而是elasticsearch+Logstash+kibana三款开源软件组合而成的日志收集处理套件,堪称神器.其中Logstash负责日志收集,elast ...

  7. Java面试02|Java集合

    关于Java中并发集合有: (1)CouncurrentHashMap (2)CopyOnWriteArrayList (3)LinkedBlockingQueue (4)ArrayBlockingQ ...

  8. KoaHub平台基于Node.js开发的Koa的连接MongoDB插件代码详情

    koa-mongo MongoDB middleware for koa, support connection pool. koa-mongo koa-mongo is a mongodb midd ...

  9. Git-多人协作

    声明: 此文参考廖雪峰老师的官方网站知识总结http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017 ...

  10. 菜鸟笔记:node.js+mysql中将JSON数据构建为树(递归制作树状菜单数据接口)

    初学Web端开发,今天是第一次将所学做随笔记录,肯定存在多处欠妥,望大家海涵:若有不足,望大家批评指正. 进实验室后分配到的第一个项目,需要制作一个不确定层级树形菜单的数据接口,对于从来没实战编过程的 ...