我们的应用程序中有一个大型进程,每月运行一次。此过程通常在大约30分钟内运行,并生成342000左右的日志事件。最近我们使用WCF将日志记录更新为集中模型,现在性能有问题。以前的解决方案将在大约30分钟内完成,而新的日志记录现在需要3到4个小时。看起来问题是因为应用程序实际上在执行继续之前等待WCF请求完成。 WCF方法已经配置为IsOneWay,我将客户端的调用包装到另一个线程中的WCF方法,以尝试防止此类问题,但它似乎没有工作。我已经考虑过使用异步WCF调用但是在我尝试其他东西之前想过我会在这里询问是否有更好的方法来处理它。
答案 0 :(得分:4)
在30分钟内发生342000个日志事件,如果我的数学运算正确,则每秒发出190个日志事件。我认为您的问题可能与WCF中的默认限制设置有关。即使您的方法设置为单向,取决于您是否为每个已记录的事件创建新代理,在创建代理时,调用该方法仍会阻塞,通道已打开,如果您正在使用基于HTTP的绑定,它将一直阻塞,直到服务收到消息(基于HTTP的绑定在收到消息时发送一个 null 响应,用于单向方法调用)。默认的WCF限制将服务端的并发实例限制为10,这意味着一次只处理10个请求,并且任何进一步的请求将排队,因此将其与HTTP绑定配对,并且在前10个请求之后的任何内容都是将阻止客户端,直到它被处理的10个请求之一。在不知道如何配置服务(实例模式等)的情况下,很难说更多,但如果您使用的是每次呼叫实例化,我建议您设置MaxConcurrentCalls
和MaxConcurrentInstances
你的ServiceBehavior
更高(默认值分别为16和10)。
此外,为了在其他人提到的关于聚合多个事件并一次性提交所有事件的基础上进行构建,我发现设置静态Logger.LogEvent(eventData)
方法很有帮助。这样,您可以在整个代码中使用它,并且可以在LogEvent
方法中控制您希望日志记录在整个应用程序中的行为,例如配置一次应提交的事件数。
答案 1 :(得分:3)
调用另一个进程或远程服务(即调用WCF服务)是您在应用程序中可以执行的最昂贵的操作。做它342,000次只是纯粹的疯狂!
如果您必须登录到集中式服务,则需要累积批量日志条目,然后,只有当您在内存中说出大约1000个时,才能将其全部发送到服务中。这将为您提供合理的性能提升。
答案 2 :(得分:1)
log4net有一个缓存系统,它存在于调用线程的上下文之外,所以它在记录时不会阻止你的调用。它的用法应该从许多appender config examples中明确 - 搜索术语bufferSize
。它被用在许多较慢的appender(例如远程处理,电子邮件)上以保持源线程移动而无需等待较慢的日志记录介质,并且还有一个通用的缓冲元appender可以“在”前面“使用”任何其他附加器。
我们在类似体积的系统中将它与 AdoNetAppender 一起使用,效果非常好。
答案 3 :(得分:0)
传统的syslog总是有很多在Windows上运行的syslog守护进程。它设计为比WCF更有效的集中式日志记录方式,WCF专为不太密集的操作而设计,尤其是在您不使用tcpip WCF配置的情况下。
换句话说,请继续使用 - 正确的工具。