我们已经创建了一个带有SQL背板的服务器。最近,我们发现这个issue导致w3wp.exe使用大量线程。在完成整个代码库之后,我们能够缩小原因与NLog的关系。
我们已通过Web配置文件中的以下配置配置了NLog。
<configuration>
<configSections>
<section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog" />
</configSections>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.nlog-project.org/schemas/NLog.xsd NLog.xsd">
<targets async="true">
<target name="file" xsi:type="File" fileName="${basedir}/Logs/${shortdate}_printcloud.log" archiveFileName="${basedir}/Logs/ArchiveAuto/{#}_printcloud.log" archiveDateFormat="yyyy-MM-dd" archiveAboveSize="50000000" archiveEvery="Day" archiveNumbering="DateAndSequence" maxArchiveFiles="14" archiveOldFileOnStartup="false" createDirs="true" layout="${longdate} ${uppercase:${level}} ${logger} ${message} (${callsite:includSourcePath=true}) ${exception:format=tostring}" />
</targets>
<rules>
<logger name="PrintCloud.*" minlevel="Trace" maxlevel="Error" writeTo="file" />-->
</rules>
</nlog>
<configuration>
在集线器内部,我们使用了下面的记录器。
public class ConnectorHub : Hub
{
private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
public void Connect(string message)
{
logger.Debug("Connection Recieved");
(new SignalRHubHelper()).SendConnectRecieved(Context.ConnectionId);
}
}
当我们在启用了这些配置的情况下运行背板时,当客户端尝试重新连接时,我们面临着大量线程使用的问题。但是如果我们从Web配置文件中注释掉NLog配置代码,则背板可以正常工作。使用背板时是否有人遇到类似的行为?这种行为可能是什么原因?
SignalR versoin - 2.2.2 NLog版本 - 4.4.9
编辑1
当我们从webconfig禁用信号器跟踪日志记录时,问题似乎没有发生。我们使用NLog.NLogTraceListener
来记录信号器跟踪。
<system.diagnostics>
<sources>
<source name="SignalR.SqlMessageBus">
<listeners>
<add name="traces" />
</listeners>
</source>
<source name="SignalR.ServiceBusMessageBus">
<listeners>
<add name="traces" />
</listeners>
</source>
<source name="SignalR.RedisMessageBus">
<listeners>
<add name="traces" />
</listeners>
</source>
<source name="SignalR.ScaleoutMessageBus">
<listeners>
<add name="traces" />
</listeners>
</source>
<source name="SignalR.Transports.WebSocketTransport">
<listeners>
<add name="traces" />
</listeners>
</source>
<source name="SignalR.Transports.ServerSentEventsTransport">
<listeners>
<add name="traces" />
</listeners>
</source>
<source name="SignalR.Transports.ForeverFrameTransport">
<listeners>
<add name="traces" />
</listeners>
</source>
<source name="SignalR.Transports.LongPollingTransport">
<listeners>
<add name="traces" />
</listeners>
</source>
<source name="SignalR.Transports.TransportHeartBeat">
<listeners>
<add name="traces" />
</listeners>
</source>
<source name="SignalR.ReflectedHubDescriptorProvider">
<listeners>
<add name="traces" />
</listeners>
</source>
</sources>
<!--Sets the trace verbosity level-->
<switches>
<add name="SignalRSwitch" value="Verbose" />
</switches>
<sharedListeners>
<add name="traces" type="NLog.NLogTraceListener, NLog" />
</sharedListeners>
<trace autoflush="true" />
</system.diagnostics>
而不是使用NLog.NLogTraceListener
而使用System.Diagnostics.TextWriterTraceListener
也似乎没有给出任何问题。
答案 0 :(得分:2)
认为问题是这样的:
autoflush=true
这会导致NLogTraceListener进入beserk并为每个trace-event执行flush。通过使用线程池线程来刷新所有已注册的NLog目标。
如果你需要autoflush = true,那么考虑通过向listener添加disableFlush属性来禁用threadpool flush:
<add name="traces" type="NLog.NLogTraceListener, NLog" disableFlush="true" />
很好奇为什么NLog Wiki建议启用autoflush = true,而不添加这个重要属性:
https://github.com/NLog/NLog/wiki/Send-System-Diagnostic-(Trace)-to-NLog