我有一个公开 API 的 C# .NET 2.2 Web 服务器进程。当收到请求时,服务器需要向数据库 API 发出自己的 HTTP 请求。根据查询,来自数据库的响应可能非常大,在某些情况下,这大到足以让我的 .NET 进程崩溃并在日志中显示 (Memory quota exceeded)
。
发送请求的代码如下所示:
string endpoint_url = "<database service url>";
var request_body = new StringContent(query, Encoding.UTF8, "<content type>");
request_body.Headers.ContentType.CharSet = "";
try {
var request_task = Http.client.PostAsync(endpoint_url, request_body);
if (await Task.WhenAny(request_task, Task.Delay(timeoutSeconds*1000)) == request_task) {
request_task.Result.EnsureSuccessStatusCode();
var response = await request_task.Result.Content.ReadAsStringAsync();
JObject json_result = JObject.Parse(response);
if (json_result["errors"] is null) {
return json_result;
} else {
// return error
}
} else {
// return timeout error
}
} catch(Exception e) {
// return error
}
我的问题是,当查询返回像这样的大响应时,防止我的 Web 服务中断的最佳方法是什么? .NET Core best practices建议我不应该将响应主体加载到一个字符串中,但实际上并没有建议替代方案。
我想优雅地失败并向客户端返回错误,而不是导致 .NET 服务中断,因此对响应大小设置某种限制会起作用。不幸的是,有问题的数据库服务不返回 Content-Length
header ,所以我不能只检查它。
我的网络服务器目前有 512MB 的可用内存,我知道这并不多,但我担心无论我有多少可用内存,这个错误都可能发生在大量响应上。我主要关心的是保证无论来自数据库服务的响应大小如何,我的 .NET 服务都不会崩溃。
最佳答案
如果 Http.client
是一个 HttpClient,您可以限制它在中止操作之前读取的最大数据量,并使用它的 MaxResponseContentBufferSize
属性抛出异常。默认情况下,它设置为 2Gb,这解释了为什么如果您的服务器只有 512Mb 的 RAM,它就会消失,因此您可以将它设置为 10/20Mb 之类的值,并在它溢出时处理异常。
关于c# - 大型 HTTPResponseMessage 导致 .NET Core 服务器进程内存不足,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62193466/