向SAP端点批量提交JSON时最后一个请求超时的代码优化咨询
问题分析与解决方案
一、代码层面的优化方向
你当前的代码存在几个可以优化的点,这些调整能直接解决或缓解超时问题,同时覆盖速率限制场景:
1. 复用HttpClient实例
每次创建新的HttpClient会导致TCP连接无法复用,快速批量请求时容易耗尽连接池,进而引发超时。正确的做法是将HttpClient注册为单例(比如通过依赖注入容器配置为Singleton),或者使用静态实例复用:
// 示例:在DI容器中注册单例HttpClient services.AddSingleton<HttpClient>(sp => { var client = new HttpClient(); client.Timeout = TimeSpan.FromMinutes(5); return client; });
之后在你的函数中通过构造函数注入HttpClient,而非每次创建新实例。
2. 扩展重试策略,覆盖超时与异常场景
现有重试仅处理InternalServerError(500),但超时会抛出TaskCanceledException(需区分用户主动取消和超时:超时的InnerException为TimeoutException),同时还要覆盖返回200但实际请求失败的异常场景。修改后的重试策略如下:
var retryPolicy = Policy .Handle<HttpRequestException>() .Handle<TaskCanceledException>(ex => ex.InnerException is TimeoutException) // 仅处理超时导致的任务取消 .HandleResult<HttpResponseMessage>(r => r.StatusCode == HttpStatusCode.InternalServerError || (r.StatusCode == HttpStatusCode.OK && /* 可根据实际情况检查响应内容是否异常,比如包含错误信息 */ false)) .WaitAndRetryAsync(3, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt))); // 指数退避,避免频繁重试触发限流
3. 增加批量请求间隔(应对速率限制)
如果怀疑是SAP端的速率限制,可在批量提交的循环中加入固定延迟,降低请求频率:
// 假设你通过循环调用InvokePostAsync,在每次调用后添加延迟 foreach (var ledgerItem in ledgerList) { await InvokePostAsync(ledgerItem.JsonString, ledgerItem.ClientId, ledgerItem.FileName); await Task.Delay(TimeSpan.FromSeconds(1.5)); // 调整间隔时间,避免触发速率阈值 }
4. 修正超时场景的状态码处理
超时抛出异常时,初始的response对象可能未被赋值,需在catch块中单独处理超时场景,返回正确的状态码(如408 Request Timeout):
catch (TaskCanceledException ex) when (ex.InnerException is TimeoutException) { responseTime = DateTime.Now.ToString(); _logger.LogError($"Request timed out for client: {clientId} Exception: {ex.Message}"); return await createEmailMessageforClient(false, clientId, submissionTime, responseTime, fileName, ex.Message, 408); } catch (Exception ex) { responseTime = DateTime.Now.ToString(); _logger.LogError($"Error while posting web service for client: {clientId} Exception: {ex.Message}"); var statusCode = (int)(response?.StatusCode ?? HttpStatusCode.BadRequest); return await createEmailMessageforClient(false, clientId, submissionTime, responseTime, fileName, ex.Message, statusCode); }
二、SAP端点配置层面的可能处理
如果上述代码优化后仍出现超时问题,大概率是SAP端的限制导致:
- 确认SAP端点是否设置了请求频率限制(如每分钟最大请求数、并发连接数)
- 检查SAP服务器在接收最后一个请求时是否存在负载过高、资源耗尽的情况
- 联系SAP管理员,确认是否需要调整端点的超时时间、连接池配置或放宽速率限制
内容的提问来源于stack exchange,提问作者BigChungus
相关产品推荐
相关产品推荐

