.net 核心 Web 应用程序因“提供给函数的缓冲区太小”错误而失败
Posted
技术标签:
【中文标题】.net 核心 Web 应用程序因“提供给函数的缓冲区太小”错误而失败【英文标题】:.netcore web application failing with 'buffer supplied to a function was too small' error 【发布时间】:2019-02-20 16:53:09 【问题描述】:我有一个正在运行的 Web 应用程序,它基本上调用 3 个非常基本的 API,它们从第 3 方检索数据,将其保存在 json 文件中并加载此数据以进行进一步处理。
起初,Web 应用程序运行良好,但随着时间的推移,我开始注意到间歇性发生以下错误:
System.Net.Http.HttpRequestException:无法建立 SSL 连接,请参阅内部异常。 ---> System.Security.Authentication.AuthenticationException:身份验证 失败,请参阅内部异常。 ---> System.ComponentModel.Win32Exception:提供给 函数太小---内部异常堆栈跟踪结束---在 System.Net.Security.SslState.StartSendAuthResetSignal(协议令牌 消息,AsyncProtocolRequest asyncRequest,ExceptionDispatchInfo 例外)在 System.Net.Security.SslState.CheckCompletionBeforeNextReceive(协议令牌 消息,AsyncProtocolRequest asyncRequest)在 System.Net.Security.SslState.StartSendBlob(字节 [] 传入,Int32 计数,AsyncProtocolRequest asyncRequest)在 System.Net.Security.SslState.ProcessReceivedBlob(字节 [] 缓冲区,Int32 计数,AsyncProtocolRequest asyncRequest)在 System.Net.Security.SslState.StartReadFrame(字节 [] 缓冲区,Int32 readBytes,AsyncProtocolRequest asyncRequest)在 System.Net.Security.SslState.StartReceiveBlob(字节 [] 缓冲区, AsyncProtocolRequest asyncRequest) 在 System.Net.Security.SslState.CheckCompletionBeforeNextReceive(协议令牌 消息,AsyncProtocolRequest asyncRequest)在 System.Net.Security.SslState.StartSendBlob(字节 [] 传入,Int32 计数,AsyncProtocolRequest asyncRequest)在 System.Net.Security.SslState.ProcessReceivedBlob(字节 [] 缓冲区,Int32 计数,AsyncProtocolRequest asyncRequest)在 System.Net.Security.SslState.StartReadFrame(字节 [] 缓冲区,Int32 readBytes,AsyncProtocolRequest asyncRequest)在 System.Net.Security.SslState.StartReceiveBlob(字节 [] 缓冲区, AsyncProtocolRequest asyncRequest) 在 System.Net.Security.SslState.CheckCompletionBeforeNextReceive(协议令牌 消息,AsyncProtocolRequest asyncRequest)在 System.Net.Security.SslState.StartSendBlob(字节 [] 传入,Int32 计数,AsyncProtocolRequest asyncRequest)在 System.Net.Security.SslState.ProcessReceivedBlob(字节 [] 缓冲区,Int32 计数,AsyncProtocolRequest asyncRequest)在 System.Net.Security.SslState.StartReadFrame(字节 [] 缓冲区,Int32 readBytes,AsyncProtocolRequest asyncRequest)在 System.Net.Security.SslState.StartReceiveBlob(字节 [] 缓冲区, AsyncProtocolRequest asyncRequest) 在 System.Net.Security.SslState.CheckCompletionBeforeNextReceive(协议令牌 消息,AsyncProtocolRequest asyncRequest)在 System.Net.Security.SslState.StartSendBlob(字节 [] 传入,Int32 计数,AsyncProtocolRequest asyncRequest)在 System.Net.Security.SslState.ProcessReceivedBlob(字节 [] 缓冲区,Int32 计数,AsyncProtocolRequest asyncRequest)在 System.Net.Security.SslState.StartReadFrame(字节 [] 缓冲区,Int32 readBytes,AsyncProtocolRequest asyncRequest)在 System.Net.Security.SslState.PartialFrameCallback(AsyncProtocolRequest asyncRequest) --- 从上一个位置结束堆栈跟踪,其中 抛出异常---在 System.Net.Security.SslState.ThrowIfExceptional() 在 System.Net.Security.SslState.InternalEndProcessAuthentication(LazyAsyncResult 懒惰的结果)在 System.Net.Security.SslState.EndProcessAuthentication(IAsyncResult 结果)在 System.Net.Security.SslStream.EndAuthenticateAsClient(IAsyncResult asyncResult) 在 System.Net.Security.SslStream.c.b__47_1(IAsyncResult iar)在 System.Threading.Tasks.TaskFactory
1.FromAsyncCoreLogic(IAsyncResult iar, Func
2 endFunction, Action1 endAction, Task
1 promise, Boolean requiresSynchronization) --- 从前一个位置结束堆栈跟踪 抛出异常的地方---在 System.Net.Http.ConnectHelper.EstablishSslConnectionAsyncCore(流 流,SslClientAuthenticationOptions sslOptions,CancellationToken cancelToken) --- 内部异常堆栈跟踪结束 --- at System.Net.Http.ConnectHelper.EstablishSslConnectionAsyncCore(流 流,SslClientAuthenticationOptions sslOptions,CancellationToken cancelToken) 在 System.Threading.Tasks.ValueTask1.get_Result() at System.Net.Http.HttpConnectionPool.CreateConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken) at System.Threading.Tasks.ValueTask
1.get_Result() 在 System.Net.Http.HttpConnectionPool.WaitForCreatedConnectionAsync(ValueTask1 creationTask) at System.Threading.Tasks.ValueTask
1.get_Result() 在 System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancelToken) 在 System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage 请求,CancellationToken 取消令牌)在 System.Net.Http.HttpClient.FinishSendAsyncUnbuffered(Task`1 sendTask, HttpRequestMessage 请求,CancellationTokenSource cts,布尔值 disposeCts) 在 System.Net.HttpWebRequest.SendRequest() 在 System.Net.HttpWebRequest.GetResponse()
我在互联网上到处搜索,但无法找到解决此问题的方法。我最近还将 .netcore sdk 版本更新为 2.1.105 和 Microsoft.NetCore.APP/Microsoft.ASPNetCore.All,因为我在某处读到该错误应该不那么频繁地发生。发生了完全相反的事情。
【问题讨论】:
如果这是一个 .NET 问题,您每次都会遇到错误。intermettently
表明这是一个网络问题。 保证网络故障,无论使用何种语言或平台。如果狗咬了你的网线,你会丢失数据包和连接,直到你的 WiFi 恢复正常。
当 HTTP 调用失败时,您唯一能做的就是重试它。必须编写服务器和客户端代码来处理重试。至少在客户端,您可以使用 Polly
之类的库在重试之前以不同的延迟自动重试。 Implement HTTP call retries with exponential backoff with IHttpClientFactory and Polly policies 展示了 HttpClient 和 Polly 如何在出现错误时合作重试
不仅仅是网络错误。也许服务器崩溃了,你必须连接到另一个?也许服务器限制了你?也许某项服务已关闭,因此您需要使用替代方案? Polly 使用各种策略来处理不同的场景。
【参考方案1】:
我之前也遇到过这个问题。在挖掘了 GitHub 问题和各种复制后,看起来它可能是由于网络不稳定导致的格式错误的 TLS 数据包引起的。由于这是一个框架问题,您所能做的就是尝试捕获错误并重试,并希望有一天能修复它。
【讨论】:
你写的是网络问题。该框架无法修复损坏的数据包。唯一的解决方案是尝试重新连接。重试是 Polly 等弹性库的工作以上是关于.net 核心 Web 应用程序因“提供给函数的缓冲区太小”错误而失败的主要内容,如果未能解决你的问题,请参考以下文章
通过 Internet 公开我的 asp.net 核心 Web 应用程序
接受 List<CustomObject> 的 ASP.NET Web 方法因“Web 服务方法名称无效”而失败。
在 .net 核心中,它具有用于 Web 应用程序项目部署的 Web.config 转换语法?
在 NET 5 asp.net 核心 Web 应用程序中为 Kestrel 启用 Windows 身份验证