Poor Performance using IHttpClientFactory with SocketsHttpHandler with Machine Name #38464
Labels
area-System.Net.Http
backlog-cleanup-candidate
An inactive issue that has been marked for automated closure.
no-recent-activity
Milestone
I have an application that uses the IHttpClientFactory pattern. When I use a machine name for the host name and a new connection needs to be created, I was experiencing response times at around 4 seconds.
When I would make subsequent calls, after there was already an active connection to the host machine on the given port, my response times were very fast, around 30 ms.
It looked like SocketsHttpHandler end up looping over every IPAddress returned by Dns.GetHostAddresses. When failing to connect to an IP, there would be about a 1 second delay.
The easiest way I was able to reproduce this was as follows. First, when I called Dns.GetHostAddresses myself, I noticed that I had 6 IPAddresses returned and the first three were IPv6 addresses. My Kestrel listener at the time was only binding to IPv4 addresses by using .UseUrls($"0.0.0.0:{port}". So, I assumed that when the connection attempt was being made, it would start with the first IPv6 address, fail, go to the next, and so on. Once it reached the first IPv4 address, which was the 4th attempt, the connection was successful. When I changed Kestrel to bind to IPv6 and IPv4 addresses, the issue disappeared since its first attempt to connect using an IPv6 address was successful.
The issue also does not occur when I use an IP address, only when I use machine name.
I have resorted to calling Dns.GetHostAddresses myself, storing the result in a Dictionary with the host name as the key, and then looping over those values and sending the IP as the host instead of the machine name. Then if a particular IP fails, I can remove it from the array so that subsequent HttpClient requests use the IP that I know works instead of trying the same ones over and over again every time a new connection is needed even though they've failed before. And to prevent issues with DNS changes, any time I need to loop over the IPs, I call Dns.GetHostAddresses first to see if they changed. Something similar should be baked into the framework so that I don't need such an extensive workaround.
The text was updated successfully, but these errors were encountered: