我认为这个问题比人们乍一看要复杂得多。
良好响应的一部分与 libuv 无关,而与您的具体需求和权衡关系很大。虽然,例如,一些缓冲,即不太频繁的写入系统调用,是好的,但它也引入了一个问题,可能(或不会)在日志记录领域对您造成严重影响。原因:如果应用程序死亡,缓冲的东西也会随着应用程序一起死亡。然而,这与日志记录的逻辑背道而驰。
至于libuv和性能,我个人的经验是
a) 想在写出信息和缓冲之间找到一个很好的平衡点。在你的情况下,我的直觉是你缓冲太多,你可能应该更频繁地写出来。
b) 人们想要从性能是否真的关键以及细节方面考虑好性能。后者在繁重的服务器负载下变得越来越重要。当您提供大约 100 个连接时,它可能无关紧要,但如果您提供数万或数十万个连接,则使用 fprintf 等便利功能可能成本太高。
具体示例:在高负载情况下,您可能希望在启动时获取一次挂墙时间以及单调计时器的(当时)当前值(非常便宜)。任何时间信息都可能与该起始值相关(简单的减法)。写出来的工作方式如下:预先格式化的开始时间加上单调差异(例如“03:52:41 +123456 ms”)。
您的场景的另一点是现代操作系统几乎总是会提供出色的缓冲,因此自己缓冲过多通常没有多大意义。
总而言之,我建议使用大约 16K 或 32K 的缓冲区并更频繁地写出它。如果(且仅当)您的场景是高性能/重负载时,您可能希望避免使用方便但昂贵的功能。
就 libuv 而言,我不担心。根据您的操作系统和 libuv 版本文件内容(与套接字内容相反)可能确实是伪异步(通过线程伪造),但我的经验是 libuv 不是问题;相反,例如,您的大缓冲区可能是一个问题,因为它很可能被写入多个块。
关于基于计时器的方法,您可能需要查看 libuv 空闲机制并处理完整缓冲区的问题。简单地丢弃日志信息对我来说似乎是不可接受的。毕竟,您不是为了好玩而登录,而是因为该信息可能很重要(如果不是这样,您一开始就不会遇到问题。那么解决方案将很简单:减少日志记录)。
最后,我想说一个更笼统的说法:这里的秘诀是平衡,而不是单个细节的优化性能。您希望使整个系统保持良好的平衡,而不是例如通过使用大型缓冲区进行优化,这最终只是将问题推到另一个层次而不是解决它。
我喜欢把这个问题领域想象成搬迁公司总部的任务:问题不在于最快的卡车,而在于所有卡车都非常快,换句话说,一种平衡的方法。