gpt4 book ai didi

docker - 当对 Trace.WriteLine() 进行多次调用时,在 Linux 容器中运行的 ASP.NET Core 2.0 应用程序会遇到锁定问题

转载 作者:IT老高 更新时间:2023-10-28 12:46:50 27 4
gpt4 key购买 nike

我们的应用程序是一个 ASP.NET Core 2.0 WebAPI,部署在 Linux Docker 容器中并在 Kubernetes 中运行。

在负载测试期间,我们发现了 CPU 使用率的间歇性峰值,我们的应用程序永远无法从中恢复。

我们使用 perfcollect 从容器中收集跟踪信息,以便我们可以比较成功的测试和 CPU 峰值的测试。我们发现,在失败的测试中,大约 75% 的 CPU 时间都花在了 JIT_MonRelaibleEnter_Protable 上,这是一个锁定操作的接口(interface)。调用者是 System.Diagnostics.TraceSource.dll

我们的应用程序是从 .NET Framework 移植而来的,并且包含对 System.Diagnostics.Trace.WriteLine() 的大量调用。当我们删除所有这些时,我们的 CPU/内存使用量减少了 50% 以上,并且我们再也看不到 CPU 峰值了。

我想了解这个问题的原因。

在 corefx 存储库中,我可以看到在 TraceInternal.cs 中设置了默认跟踪监听器:

public static TraceListenerCollection Listeners
{
get
{
InitializeSettings();
if (s_listeners == null)
{
lock (critSec)
{
if (s_listeners == null)
{
// In the absence of config support, the listeners by default add
// DefaultTraceListener to the listener collection.
s_listeners = new TraceListenerCollection();
TraceListener defaultListener = new DefaultTraceListener();
defaultListener.IndentLevel = t_indentLevel;
defaultListener.IndentSize = s_indentSize;
s_listeners.Add(defaultListener);
}
}
}
return s_listeners;
}
}

我可以看到 DefaultTraceListener.cs调用 Debug.Write():

private void Write(string message, bool useLogFile)
{
if (NeedIndent)
WriteIndent();

// really huge messages mess up both VS and dbmon, so we chop it up into
// reasonable chunks if it's too big
if (message == null || message.Length <= InternalWriteSize)
{
Debug.Write(message);
}
else
{
int offset;
for (offset = 0; offset < message.Length - InternalWriteSize; offset += InternalWriteSize)
{
Debug.Write(message.Substring(offset, InternalWriteSize));
}
Debug.Write(message.Substring(offset));
}

if (useLogFile && !string.IsNullOrEmpty(LogFileName))
WriteToLogFile(message);
}

Debug.Unix.cs ,可以看到有对SysLog的调用:

 private static void WriteToDebugger(string message)
{
if (Debugger.IsLogging())
{
Debugger.Log(0, null, message);
}
else
{
Interop.Sys.SysLog(Interop.Sys.SysLogPriority.LOG_USER | Interop.Sys.SysLogPriority.LOG_DEBUG, "%s", message);
}
}

我没有太多使用 Linux 的经验,但我相信我可以通过在容器中运行以下命令来模拟对 SysLog 的调用:

logger --socket-errors=on 'SysLog test'

当我运行该命令时,我得到以下响应:

socket /dev/log: No such file or directory

所以看起来我无法从容器成功调用 SysLog。如果这确实是我调用 Trace.WriteLine() 时发生的情况,为什么它会导致我的应用程序出现锁定问题?

据我所知,EnvVar_DebugWriteToStdErr 未在我的容器中设置,因此它不应尝试写入 StdErr。

最佳答案

解决办法可能是 rsyslog 没有运行。是否安装在您的容器中?使用内置 rsyslog 的基础镜像。

This link也可以帮忙。

关于docker - 当对 Trace.WriteLine() 进行多次调用时,在 Linux 容器中运行的 ASP.NET Core 2.0 应用程序会遇到锁定问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49397120/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com