Docker / Kubernetes上的Asp.Net Core微服务在调用者和被调用者之间的服务间调用持续时间上存在分歧。
呼叫者日志可以比被呼叫者多显示几毫秒到十整秒的时间。该问题在重负载下加剧,但在轻负载下仍然存在。许多呼叫确实在主叫方和被叫方之间达成了一致,但是这种差异确实经常发生,足以使整体性能下降。
时间戳指示该时间间隔可以是被呼叫者报告其响应已完成的之前或之后。
示例日志(实时差异中的数字)
ServiceB: [2018-10-11T22:41:41.374Z] S2S request complete to ServiceA, Duration: 11644
ServiceA: [2018-10-11T22:41:29.732Z] Request complete, Duration: 5
呼叫者时间(所有S2S呼叫的通用类)
var timer = Stopwatch.StartNew();
var response = await _httpClientFactory.CreateClient().SendAsync(request);
timer.Stop();
Logger.Info($"S2S request complete to {service}, Duration: {timer.EllapsedMilliseconds}");
Callee Timing(自定义Asp.Net中间件)
var timer = Stopwatch.StartNew();
await _next(context);
timer.Stop();
Logger.Info($"Request complete, Duration: {timer.EllapsedMilliseconds}");
该中间件几乎注册为管道中的第一个(用于日志关联的仅次于ActivityId / TraceId中间件)。
故障排除步骤
系统拓扑
Asp.Net Core 2.1自托管的Kestrel
.Net Core 2.1.5运行时
Docker / Kubernetes 1.10.5
K8s插件:kube-proxy,weave,etcd,SkyDNS
AWS c5.4xlarge
更新
答案 0 :(得分:0)
在这种情况下,此问题已通过删除 k8s spec CPU限制得到解决。
监视container_cpu_cfs_throttled_seconds_total
度量标准发现,其中一个服务容器被频繁暂停 。这些暂停主要发生在S2S呼叫的呼叫方。这会增加呼叫者报告的经过时间。
删除k8s规范中的CPU限制可防止k8s通过--cpu-quota
和--cpu-period
docker parameters。哪个控制着容器暂停。