将 HttpClient 与 NServiceBus 结合使用时出现严重延迟

Serious delay using HttpClient in combination with NServiceBus

我正在使用 NServiceBus 进行集成 POC。当发生某些事情时,此集成会向 API 发送通知。

一切正常,但在执行并发 http 请求时会出现严重的性能问题。

我配置了一个端点来做一件事:发送 json 请求(通知)到 REST API。

我的设置:

端点(框架 4.6.1)有 1 个静态 HttpClient,仅在程序启动时初始化一次:

internal static void Intitialize()
        {
            ServicePointManager.DefaultConnectionLimit = 100;
            var apiSettings = NotificationEngineManager.GetInterfaceSettings()?.API;
            NotificationClient = new HttpClient();
            NotificationClient.Timeout = TimeSpan.FromSeconds(45);
            if (!string.IsNullOrEmpty(apiSettings.UserName))
            {
                var byteArray = Encoding.ASCII.GetBytes($"{apiSettings.UserName}:{apiSettings.Password}");
                NotificationClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));
            }
        }

        internal static HttpClient NotificationClient { get; set; }

我的处理程序负责 post 请求:

   public async Task Handle(EventRegistered message, IMessageHandlerContext context)
            {
                var apiSettings = NotificationEngineManager.GetInterfaceSettings()?.API;
                if (apiSettings == null)
                {
                    throw new BusinessException("No valid API settings found");
                }

                JsonSerializerSettings settings = new JsonSerializerSettings();
                settings.NullValueHandling = NullValueHandling.Ignore;
                settings.DateFormatString = "s";
                settings.Converters.Add(new StringEnumConverter { });


                try
                {
                    var jsonRequest = JsonConvert.SerializeObject(message.Notification, settings);
                    var response = await HttpClients.NotificationClient.PostAsync(apiSettings.Endpoint, new StringContent(jsonRequest, Encoding.UTF8, "application/json"));
                    response.EnsureSuccessStatusCode();
                }
                catch (TaskCanceledException)
                {
                    throw new Exception("Notifiaction Request timed out.");
                }

                await context.Publish(new NotificationSent(message, DateTime.Now)).ConfigureAwait(false);

}

问题:

NServiceBus 端点同时处理 10 条消息,即同时处理 10 个 http post 请求。

Rest API 大约需要 0.2s 来响应 1 条消息。但是同时触发 10 个 http post 请求大约需要 35 秒。 请求全部同时开始,也全部同时结束,也就是大约35秒后。

使用 netstat 命令我可以看到 10 个打开的 tcp 连接到 API。所以 HttpClient 确实处理并发请求。

奇怪的是,如果我将我的端点并发设置为 1,意味着 1 对 1 处理 http 请求,所有 10 个请求都在 2 秒内处理。

如果我将端点并发级别设置为 20 或更高,几乎所有请求都会超时(超时 = 45 秒)。

可以使用 HttpWebRequest 而不是 HttpClient 重现相同内容。

I'm at a loss here. What do I miss? It looks like all the requests are waiting on each other, either on the client or the server. Any help is very much appreciated.

Rest API 是 ISS 上的基本 .NET Core API 运行。

// POST api/notification
        [HttpPost]
        [Authorize]
        public async Task<IActionResult> Post([FromBody] Notification notification)
        {
            try
            {
                return Accepted();
            }
            catch (Exception ex)
            {

                return BadRequest(ex);
            }

        }

更新: 客户端 (nservicebus) 和服务器端 (api) 都记录。 运行 在本地主机上处于调试模式并且很容易重现。

客户端

    log.Info($"Start request {message.Event.Id.ToString()}");
                    var response = await HttpClients.NotificationClient.PostAsync(apiSettings.Endpoint, new StringContent(jsonRequest, Encoding.UTF8, "application/json"));              
                    response.EnsureSuccessStatusCode();
                    log.Info($"Stop request {message.Event.Id.ToString()}");

