首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >HttpClient与ASP.NET Core2.0webservice之间的连接是关闭的错误

HttpClient与ASP.NET Core2.0webservice之间的连接是关闭的错误
EN

Stack Overflow用户
提问于 2017-10-05 03:42:48
回答 1查看 10K关注 0票数 9

我在ASP.NET上运行了一个IISCore2.0webservice。控制器的方法之一大致如下所示:

代码语言:javascript
运行
AI代码解释
复制
[HttpGet()]
public IActionResult Test()
{
    // do some db updates and get data
    var result = DoSomeStuff();
    // serialize data to byte array
    var output = Serialize(result);

    return File(output, "application/octet-stream");
}

它执行一些数据库更新、从表中查询记录、序列化数据并将其作为响应发送。数据以二进制格式发送。我使用MessagePack-CSharp作为序列化程序。

然后,我有客户端应用程序与此with服务进行通信。它是.NET标准2.0库,它从.NET 4.6.1控制台应用程序中引用。我使用HttpClient来请求和HttpResponseMessage.Content.ReadAsByteArrayAsync()来读取响应(确切的代码见下面)。

我想做些测试。我的桌子上有cca。80列,包含cca。140000张唱片。所有这些都应该发送给客户。从db获取数据只需几秒钟,那么它就是所有的序列化和cca的结果。34 is被发送到客户端。

我有10个客户。当他们连续调用webservice时,一切都正常。当我强调webservice并并行解雇客户端时,我几乎总是会得到其中一些错误(通常是一个或两个失败,有时甚至是4-5)。

异常如下,它是从ReadAsByteArrayAsync调用引发的:

代码语言:javascript
运行
AI代码解释
复制
System.AggregateException: One or more errors occurred. ---> System.Net.Http.HttpRequestException: Error while copying content to a stream. ---> System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host. ---> System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host
   at System.Net.Sockets.Socket.EndReceive(IAsyncResult asyncResult)
   at System.Net.Sockets.NetworkStream.EndRead(IAsyncResult asyncResult)
   --- End of inner exception stack trace ---
   at System.Net.ConnectStream.EndRead(IAsyncResult asyncResult)
   at System.IO.Stream.<>c.<BeginEndReadAsync>b__43_1(Stream stream, IAsyncResult asyncResult)
   at System.Threading.Tasks.TaskFactory`1.FromAsyncTrimPromise`1.Complete(TInstance thisRef, Func`3 endMethod, IAsyncResult asyncResult, Boolean requiresSynchronization)
...
---> (Inner Exception #0) System.Net.Http.HttpRequestException: Error while copying content to a stream. ---> System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host. ---> System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host
   at System.Net.Sockets.Socket.EndReceive(IAsyncResult asyncResult)
   at System.Net.Sockets.NetworkStream.EndRead(IAsyncResult asyncResult)
   --- End of inner exception stack trace ---
   at System.Net.ConnectStream.EndRead(IAsyncResult asyncResult)
   at System.IO.Stream.<>c.<BeginEndReadAsync>b__43_1(Stream stream, IAsyncResult asyncResult)
   at System.Threading.Tasks.TaskFactory`1.FromAsyncTrimPromise`1.Complete(TInstance thisRef, Func`3 endMethod, IAsyncResult asyncResult, Boolean requiresSynchronization)
...

我发现了几个与这种异常相关的线程(例如这里),所以我最初认为这是一个与客户端相关的问题。答复建议:

  • 切换到HTTP1.0
  • 设置Connection: close而不是Connection: keep-alive
  • 反之亦然

对我没什么用。我想我在某个地方读到了HttpClient中有一些bug (现在找不到源代码)。我试着使用来自Nuget的最新System.Net.Http软件包。同样的问题。我创建了.NET核心控制台应用程序,并使用了HttpClient的核心版本。同样的问题。我用的是HttpWebRequest而不是HttpClient。同样的潜在问题。

我在同一台VM机器上运行webservice和客户端。为了排除一些本地问题,我从其他计算机同时运行客户端。同样的问题。

因此,我得到了以下简化代码(只有一个有10个线程的应用程序):

