• Server endpoint是host还是url
  • 发布于 2个月前
  • 582 热度
    0 评论

问题:

Server endpoint是host还是url,例如:https://www.duidaima.com/a/b.js是duidaima.com还是duidaima.com/a/b.js?

官方文档对 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;
结论
由上面的代码,我们可以得出如下结论:如果连接类型、服务器地址、服务器端口、代理(如果有)全部相同,则认为是同一终结点
用户评论