2018-04-18 09:05:23.2886 INFO NOTIFY_WO_OUT 8 Start request
2018-04-18 09:05:23.2886 INFO NOTIFY_WO_OUT 10 Start request
2018-04-18 09:05:23.2886 INFO NOTIFY_WO_OUT 5 Start request
2018-04-18 09:05:23.2886 INFO NOTIFY_WO_OUT 2 Start request
2018-04-18 09:05:23.2886 INFO NOTIFY_WO_OUT 4 Start request
2018-04-18 09:05:23.6336 INFO NOTIFY_WO_OUT 6 Start request
2018-04-18 09:05:24.6329 INFO NOTIFY_WO_OUT 9 Start request
2018-04-18 09:05:25.6142 INFO NOTIFY_WO_OUT 1 Start request
2018-04-18 09:05:26.6544 INFO NOTIFY_WO_OUT 7 Start request
2018-04-18 09:05:27.6545 INFO NOTIFY_WO_OUT 3 Start request
2018-04-18 09:05:47.2034 INFO NOTIFY_WO_OUT 5 Stop request
2018-04-18 09:05:47.6285 INFO NOTIFY_WO_OUT 3 Stop request
2018-04-18 09:05:47.9855 INFO NOTIFY_WO_OUT 6 Stop request
2018-04-18 09:05:48.0550 INFO NOTIFY_WO_OUT 9 Stop request
2018-04-18 09:05:48.5226 INFO NOTIFY_WO_OUT 4 Stop request
2018-04-18 09:05:48.5526 INFO NOTIFY_WO_OUT 10 Stop request
2018-04-18 09:05:48.9987 INFO NOTIFY_WO_OUT 8 Stop request
2018-04-18 09:05:49.0347 INFO NOTIFY_WO_OUT 1 Stop request
2018-04-18 09:05:49.0647 INFO NOTIFY_WO_OUT 7 Stop request
2018-04-18 09:05:49.3017 INFO NOTIFY_WO_OUT 2 Stop request

服务器端日志记录。 日志记录中间件添加到管道的开头。

2018-04-18 09:05:38.7660 INFO Begin Request 6
2018-04-18 09:05:38.7850 INFO message 6 received
2018-04-18 09:05:38.8150 INFO End Request 6
2018-04-18 09:05:39.4036 INFO Begin Request 9
2018-04-18 09:05:39.4231 INFO message 9 received
2018-04-18 09:05:39.4551 INFO End Request 9
2018-04-18 09:05:39.7172 INFO Begin Request 10
2018-04-18 09:05:39.7512 INFO message 10 received
2018-04-18 09:05:39.7512 INFO Begin Request 8
2018-04-18 09:05:39.7812 INFO End Request 10
2018-04-18 09:05:39.8132 INFO message 8 received
2018-04-18 09:05:39.8302 INFO End Request 8
2018-04-18 09:05:40.0722 INFO Begin Request 1
2018-04-18 09:05:40.1097 INFO message 1 received
2018-04-18 09:05:40.1097 INFO Begin Request 5
2018-04-18 09:05:40.1413 INFO message 5 received
2018-04-18 09:05:40.1703 INFO End Request 1
2018-04-18 09:05:40.1913 INFO End Request 5
2018-04-18 09:05:40.4033 INFO Begin Request 3
2018-04-18 09:05:40.4403 INFO message 3 received
2018-04-18 09:05:40.4563 INFO End Request 3
2018-04-18 09:05:40.5173 INFO Begin Request 7
2018-04-18 09:05:40.5508 INFO message 7 received
2018-04-18 09:05:40.5663 INFO End Request 7
2018-04-18 09:05:41.0100 INFO Begin Request 4
2018-04-18 09:05:41.0470 INFO message 4 received
2018-04-18 09:05:41.0630 INFO End Request 4
2018-04-18 09:05:41.3535 INFO Begin Request 2
2018-04-18 09:05:41.3740 INFO message 2 received
2018-04-18 09:05:41.4080 INFO End Request 2

正在查看请求 8。 请求是在 .23 的代码中发起的。服务器在 0.39 收到请求。所以有16秒的差距

我正在使用 System.Diagnostics 和 NLog 记录网络跟踪。 这导致了严重的性能下降。

禁用 System.Diagnostics 解决了我的问题。