代码语言:javascript
运行
AI代码解释
复制
private async void Test_Click(object sender, RoutedEventArgs e)
{
    try
    {
        var tasks = Enumerable.Range(1, 10).Select(async i => await Task.Run(async () => await GetContent(i))).ToList();

        await Task.WhenAll(tasks);

        MessageBox.Show(String.Join(Environment.NewLine, tasks.Select(t => t.Result.ToString())));
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.ToString());
    }
}

private async Task<Int32> GetContent(Int32 id)
{
    using (var httpClient = new HttpClient())
    {
        var url = "http://localhost/TestService/api/test";

        using (var responseMessage = await httpClient.GetAsync(url).ConfigureAwait(false))
        {
            // just read everything and return length
            // ReadAsByteArrayAsync throws sometimes an exception
            var content = await responseMessage.Content.ReadAsByteArrayAsync();
            return content.Length;
        }
    }
}

我对实际的流量很好奇,所以我设置了费德勒。当错误发生时,Fiddler显示响应确实已损坏,并且实际上只发送了一部分假定的数据量(6MB,20 6MB,.而不是34 of )。好像是随机中断的。我和Wireshark玩了一段时间,我看到RST/ACK数据包是从服务器发送的,但是我对这种低级别通信的分析还不够好。

所以,我专注于服务器端。当然,我再次检查了控制器方法中是否有异常。一切都很好。我将日志级别设置为跟踪,并在日志中找到以下内容:

代码语言:javascript
运行
AI代码解释
复制
info: Microsoft.AspNetCore.Server.Kestrel[28]
      Connection id "0HL89D9NUNEOQ", Request id "0HL89D9NUNEOQ:00000001": the connection was closed becuase the response was not read by the client at the specified minimum data rate.
dbug: Microsoft.AspNetCore.Server.Kestrel[10]
      Connection id "0HL89D9NUNEOQ" disconnecting.
...
info: Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv[14]
      Connection id "0HL89D9NUNEOQ" communication error.
Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.Internal.Networking.UvException: Error -4081 ECANCELED operation canceled

我没有发现任何有趣的东西,而且ASP.NET核心与这个错误有关。根据这份文件,IIS在向客户端发送响应时可以选择指定最低吞吐量,设置如下:

代码语言:javascript
运行
AI代码解释
复制
<system.applicationHost>
  <webLimits minBytesPerSecond="0"/>
</system.applicationHost>

我在我的Web.config中使用它,但它没有效果(它是应用于ASP.NET核心应用程序,还是只设置完整的框架?)

我试图返回FileStreamResult而不是FileContentResult,但是--这并没有帮助。

与客户端类似,我也试图为服务器端找到最小的可重复代码。方法只有Thread.Sleep(8000) (而不是db调用),然后生成随机的50 db字节数组并返回它。这没什么问题,所以我想我会继续朝这个方向调查。我知道db可能是这里的瓶颈,但不确定它如何导致这种情况(没有超时异常,没有死锁,.)。

有什么建议吗?我至少想知道这是服务器问题还是真正与客户有关的问题。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-10-05 03:58:14

看起来,您的吞吐量低于最低数据速率。此行为在Kestrel基本面中描述。

Kestrel每秒钟检查一次数据是否以字节/秒的指定速率输入。如果速率低于最小值,则连接将超时。宽限期是Kestrel给予客户将其发送速率提高到最低限度的时间;在此期间不检查该费率。宽限期有助于避免由于TCP慢启动而导致最初以慢速率发送数据的连接中断。 默认的最小速率为240字节/秒,宽限期为5秒。 最低费率也适用于答复。设置请求限制和响应限制的代码是相同的,除非在属性和接口名称中有RequestBodyResponse

您可以在Program.cs中像这样配置它:

代码语言:javascript
运行
AI代码解释
复制
var host = new WebHostBuilder() 
    .UseKestrel(options => 
    { 
        options.Limits.MinResponseDataRate = null;
    })

将此选项设置为null表示不应强制执行最低数据速率。

票数 13
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46584760

