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信息了,两类请求在高并发场景下也能互不干扰。

  • 相关阅读:
    Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessApiUsageException: Multiple representations of the same entity解决方法
    基于注释配置bean和装饰bean
    Oracle 11g+oracle客户端(32位)+PL/SQL develepment的安装配置
    SpringData JPA的学习笔记之环境搭建
    Maven+struts2+spring4+hibernate4的环境搭建
    springmvc集成Ueditor插件实现图片上传2、
    c博客作业函数
    C语言博客作业2循环结构
    C语言第0份作业
    c博客作业分支、顺序结构
  • 原文地址:https://www.cnblogs.com/rampb/p/10169216.html
Copyright © 2011-2022 走看看