如何使用HTTPCLIENT改善慢速DN?

发布于 2025-01-17 12:57:00 字数 838 浏览 4 评论 0原文

我有一个特定域的请求,该域需要很长时间才能完成:平均22秒。请求本身不会返回大量数据。

var httpClient = new HttpClient();  //instantiated at app start and reused 
var request = new HttpRequestMessage(HttpMethod.Get, "http://www.somedomain.com");
var result = await httpClient.SendAsync(request); //take a really long time

经过一些调试后,它似乎与DNS有关。如果我运行完全相同的请求,但用IP替换域名,则很快(< 200 ms)。

如果我第二次使用相同的httpclient实例运行请求,也很快。但是,如果我在超过一分钟后运行第二个请求,则又慢了(可能是因为连接在1分钟后自动关闭)。

有没有办法改善这一点? (例如:确保已解决的DNS条目将长时间保留)。另外,为什么使用httpclient时该域的DNS如此慢?如果我尝试使用Chrome访问该域,它将快速燃烧(即使在冲洗DNS和清除缓存之后)。使用在线服务对该域查找的DNS也非常快。报告的TTL为60分钟。


编辑:我尝试增加servicepointManager.dnsrefreshtimeout(默认设置为2分钟)。但这无济于事。

呼叫dns.gethostentry(“ Somedomain.com”)是瞬时的,并返回正确的IP。我不知道为什么使用httpclient请求太慢。

I have one request for a specific domain that take a really long time to complete : 22 seconds in average. The request itself does not return a lot of data.

var httpClient = new HttpClient();  //instantiated at app start and reused 
var request = new HttpRequestMessage(HttpMethod.Get, "http://www.somedomain.com");
var result = await httpClient.SendAsync(request); //take a really long time

After some debugging, it seems related to DNS. If I run the exact same request but replace domain name by IP, it's fast (< 200 ms).

It's also fast if I run the request a second time using same HttpClient instance. However, if I run that second request after more than one minute it's slow again (probably because connections are closed automatically after 1 minute).

Is there a way to improve this ? (eg: to make sure resolved DNS entries would stay in cache for a long period). Also why is DNS so slow for that domain when using HttpClient ? If I try to access that domain using Chrome it's blazing fast (even after flushing DNS and clearing cache). A DNS lookup of that domain using an online service is also very fast. Reported TTL is 60 minutes.


EDIT: I have tried to increase ServicePointManager.DnsRefreshTimeout (which is set by default to 2 minutes). But it does not help.

Calling Dns.GetHostEntry("somedomain.com") is instantaneous and return the right IP. I don't know why request with HttpClient are so slow.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

泪冰清 2025-01-24 12:57:00

我发现出了什么问题:速度慢的域在 DNS 记录中有一个 IPV6 地址。
这可以通过调用此函数来确认:

Dns.GetHostEntry("somedomain.com")

首先它尝试使用 IPV6 进行连接。最终,发生超时。然后它尝试 IPV4(并且它有效)。这解释了为什么它这么慢。目前我找到的解决方案是自己通过解析域名来强制IPV4:

var uri = new Uri("somedomain.com");
var builder = new UriBuilder(uri);
var addresses = await Dns.GetHostAddressesAsync(uri.Host);    
builder.Host = addresses
                 .First(x => x.AddressFamily == AddressFamily.InterNetwork) //IPV4 only
                 .ToString(); 
var request = new HttpRequestMessage(HttpMethod.Get, builder.Uri);
request.Host = uri.Host;

也许还有更好的方法。我无法使用 SocketsHttpHandler 因为我一直使用 .NET Framework 4.5

I found out what is wrong: the domain that is slow has an IPV6 address in the DNS records.
This can be confirmed by calling this function:

Dns.GetHostEntry("somedomain.com")

First it tries to connect using IPV6. Eventually, a timeout occurs. Then it tries IPV4 (and it works). This explains why it is so slow. The solution I have found so far is to force IPV4 by resolving the domain name myself:

var uri = new Uri("somedomain.com");
var builder = new UriBuilder(uri);
var addresses = await Dns.GetHostAddressesAsync(uri.Host);    
builder.Host = addresses
                 .First(x => x.AddressFamily == AddressFamily.InterNetwork) //IPV4 only
                 .ToString(); 
var request = new HttpRequestMessage(HttpMethod.Get, builder.Uri);
request.Host = uri.Host;

Maybe there is a better way. I can't use SocketsHttpHandler since i'm stuck with .NET Framework 4.5

摇划花蜜的午后 2025-01-24 12:57:00

此处使用 SocketsHttpHandler 和 HttpClient 的另一个工作解决方案:https://stackoverflow。 com/a/70475741/1529139

它在连接时使用 IPv4 over IPv6。

它为我完成了工作

An other working solution using SocketsHttpHandler and HttpClient here : https://stackoverflow.com/a/70475741/1529139

It uses IPv4 over IPv6 at connection time.

It did the job for me

无边思念无边月 2025-01-24 12:57:00

它不仅仅是缓存 DNS 查询。如果您为每个请求创建新的客户端,那么在每个请求之前都会进行 TCP 和 HTTP 握手——这会使您的单个请求变慢。这可能就是为什么使用“旧”代理的后续请求更快的原因——握手仅在第一个请求之前进行,而不是在第二个请求之前进行。

It's not only about caching DNS query. If you create new client for every request, then before every request both TCP and HTTP handshakes are made -- which makes your single request slow. This is probably the reason why subsequent requests with "old" agent are faster -- handshakes are only made before first request, but not before second one.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文