zoukankan      html  css  js  c++  java
  • 使用HttpClient请求,问题记录

    上篇博客说到使用单例HttpClient,以GET请求方法为例。可以看到对于Http请求头中Authorization参数,会根据传入的accessToken是否为空来判断是否添加此请求头。

            public async Task<HttpResponseMessage> GetRequestAsync(string requestUri, string accessToken)
            {
                HttpRequestMessage message = new HttpRequestMessage(HttpMethod.Get, requestUri);
                if (!string.IsNullOrEmpty(accessToken))
                {
                    message.Headers.Add("Authorization", "Bearer " + accessToken);
                }
                try
                {
                    var response = await _httpClient.SendAsync(message);
                    //var response = await this._client.GetAsync(requestUri);
                    if (response.IsSuccessStatusCode)
                    {
                        return response;
                    }
                    else
                    {
                        throw new Exception(response.Content.ReadAsStringAsync().Result);
                    }
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            }

    假设现在有两类请求,一类accessToken有值,一类accessToken值为null。那么在高并发请求中(两类请求都有),经常会曝出如下异常信息。

    <error xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
    <code>AuthenticationFailed</code>
    <message xml:lang="en-US">Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
    RequestId:6c793977-1002-0001-25dc-9ace78000000
    Time:2018-12-23T16:24:40.3625699Z</message>
    </error>

    之前一直以为是并行代码有问题,因为使用串行代码执行是能正常运行的。后来测试的时候对并行请求那块代码加lock锁,同样会报这个错误。那么说明并行代码应该是没问题的。

    因为报这个错误的请求都是accessToken为null的这类请求。而这类请求由于做了判断,请求头中并不应该有Authorization参数,而异常信息却说我的Authorization格式不正确,那么

    似乎是accessToken为null的这类请求的请求头中有key为Authorization的请求头,只是value值不正确,但这类请求是不应该有key为Authorization的请求头的。

    后来看到这篇文档(https://mitra.computa.asia/articles/msdn-azure-batch-server-failed-authenticate-request),发现是因为客户端的代理层(proxy layer)会缓存请求信息。也就是说在高并发请求中,带Authorization请求头的请求会缓存下来(而我猜测这因为有一个很短的过期时间,不然就无法解释串行请求是正常的),当切换到不应该带Authorization请求头的请求时(因为Authorization请求头的值为空),就会出现此异常。所以我们需要将Proxy禁用掉就可以的。

    //创建HttpClient对象时,禁用Proxy
    HttpClientHandler handler = new HttpClientHandler()
    {
           UseProxy = false
    };
    _httpClient = new HttpClient(handler);

    或者也可以使用如下方式禁用客户端Proxy

      <system.net>
        <requestCaching defaultPolicyLevel="NoCacheNoStore"/>
      </system.net>

    这样客户端Proxy就不会缓存Http信息了,两类请求在高并发场景下也能互不干扰。

  • 相关阅读:
    bzoj 1017 魔兽地图DotR
    poj 1322 chocolate
    bzoj 1045 糖果传递
    poj 3067 japan
    timus 1109 Conference(二分图匹配)
    URAL 1205 By the Underground or by Foot?(SPFA)
    URAL 1242 Werewolf(DFS)
    timus 1033 Labyrinth(BFS)
    URAL 1208 Legendary Teams Contest(DFS)
    URAL 1930 Ivan's Car(BFS)
  • 原文地址:https://www.cnblogs.com/rampb/p/10169216.html
Copyright © 2011-2022 走看看