前言
官方文档对 HttpClientHandler.MaxConnectionsPerServer 属性有如下说明:
获取或设置使用 HttpClient 对象发出请求时允许的最大并发连接数(每个服务器终结点)。请注意,该限制针对每个服务器终结点,例如,值为 256 表示允许 256 个到 http://www.adatum.com/ 的并发连接,以及另外 256 个到 http://www.adventure-works.com/ 的并发连接。
有网友在交流群中询问,终结点到底指的啥,怎么判断是同一终结点?
让我们通过源码来看看吧!
源码分析
HttpClientHandler.MaxConnectionsPerServer
HttpClientHandler.MaxConnectionsPerServer 的实现代码如下:
public int MaxConnectionsPerServer
{
get => _underlyingHandler.MaxConnectionsPerServer;
set => _underlyingHandler.MaxConnectionsPerServer = value;
}
实际使用的是_underlyingHandler.MaxConnectionsPerServer
。而_underlyingHandler
是SocketsHttpHandler
类的实例:
using HttpHandlerType = System.Net.Http.SocketsHttpHandler;
private readonly HttpHandlerType _underlyingHandler;
SocketsHttpHandler.MaxConnectionsPerServer
SocketsHttpHandler.MaxConnectionsPerServer 的实现代码如下:
public int MaxConnectionsPerServer
{
get => _settings._maxConnectionsPerServer;
set
{
...
_settings._maxConnectionsPerServer = value;
}
}
实际使用的是_settings._maxConnectionsPerServer
。那么,谁在使用这个设置值呢?
HttpConnectionPool
我们定位到了HttpConnectionPool
的构造函数:
public HttpConnectionPool(HttpConnectionPoolManager poolManager, HttpConnectionKind kind, string? host, int port, string? sslHostName, Uri? proxyUri)
{
...
_maxHttp11Connections = Settings._maxConnectionsPerServer;
...
}
而HttpConnectionPool
的作用就是,提供到同一终结点的连接池。看来我们离真相越来越近了。
/// <summary>Provides a pool of connections to the same endpoint.</summary>
internal sealed class HttpConnectionPool : IDisposable
HttpConnectionPoolManager
HttpConnectionPool
的构造函数只在HttpConnectionPoolManager
类中被调用:
public ValueTask<HttpResponseMessage> SendAsyncCore(HttpRequestMessage request, Uri? proxyUri, bool async, bool doRequestAuth, bool isProxyConnect, CancellationToken cancellationToken)
{
HttpConnectionKey key = GetConnectionKey(request, proxyUri, isProxyConnect);
HttpConnectionPool? pool;
while (!_pools.TryGetValue(key, out pool))
{
pool = new HttpConnectionPool(this, key.Kind, key.Host, key.Port, key.SslHostName, key.ProxyUri);
可以看到,HttpConnectionPool
是从ConcurrentDictionary
_pools 中获取的,而key的值是HttpConnectionKey
类型。
HttpConnectionKey
而 HttpConnectionKey 是这样判断是否相等的:
public readonly HttpConnectionKind Kind;
public readonly string? Host;
public readonly int Port;
public readonly string? SslHostName; // null if not SSL
public readonly Uri? ProxyUri;
public readonly string Identity;
public bool Equals(HttpConnectionKey other) =>
Kind == other.Kind &&
Host == other.Host &&
Port == other.Port &&
ProxyUri == other.ProxyUri &&
SslHostName == other.SslHostName &&
Identity == other.Identity;
结论
由上面的代码,我们可以得出如下结论:
如果连接类型、服务器地址、服务器端口、代理(如果有)全部相同,则认为是同一终结点
添加微信号【MyIO666】,邀你加入技术交流群