复制
相关文章
WebClient, HttpClient, HttpWebRequest ,RestSharp之间的区别与抉择
NETCore提供了三种不同类型用于生产的REST API: HttpWebRequest;WebClient;HttpClient,开源社区创建了另一个名为RestSharp的库。如此多的http库,该怎样选择呢?
leon公众号精选
2022/04/27
1.3K0
Http 持久连接与 HttpClient 连接池
HTTP协议是无状态的协议,即每一次请求都是互相独立的。因此它的最初实现是,每一个http请求都会打开一个tcp socket连接,当交互完毕后会关闭这个连接。
用户1257393
2018/07/30
2.1K0
Http 持久连接与 HttpClient 连接池
HttpClient(二)HttpClient使用Ip代理与处理连接超时
前言   其实前面写的那一点点东西都是轻轻点水,其实HttpClient还有很多强大的功能:   (1)实现了所有 HTTP 的方法(GET,POST,PUT,HEAD 等)   (2)支持自动转向   (3)支持 HTTPS 协议   (4)支持代理服务器等 一、HttpClient使用代理IP 1.1、前言   在爬取网页的时候,有的目标站点有反爬虫机制,对于频繁访问站点以及规则性访问站点的行为,会采集屏蔽IP措施。   这时候,代理IP就派上用场了。可以使用代理IP,屏蔽一个就换一个IP。   关于代
用户1195962
2018/01/18
2.6K0
Http 持久连接与 HttpClient 连接池
HTTP 协议是无状态的协议,即每一次请求都是互相独立的。因此它的最初实现是,每一个 http 请求都会打开一个 tcp socket 连接,当交互完毕后会关闭这个连接。
业余草
2021/12/06
1.8K0
Http 持久连接与 HttpClient 连接池
ASP.NET Core 2.1 : 十三.httpClient.GetAsync 报SSL错误的问题
不知什么时候 ,出现了这样的一个奇怪问题,简单的httpClient.GetAsync("xxxx")居然报错了。
FlyLolo
2018/08/20
1.1K0
HttpComponents HttpClient连接池(2)-连接的申请
在上一篇文章里我们主要介绍了 httpclient 连接池的关键类和数据结构,在这里我们主要介绍http连接的申请和释放。
TA码字
2020/04/01
1.3K0
HttpComponents HttpClient连接池(3)-连接的释放
在上一篇文章里我们介绍了 httpclient 连接池中连接的申请,在这里我们主要介绍连接的和释放。
TA码字
2020/04/01
1.5K1
Asp.Net Core中HttpClient的使用方式
在.Net Core应用开发中,调用第三方接口也是常有的事情,HttpClient使用人数、使用频率算是最高的一种了,在.Net Core中,HttpClient的使用方式随着版本的升级也发生了一些变化,本次就讲解一下Asp.Net Core2.1前后使用的两种方式。
心莱科技雪雁
2019/03/11
1.2K0
Asp.Net Core中HttpClient的使用方式
HttpComponents HttpClient连接池(4)-连接的重用和KeepAlive
在上一篇文章里我们介绍了 httpclient 连接池中对于连接的申请和释放,这里我们主要介绍连接的重用,以及 keep alive。
TA码字
2020/04/01
3.4K0
Openresty主动关闭连接与KeepAlive Requests
01最近客户端(APP)换了新的网络库,几轮测试下来,功能和性能上都是正常的,只是网络库对应的日志里会有连接被关闭的提示,开始以为新的网络库踩到坑了,客户端的同学排查了几轮下来,过滤抓包发现是服务端发fin包主动关闭的连接,于是找到我说帮忙排查下。
糖果
2019/11/20
3.3K0
3 - 各种变量与值之间的多种连接方式
字符串与字符串之间连接 # 字符串与字符串之间连接的方式有5 种 ## 1:+(加号) s1 = 'hello' s2 = 'world' s = s1 + s2 print(s) helloworld helloworld 用逗号连接: hello world 格式化: <hello> <world> join连接: hello world ## 2: 直接连接 s = 'hello''world' print(s) helloworld ## 3: 用逗号(,)连接,标准输出的重定向 from io i
ruochen
2021/05/22
7380
3 - 各种变量与值之间的多种连接方式
asp.net core之HttpClient
本文介绍了ASP.NET Core中的HttpClient和HttpClientFactory的作用、用法以及最佳实践。通过示例代码的展示,读者可以了解如何使用HttpClient发送HTTP请求并处理响应,以及如何使用HttpClientFactory来解决HttpClient的一些问题,如资源泄漏和性能问题。同时,本文还强调了HttpClientFactory的优势,如更好的性能、资源管理和可配置性。通过深入理解和应用HttpClient和HttpClientFactory,开发人员可以更好地与外部服务进行通信。
饭勺oO
2023/10/18
4750
asp.net core之HttpClient
【说站】java中HttpClient的错误处理
1、HttpClient异步请求返回CompletableFuture,其自带的exceptionally方法可用于fallback处理。
很酷的站长
2022/11/23
1.1K0
【说站】java中HttpClient的错误处理
一场HttpClient调用未关闭流引发的问题
最近生产环境出现了一个问题,就是Job服务日志好端端的不打印日志了,服务也没有挂, 现在将此次问题解决过程记录下来~
石臻臻的杂货铺[同名公众号]
2021/07/14
3.6K0
解决httpclient因为保持永久长连接造成连接吊死的问题
httpclient使用了连接池,如果没有设置keep-alive策略,PoolingHttpClientConnectionManager会默认使用永久连接。
用户7043603
2022/02/25
3.5K0
进程、会话、连接之间的差异
--======================== -- 进程、会话、连接之间的差异 --========================     在使用Oracle database的时候,连接与会话是我们经常碰到的词语之一。咋一看貌似一回事,事实则不然。一个连接上可以建立零个、 一个、甚至多个会话。啊,咋这样呢?是的,没错。这也是我们经常误解的原因。     各个会话之间是单独的,独立于其他会话,即便是同一个连接的多个会话也是如此。 一、几个术语之间的定义(参照Oracle 9i &10g 编程艺术)         连接(connection):连接是从客户到Oracle 实例的一条物理路径。连接可以在网络上建立,或者通过IPC 机制建立。通常会在     客户进程与一个专用服务器或一个调度器之间建立连接。         会话(session):会话是实例中存在的一个逻辑实体。这就是你的会话状态(session state),也就是表示特定会话的一组内存     中的数据结构.提到"数据库连接"时,大多数人首先想到的就是“会话”。你要在服务器中的会话上执行SQL、提交事务和运行存储过程。 二、通过例子演示来查看之间的关系 1. 无连接,无会话,无进程的情形
Leshami
2018/08/14
2K0
HttpComponents HttpClient连接池(6)-连接清理
在上一篇文章里我们介绍了 httpclient 连接池中连接的可用性检查,在这里我们主要介绍空闲 http 连接的清理。对于连接池中的连接基本都是复用的,其中避免不了 server 端主动关闭连接,这个时候取出的连接自然是不可用的,当然可以通过上一篇文章中的可用性检查避免。但同时 httpclient 连接池也提供了 http 连接的清理策略,用来对连接进行清除。
TA码字
2020/04/01
3.3K0
理想与现实之间的差距是真实存在的
深夜,我成功被上面这张与现实毫无违和感的图片搞失眠了。在失眠之余我居然还从中悟出一个道理:理想与现实之间的差距是真实存在的,而且这个差距还可以拿来供人搞笑。
用户1272076
2020/03/26
6340
PHP中PDO关闭连接的问题
在之前我们手写 mysql 的连接操作时,一般都会使用 mysql_close() 来进行关闭数据库连接的操作。不过在现代化的开发中,一般使用框架都会让我们忽视了底层的这些封装,而且大部分框架都已经默认是使用 PDO 来进行数据库的操作,那么,大家知道 PDO 是如何关闭数据的连接的吗?
用户7353560
2021/11/07
2.8K0
HttpComponents HttpClient连接池(9)-长连接
在上一篇文章里我们介绍了 httpclient 连接池对于 SSL 的支持,这里主要介绍连接池中的长连接。
TA码字
2020/04/14
1.6K0
HttpComponents HttpClient连接池(9)-长连接

相似问题

连接与SqlTransaction是关闭错误

12

HttpClient关闭连接

118

httpClient连接未关闭

11

在HttpClient请求之间休眠长时间连接时关闭连接

24

HttpClient和连接:关闭HttpRequestHeaders

10
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
社区富文本编辑器全新改版!诚邀体验~
全新交互,全新视觉,新增快捷键、悬浮工具栏、高亮块等功能并同时优化现有功能,全面提升创作效率和体验
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文