public static async Task<string> HttpGetAsync(string baseUrl, string entityName, string entityNameSuffixQueryParamer)
{
    var requestUrl = $@"{baseUrl}{entityName}{entityNameSuffixQueryParamer}";
    var headerRetryAfter = 0;// header中包含的RetryAfter值

    // 配置重试机制
    var retryPolicy = Policy
        .Handle<Exception>()
        .WaitAndRetry(
            // 重试次数
            retryCount: 3,
            // 确定每次重试尝试需要等待的时长
            sleepDurationProvider: (retryAttempt) =>
            {
                if (headerRetryAfter == 0)
                {
                    // 重试间隔时间(秒) => 3^次数
                    return TimeSpan.FromSeconds(Math.Pow(3, retryAttempt));
                }
                else
                {
                    var retryAfter = TimeSpan.FromSeconds(headerRetryAfter);
                    headerRetryAfter = 0;
                    return retryAfter;
                }
            },
            // 每次重试时要执行的操作或函数
            onRetry: (exception, timeSpan, retryCount, context) =>
            {
                Console.WriteLine($"请求D365失败,第{retryCount}次重试,延迟{timeSpan.TotalSeconds}秒");
            }
        );

    return await retryPolicy.Execute(async () =>
    {
        // 获取授权信息
        var token = await GetToken();

        // 设置授权信息
        httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", token);

        // 发起Get请求
        var httpResponseMessage = await httpClient.GetAsync(requestUrl);

        // 读取响应正文
        var responseBody = await httpResponseMessage.Content.ReadAsStringAsync();

        // 200 - 299
        if (!httpResponseMessage.IsSuccessStatusCode)
        {
            // 看是否存在Retry-After的header(429 请求过多)
            // See https://learn.microsoft.com/power-apps/developer/data-platform/api-limits#retry-operations
            if (httpResponseMessage.Headers.Contains("Retry-After"))
            {
                headerRetryAfter = int.Parse(httpResponseMessage.Headers.GetValues("Retry-After").FirstOrDefault());
            }

            var exceptionObj = new
            {
                Msg = "请求D365失败",
                ChinaTime = DateTime.Now.FormatChinaTime(),
                RequestUrl = requestUrl,
                RequestToken = token,
                HttpResponseStatusCode = (int)httpResponseMessage.StatusCode,
                HttpResponseStatusCodeName = httpResponseMessage.StatusCode.ToString(),
                HttpResponseHeader = JsonConvert.SerializeObject(httpResponseMessage.Headers),
                HttpResponseBody = responseBody,
            };
            var exceptionString = JsonConvert.SerializeObject(exceptionObj, Formatting.Indented);
            throw new Exception(exceptionString);
        }

        // 记录日志
        var reqId = httpResponseMessage.Headers.GetValues("REQ_ID").FirstOrDefault();
        var logString = $@"EntityName: {entityName}, _REQ_ID: {reqId}";
        _logger.LogInformation(logString);

        // 返回响应正文
        return responseBody;
    });
}

标签: none

评论已关闭