[英]ASP.NET Core HttpClient can't make HTTPS calls in container
[英]HttpClient is slow when called in an https context in Asp.Net Core
我有一台使用 Asp.Net Core 的服務器,但在使用 HTTPS 時遇到了延遲問題。 當只獲取幾張圖片時,每個請求大約需要 20 毫秒來處理。 但是,當我同時發出 125 個請求時,使用 HTTP 時它們會減慢到 30-80 毫秒(可接受),而使用 HTTPS 時會減慢到 130-850 毫秒(不可接受)。
我已經進行了一些調試,當我的服務器對 WMS 服務器進行 http 調用時會出現減速。
添加自定義套接字處理程序將延遲從 4000-6000 毫秒減少到當前的 130-850 毫秒,因此幫助很大,但延遲仍然有點多。
PS:服務器將做的不僅僅是代理查詢,所以我不能簡單地為該角色使用專用代理服務器。
這是服務器代碼的最小示例:
using System.Diagnostics.Tracing;
using Microsoft.AspNetCore.Mvc;
using System.Diagnostics;
using var socketHandler = new SocketsHttpHandler()
{
PooledConnectionIdleTimeout = TimeSpan.FromMinutes(10),
PooledConnectionLifetime = TimeSpan.FromMinutes(10),
MaxConnectionsPerServer = 1,
};
using var httpClient = new HttpClient(socketHandler);
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddSingleton(httpClient);
var app = builder.Build();
app.MapControllers();
app.Run();
[ApiController]
[Route("[controller]")]
public class WMSController : ControllerBase
{
private readonly HttpClient Client;
private readonly string BaseUrl;
public WMSController(HttpClient client)
{
Client = client;
BaseUrl = "http://my-local-hostname.company.internal:10301/WMS";
}
[HttpGet(Name = "WMS")]
public async Task<ActionResult> GetWms()
{
var query = HttpContext.Request.QueryString.Value;
var stopwatch = new Stopwatch();
stopwatch.Start();
var response = await Client.GetAsync(BaseUrl + query); // This is the slow part.
stopwatch.Stop();
Console.WriteLine($"{DateTime.Now:HH:mm:ss} - {stopwatch.ElapsedMilliseconds} - {HttpContext.Connection.Id}");
stopwatch.Reset();
var image = await response.Content.ReadAsByteArrayAsync();
return new FileContentResult(image, "image/jpeg");
}
}
您可以提高許多效率。
HttpClient
和處理程序,以便對同一服務器的請求可以多路復用。 這也可以防止套接字耗盡。static HttpClient httpClient = new HttpClient(new SocketsHttpHandler()
{
PooledConnectionIdleTimeout = TimeSpan.FromMinutes(10),
PooledConnectionLifetime = TimeSpan.FromMinutes(10),
});
HttpCompletionOption.ResponseHeadersRead
以便僅緩沖標頭,否則必須緩沖完整響應。[HttpGet(Name = "WMS")]
public async Task<ActionResult> GetWms()
{
var query = HttpContext.Request.QueryString.Value;
var stopwatch = Stopwatch.StartNew();
using var response = await Client.GetAsync(BaseUrl + query, HttpCompletionOption.ResponseHeadersRead);
stopwatch.Stop();
Console.WriteLine($"{DateTime.Now:HH:mm:ss} - {stopwatch.ElapsedMilliseconds} - {HttpContext.Connection.Id}");
stopwatch.Reset();
var image = await response.Content.ReadAsByteArrayAsync();
return new FileContentResult(image, "image/jpeg");
}
FileStreamResult
[HttpGet(Name = "WMS")]
public async Task<ActionResult> GetWms()
{
var query = HttpContext.Request.QueryString.Value;
var stopwatch = Stopwatch.StartNew();
// NO using, otherwise stream gets disposed
var response = await Client.GetAsync(BaseUrl + query, HttpCompletionOption.ResponseHeadersRead);
stopwatch.Stop();
Console.WriteLine($"{DateTime.Now:HH:mm:ss} - {stopwatch.ElapsedMilliseconds} - {HttpContext.Connection.Id}");
stopwatch.Reset();
var image = await response.Content.ReadAsStreamAsync();
return new FileStreamResult(image, "image/jpeg");
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.