gpt4 book ai didi

Node.js 管道控制台错误到另一个程序(使其异步)

转载 作者:搜寻专家 更新时间:2023-10-31 23:23:21 25 4
gpt4 key购买 nike

来自 Expressjs documentation :

To keep your app purely asynchronous, you’d still want to pipe console.err() to another program

问题:

  1. 使用 stdout 和 stderr 重定向到 not block event loop 运行我的 Node 应用程序是否足够?像这样: node app 2>&1 | tee 日志文件 ?
  2. 如果 ad.1 答案为真,那么如何在使用 Winston 或 Bunyan 时实现非阻塞日志记录?他们有一些内置机制来实现这一点,或者他们只是将数据保存到特定文件浪费当前 Node.js 进程的 cpu 时间?或者也许为了实现真正的异步日志记录,他们应该将数据通过管道传输到执行“保存到文件”的子进程(它仍然是性能积极的吗?)?如果我的思维方式有误,谁能解释或纠正我?

  3. 已编辑部分:我可以假设从进程 A、B 等到进程 L 的管道数据对于这个特定进程(A、B、...)来说更便宜而不是将其写入文件(或通过网络发送)。关键点:我正在为使用 nodejs 集群的应用程序设计记录器。简而言之 - 其中一个进程 (L) 将处理来自其他进程 (A, B, ...) 的数据流。进程 L 将消息排队(例如逐行或其他特殊分隔符)并将其逐条记录到文件、数据库或其他任何地方。这种方法的优点是减少了可以花更多时间完成工作的进程的负载。还有一件事——假设是为了简化这个库的使用,这样用户将只包含这个记录器,而不需要通过 shell 进行任何额外的交互(流重定向)。您认为这个解决方案有意义吗?也许您知道某个图书馆已经这样做了?

最佳答案

让我们先设置一些地面...

写入终端屏幕(console.log() 等),写入文件(fs.writeFile(), fs.writeFileSync( ) 等)或将数据发送到流 process.stdout.write(data) 等)将始终“阻塞事件循环”。为什么?因为这些函数的某些部分总是用 JavaScript 编写的。这些函数所需的最少工作量是获取输入并将其交给一些 native 代码,但始终会执行一些 JS。

而且既然涉及到JS,那么必然会“阻塞”事件循环,因为无论如何JavaScript代码总是在单线程上执行。

这是一件坏事吗...?

没有。处理一些日志数据并将其发送到文件或流所需的时间非常少,并且不会对性能产生重大影响。

什么时候这是一件坏事,然后...?

您可以通过执行通常称为“同步”I/O 操作的操作来损害您的应用程序 - 也就是说,写入文件并且实际上不执行任何其他 JavaScript 代码直到写入完成。执行此操作时,您将所有数据交给底层 native 代码,虽然理论上能够继续在 JS 空间中执行其他工作,但您有意决定等待 native 代码以结果响应您。 这会“阻塞”您的事件循环,因为这些 I/O 操作可能比执行常规代码花费的时间长得多(磁盘/网络往往是计算机中最慢的部分)。

现在,让我们回到写入stdout/stderr

来自 Node.js 的文档:

process.stdout and process.stderr differ from other Node.js streams in important ways:

  1. They are used internally by console.log() and console.error(), respectively.
  2. They cannot be closed (end() will throw).
  3. They will never emit the 'finish' event.
  4. Writes may be synchronous depending on what the stream is connected to and whether the system is Windows or POSIX:
    • Files: synchronous on Windows and POSIX
    • TTYs (Terminals): asynchronous on Windows, synchronous on POSIX
    • Pipes (and sockets): synchronous on Windows, asynchronous on POSIX

我假设我们正在使用下面的 POSIX 系统。

实际上,这意味着当您的 Node.js 输出流未通过管道传输并直接发送到 TTY 时,向控制台写入内容将阻塞事件循环,直到整个 block 数据发送到屏幕。但是,如果我们现在将输出流重定向到其他东西(进程、文件等),当我们向控制台写入内容时,Node.js 将不会等待操作完成并继续执行其他 JavaScript 代码 它将数据写入该输出流

在实践中,我们可以在同一时间段内执行更多的 JavaScript

有了这些信息,您现在应该能够自己回答所有问题了:

  1. 如果您不向控制台写入任何内容,则无需重定向 Node.js 进程的 stdout/stderr,或者您可以仅重定向其中之一如果您不向另一个流写入任何内容,则流。无论如何您都可以重定向它们,但如果您不使用它们,您将不会获得任何性能优势。
  2. 如果您将记录器配置为将日志数据写入流,那么它不会过多地阻塞您的事件循环(除非涉及一些繁重的处理)。

If you care this much about your app's performance, do not use Winston or Bunyan for logging - they are extremely slow. Use pino instead - see the benchmarks in their readme.

关于Node.js 管道控制台错误到另一个程序(使其异步),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48325524/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com