2

我需要为 ASP.NET 应用程序设置一个自定义的日志记录系统。除其他外,它必须为每个请求记录一些数据。我想到了两种方法:

方法 #1:提交每个请求的每个条目。例如:在每个请求上创建一个日志条目并将其提交到数据库(使用瞬态DbContext)。我担心此提交会给无法很好扩展的请求的服务带来开销。

方法#2:缓冲条目,定期提交。例如:在每个请求上创建一个日志条目并将其添加到并发缓冲区(使用共享锁)。当超出该缓冲区的限制时,将获取一个独占锁,缓冲的条目一次性提交到数据库(使用另一个,也是瞬态DbContext的,仅为每次提交创建和销毁)并清空缓冲区。我知道这会使“提交”请求变慢,但这是可以接受的。我也知道关闭/重新启动应用程序可能会导致丢失未提交的日志条目,因为在这种情况下 AppDomain 会发生变化,但这也是可以接受的。

我已经在我的要求范围内实现了这两种方法,我已经对它们进行了测试,并且我已经在本地环境中尽可能多地使用它们。我还没有部署,因此我无法在真实条件下测试它们。两者似乎都同样有效,但我无法得出这样的结论。

这两种方法中哪一种是最好的?我担心数千用户高峰期间的性能。有没有我不知道的陷阱?

4

2 回答 2

2

为了解决您对选项 1 关于减慢每个请求的担忧,为什么不使用 TPL 将日志记录卸载到不同的线程?像这样的东西:

public class Logger
{

    public static void Log(string message)
    {
        Task.Factory.StartNew(() => { SaveMessageToDB(message); });
    }

    private static void SaveMessageToDB(string message)
    {
        // etc.
    }

}

在写入条目时,HTTP 请求线程不必等待。您还可以调整选项 2 以执行相同的操作,将累积的消息集写入不同的线程。

我实现了一个类似于选项 2 的解决方案,但除了数量限制之外,还有时间限制。如果在一定秒数内没有输入日志条目,则队列将转储到数据库。

于 2013-05-31T20:20:50.373 回答
1

使用 log4net,并适当设置其缓冲区大小。然后你就可以回家喝啤酒了...第三方”你想到的)。

不过说真的 - 以大量复杂性为代价优化每个请求的单个数据库插入似乎还为时过早。如果您对每个请求进行 10 次以上的日志调用,那么对每个请求进行缓冲可能是有意义的——但这比编写高性能多线程代码要简单得多且不易出错。

当然,与往常一样,真正的证据在于分析——所以启动一些测试,并获得一些数字。至少,对缓冲记录器进行一批直接插入,并确定每个请求可能存在的差异,以便您做出合理的决定。

直觉上,我认为这不值得这么复杂——但我以前在性能上犯过错误。

于 2013-05-31T20:00:55.643 回答