通过WCF记录而不会降低速度

我们的应用程序中有一个大型进程,每月运行一次。 此过程通常在大约30分钟内运行,并生成342000左右的日志事件。 最近我们使用WCF将我们的日志记录更新为集中模型,现在性能有问题。 以前的解决方案将在大约30分钟内完成,而新的日志记录现在需要3到4个小时。 看起来问题是因为应用程序在执行继续之前实际上正在等待WCF请求完成。 WCF方法已经配置为IsOneWay,我将客户端的调用包装到另一个线程中的WCF方法,以尝试防止此类问题,但它似乎没有工作。 我曾经考虑过使用异步WCF调用,但在我尝试别的东西之前想过我会问这里是否有更好的方法来处理这个问题。

30分钟内342000个日志事件,如果我的数学运算正确,则每秒发出190个日志事件。 我认为您的问题可能与WCF中的默认限制设置有关。 即使您的方法设置为单向,取决于您是否为每个已记录事件创建新代理,在创建代理时,调用该方法仍会阻塞,通道将被打开,如果您正在使用基于HTTP的绑定,它将阻塞,直到服务接收到消息(基于HTTP的绑定在收到消息时发送回单向方法调用的响应)。 默认的WCF限制将服务端的并发实例限制为10,这意味着一次只能处理10个请求,并且任何其他请求将排队,因此将其与HTTP绑定配对,并且在前10个请求之后的任何内容都是将阻止客户端,直到它被处理的10个请求之一。 在不知道如何配置服务(实例模式等)的情况下,很难说更多,但如果您使用的是每次调用实例化,我建议将ServiceBehavior上的MaxConcurrentCallsMaxConcurrentInstances设置为更高的值(默认值分别为16和10)。

此外,为了构建其他人提到的关于聚合多个事件并一次性提交它们的内容,我发现设置静态Logger.LogEvent(eventData)方法很有帮助。 这样,在整个代码中使用起来很简单,并且您可以在LogEvent方法中控制希望日志记录在整个应用程序中的行为,例如配置一次应提交的事件数。

调用另一个进程或远程服务(即调用WCF服务)是您在应用程序中可以执行的最昂贵的操作。 做它342,000次只是纯粹的疯狂!

如果您必须登录到集中服务,则需要累积批量日志条目,然后,只有当您在内存中说出大约1000个时,才能将其全部发送到服务中。 这将为您提供合理的性能提升。

log4net有一个缓冲系统,它存在于调用线程的上下文之外,所以它在记录时不会保持你的调用。 它的用法应该从许多appender配置示例中清楚 – 搜索术语bufferSize 。 它被用在许多较慢的appender(例如,远程处理,电子邮件)上以保持源线程移动而无需等待较慢的日志记录介质,并且还有一个通用的缓冲元appender可以在“任何其他”前面使用附加目的地。

我们在类似体积的系统中将它与AdoNetAppender一起使用,效果非常好。

传统的syslog总是有很多在Windows上运行的syslog守护进程。 它设计为比WCF更有效的集中式日志记录方式,WCF专为不太密集的操作而设计,特别是如果您不使用tcpip WCF配置。

换句话说,有了这个 – 正确的工具。