Node.js 服务器超时问题(EC2 + Express + PM2)

标签 node.js http express amazon-ec2 connection-timeout

我对运行生产 node.js 应用程序比较陌生,最近我的服务器超时出现问题。

基本上在一定的使用量和时间后,我的 node.js 应用程序停止响应请求。我什至看不到在我的控制台上触发路由 - 就像整个事情都停止了,来自我的客户端(运行 AFNetworking 的 iPhone)的 HTTP 调用不再到达服务器。但是如果我重新启动我的 node.js 应用程序服务器,一切都会重新开始工作,直到事情不可避免地再次停止。该应用程序永远不会崩溃,它只是停止响应请求。

我没有收到任何错误,而且我确保处理和记录所有数据库连接错误,所以我不确定从哪里开始。我认为这可能与内存泄漏有关,所以我安装了 node-memwatch 并为内存泄漏设置一个监听器,但在我的服务器停止响应请求之前不会被调用。

关于可能发生什么以及我如何解决这个问题的任何线索?

这是我的堆栈:

  • AWS EC2 微型实例上的 Node.js(使用 Express 4.0 + PM2)
  • 运行 MySQL 的 AWS RDS 卷上的数据库(使用 node-mysql)
  • 使用 Redis 存储在与 node.js 应用程序相同的 EC2 实例上的 session
  • 客户端是通过 AFNetworking 访问服务器的 iPhone

  • 再一次,上面提到的任何模块都没有发生错误。

    最佳答案

    首先,您需要更具体地了解超时。

  • TCP 超时 :TCP 将一条消息分成多个数据包,这些数据包一个一个地发送。接收方需要确认已收到数据包。如果接收方在一定时间内没有确认收到该包,则发生 TCP 重传,即再次发送相同的数据包。如果这种情况再发生几次,发送方就会放弃并终止连接。
  • HTTP 超时 :像浏览器这样的 HTTP 客户端,或者作为客户端的服务器(例如:向其他 HTTP 服务器发送请求)可以设置任意超时。如果在该时间段内未收到响应,它将断开连接并将其称为超时。

  • 现在,有很多很多可能的原因......
  • 错误的内容长度计算 :如果您发送带有 Content-Length: 20 的请求 header ,这意味着“我将向您发送 20 个字节”。如果您发送 19 个,另一端将等待剩余的 1 个。如果这需要太长时间...超时。
  • 基础设施不足 : 也许你应该为你的应用程序分配更多的机器。如 (total load / # of CPU cores)大于 1,或者您的内存使用率很高,您的系统可能容量过大。但是请继续阅读...
  • 静默异常 :抛出错误但未在任何地方记录。请求从未完成处理,导致下一个项目。
  • 资源泄露 : 每个请求都需要处理完成。如果您不这样做,连接将保持打开状态。此外,IncomingMesage对象(又名:在 express 代码中通常称为 req)将保持被其他对象引用(例如:express 本身)。这些对象中的每一个都可以使用大量内存。
  • Node 事件循环饥饿 : 我会在最后。


  • 对于内存泄漏,症状是:
    Node 进程将使用越来越多的内存。

    更糟糕的是,如果可用内存不足并且您的服务器被错误配置为使用交换,Linux 将开始将内存移动到磁盘(交换),这是非常 I/O 和 CPU 密集型的。服务器不应启用交换。
    cat /proc/sys/vm/swappiness
    

    将返回您系统中配置的交换级别(从 0 到 100)。您可以通过 /etc/sysctl.conf 以持久的方式修改它。 (需要重新启动)或以不稳定的方式使用:sysctl vm.swappiness=10
    一旦确定存在内存泄漏,就需要获取核心转储并下载以进行分析。可以在另一个 Stackoverflow 响应中找到一种方法:Tools to analyze core dump from Node.js

    对于连接泄漏(您通过不处理完成请求而泄漏了连接),您将有越来越多的已建立连接到您的服务器。您可以使用 netstat -a -p tcp | grep ESTABLISHED | wc -l 检查已建立的连接可用于计数已建立的连接。

    现在,事件循环饥饿 是最糟糕的问题。如果您的代码生命周期很短,则 Node 工作得很好。但是如果你做 CPU 密集型的事情并且有一个功能让 CPU 忙了很长时间......比如 50 毫秒(50 毫秒的稳定、阻塞、同步 CPU 时间,而不是需要 50 毫秒的异步代码),操作是由事件循环处理,例如处理 HTTP 请求开始落后并最终超时。

    查找 CPU 瓶颈的方法是使用性能分析器。 nodegrind/qcachegrind是我首选的分析工具,但其他人更喜欢火焰图等。然而,在生产中运行分析器可能很困难。只需使用一个开发服务器并用请求猛烈抨击它。又名:负载测试。有很多工具可以做到这一点。

    最后,另一种调试问题的方法是:
    env NODE_DEBUG=tls,net node <...arguments for your app>
    Node 具有可选的调试语句,可通过 NODE_DEBUG 启用。环境变量。设置 NODE_DEBUGtls,net将使 Node 发出 tls 和 net 模块的调试信息......所以基本上所有正在发送或接收的内容。如果有超时,您将看到它的来源。

    来源:多年维护大型 Node 服务部署的经验。

    关于Node.js 服务器超时问题(EC2 + Express + PM2),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29812692/

    相关文章:

    node.js - VSC 不会在正确的断点处中断

    node.js - Node 尝试查找很早才在:app:bundleReleaseJsAndAssets阶段删除的包

    http - 当 session 在 OpenID Connect 设置中过期时,WWW-Authenticate 应该包含什么?

    javascript - Mongoose 类型错误 : Question is not a constructor

    javascript - Dynamoose/DynamoDB 更新将空数组保存为 null

    node.js - Jasmine spyOn NodeJS

    javascript - 在成功登录后运行 HTTP post

    c++ - 如何在C++中获取外部IP地址?

    javascript - nodejs expressjs gzip json 内容

    node.js - Express.js 中的 res.download 文件发生了什么?