Node.js+Express 随机丢弃请求,导致网关超时

2024-05-07

EDIT

经过一番思考,我终于找到了一些看起来可能是可靠的线索:

当 Express 库当前正在使用 Node+OAuth 模块执行多个出站请求(例如,到 Facebook、Twitter 等)时,它无法接受传入请求。我能够通过在代码中放置大量日志来确定这一点,我发现在出站请求中间时不会触发“开始请求”日志(如下所述)。

我已经能够清楚地表明,当 Node+OAuth 模块发出一些出站请求时,对我的 API 的入站请求(通过浏览器窗口)将挂起并且不会被接收,直到其中一个出站 OAuth 请求完成为止。

当然,我已经做了:

require('http').globalAgent.maxSockets = 999;

根据 IRC 中的建议,我添加了

console.log(require('http').globalAgent.requests);

但这似乎总是 === {},这意味着据我所知没有待处理的入站请求。

因此,我得出的结论是,出于某种原因,node.js 或express 选择阻止由于出站请求而导致的传入请求,即使应该有大量可用的套接字......

有人对如何解决这个问题有任何提示吗?


我有一个使用 Express、Mongoose 等在 Node.js 中创建的 API,部署在 Amazon 云上,该 API 在 99% 的情况下都运行良好且快速。

但偶尔,某个请求似乎会以某种方式被丢弃或以其他方式被忽略。我说的是通常在几毫秒内完成的请求,随机无响应且没有清晰的图片why.

症状是连接到 API 端点时出现简单的“网关超时”。同一客户端使用相同参数发出的相同请求,无论是在之前还是之后,都可以正常工作。

当然,我的第一个想法是“呃,服务器超载!”所以我花了很多时间优化我的请求、mongoDB 等。最后我发现 CPU/磁盘/RAM 的整体使用情况(在 Node.js 服务器和 Mongo 服务器中)是very低的。我使用 Scout 和 RightScale 实时跟踪我的服务器,并记录任何耗时超过 100 毫秒的请求或查询。我的节点服务器目前有 5GB 的可用 RAM、70% 的可用 CPU(在第一个核心上)等。所以我 99.99% 确定这不是性能问题。

最后,我孤注一掷:我在客户提出的所有请求中附加了一个随机数。然后,在 node.js 应用程序中,我在首次收到请求和完成请求时执行 console.log() 。例如,这是我在express中使用的中间件:

var configureAPI = function() {
    return function(req, res, next) {
        if(req.body.ruid)
            console.log(req.body.ruid);

        // more middleware stuff...
    };
}
server.configure(function(){

    server.use(express.bodyParser());
    server.use(configureAPI());
    server.use(onError);

    // ...  more config stuff
}

我的发现令我震惊:显然,Node.js 应用程序甚至没有收到有问题的请求。我有一个 Javascript Web 应用程序,我将随请求发送到控制台的“ruid”打印出来。每当请求成功时,node.js 控制台中就会打印相应的“ruid”。每当超时,就没有。


编辑:更多调试和信息。

我的应用程序服务器实际上启动(并继续)也提供 PHP 服务(因此,它们安装了 Apache 等)。我需要http://streamified.me http://streamified.me为我的网站(PHP)提供服务并且http://api.streamified.me http://api.streamified.me为我的 API (node.js) 提供服务...所以我的 httpd.conf 文件中有一行可以导致对 api.streamified.me (而不是 Streamified.me)的请求通过端口 8888 转到 node.js:

RewriteCond %{HTTP_HOST} ^api.streamified.me
RewriteRule ^(.*) http://localhost:8888$1 [P]

因此,在同一个 httpd.conf 文件中,我打开了 RewriteLogLevel 5,然后在本地主机上创建了一个简单的 PHP+CURL 脚本,以使用随机 URL 访问我的 api.streamified.me(这应该会导致 node.js 触发一个简单的“未找到”响应),直到导致网关超时。在这里,您可以看到它已经发生了——并且重写日志显示该请求肯定已被应用程序服务器接收并转发到端口 8888...但它从未被 node.js 接收过(或者,至少,中间件第一行中的第一行代码永远不会得到它......)


我已经一遍又一遍地检查我的 Node.js 代码,并且非常确定我没有阻塞代码,即使我有,我也无法想象它会阻塞线程足够长的时间以错过请求而不在某处引发红旗。

我缺少什么?是否有某种原因导致传入套接字被阻止?我确实通过我的 node.js 应用程序向外部 API 发出了相当多的 HTTP 请求,但据我所知,这不应该阻止传入的套接字。


当然,我有错误日志记录。我已在进程级别启用它......

process.addListener("uncaughtException", function (err) {
    // some logging code
}

以及 Express 级别(上面的 onError 处理程序)。我知道我的错误记录功能可以工作,因为我以前见过它们都触发过。但他们都没有在删除请求时报告任何内容,我也没有在控制台中看到任何内容......


  • 快速版本:3.0.0rc5
  • Node.js 版本:0.8.12
  • 在标准 Amazon Cloud 设置(m1.large 实例)上运行的 Node.js 应用程序的 2 个实例,位于 2 个负载均衡器后面,连接到 3 个 MongoDB 副本集(也是 m1.large)

听起来您锁定 Node 线程的时间太长,导致传入连接在处理它们之前超时。 Node 是单线程的,因此它一次只做一件事,它不能因为传出请求而选择阻止传入请求。它只能因为正忙于做其他事情而无法接受传入请求。你需要弄清楚它在忙什么。

如果您不发出出站请求,一切都正常吗?如果是这样,您需要查看发出这些请求的代码,以确保您没有等待响应。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Node.js+Express 随机丢弃请求,导致网关超时 的相关文章

随机推荐

  • style.css 在 WordPress 中不起作用

    我的 WordPress 有问题 我已经创建了所有需要的文件 包括 style css index php 等 但页面没有样式 在标题中 除其他外 我把这个
  • 使用 proto.io 让开关在 IE8 中工作

    Proto io 为使用 CSS 的开 关切换按钮提供了一个非常好的解决方案 但是 它在 IE8 中不起作用 http proto io freebies onoff http proto io freebies onoff 有谁知道如何用
  • 需要使用 Node.js 压缩整个目录

    我需要使用 Node js 压缩整个目录 我目前正在使用node zip 每次该进程运行时都会生成一个无效的ZIP文件 正如您可以从这个 Github 问题 https github com Stuk jszip issues 41 是否有
  • 如何像java中的make一样程序化生成塞尔达传说

    我将如何用java制作程序生成的地图 游戏本身就像塞尔达传说是程序生成的 有帮助吗 不久前的 塞尔达传说 地图使用等距平铺视图 您需要做的第一件事是将等距图块集加载到您的程序中 我确信您可以找到塞尔达图块集 然后 您需要决定如何按程序生成地
  • Jsch:命令输出不可用

    我正在尝试使用 jsch 连接到远程交换机并运行一些命令并提取输出 我可以使用 连接到交换机 但是命令输出在输入流中不可用 也许我没有以正确的方式做这件事 这是代码 session jsch getSession user 10 0 0 0
  • 如何在postman中从JSONArray获取JSONobject

    我正在尝试使用测试脚本自动化邮递员中的注册场景 我有以下 JsonArray 作为响应 id 1 name user A cntkp martin company kreativ tel 12345678 email email prote
  • Django:djcelery 从 celery import current_app as celery in virtualenv 导入错误

    好吧 我已经尝试了我和谷歌能想到的一切 我正在尝试在 Macbook Pro OSX 10 8 4 上的 virtualenv 下运行 django celery 我在激活 virtualenv 时使用 pip 安装了 django cel
  • 如何在 Vue.js 中排除文件(例如配置文件)?

    https cli vuejs org config configurewebpack https cli vuejs org config configurewebpack https cli vuejs org config chain
  • Windows 8 SDK 中的 DirectX

    Summary 是否应该从针对 Windows 8 的应用程序中删除 directX 包含文件 Details 我是 Windows 开发新手 我正在尝试使用 Visual Studio 2012 如果可能 在 Windows 8 上编译
  • 如何在 F# 中捕获任何异常(System.Exception)而不发出警告?

    我试图捕获异常 但编译器给出警告 此类型测试或向下转型将始终保持 let testFail try printfn Ready for failing failwith Fails with System ArgumentException
  • 是否有一个 clojure 函数可以“连接”两个地图列表?

    我正在寻找一个类似于sql中的join的连接函数 例如 这是两个地图列表 def a user id 1 name user 1 user id 2 name user 2 def b user id 2 email e 2 user id
  • 如何读取/理解目标主机上的ansible日志(由syslog编写)

    当你在某个主机上执行 ansible 时 它 会写入该主机上的 syslog 如下所示 Dec 1 15 00 22 run tools python ansible
  • 如何在 Python 中的每个单元测试之前和之后运行特定代码

    以下是我在文件中的测试的结构 Class setup 测试01测试02测试03拆除 我需要在每次测试之前和之后运行特定的代码 以前 我可以从设置中调用该代码 但在测试之后 我不知道该怎么做 显然 从拆卸中调用代码对于最后一个测试是有效的 但
  • 屏幕关闭时接近传感器不起作用?

    Hy 我有一个与接近传感器相关的问题 当我将手指放在上面时 我想关闭屏幕 当我拿开手指时 我想打开屏幕 我成功地完成了关闭部分 但是当我将手指从传感器上移开时 它似乎没有执行 onSensorChanged 方法 这是它的代码 public
  • PL/SQL 触发器问题

    我正在尝试编写一个触发器来填充包含员工更新工资信息的表 我现在遇到一个无法解决的问题 这是要填充的表 drop table SalUpdates cascade constraints create table SalUpdates Sal
  • 如何替换每行中出现的所有字符串?

    我想在以下脚本中将所有出现的 用户名 替换为 但它仅替换第一次出现的情况 ls al sed s username 这就是 sed 默认情况下的工作方式吗 提前致谢 你需要g 全局 修饰符 sed s username g
  • 同步不经常更新的哈希图的最佳方式

    我有一个在应用程序中使用的 HashMap 数据是在应用程序初始加载期间从数据库填充的 然后它始终只是读取并且从不更新 会有多个线程不断地读取数据 由于数据永远不会更新 因此我们目前不使用任何同步 仅使用 HashMap 我们现在定义的方式
  • 修改“NodeJS”上的 XML 标签

    有谁知道如何使用 NodeJS 修改 XML 文件的标签值 这是我的 XML 文件
  • 动态更新 bootstrap 3 日期选择器选项?

    该日期选择器已经使用其他默认选项创建 但我需要使用以下新选项更新它 但它似乎不起作用 new options var new options format dd mm yyyy autoclose true language es upda
  • Node.js+Express 随机丢弃请求,导致网关超时

    EDIT 经过一番思考 我终于找到了一些看起来可能是可靠的线索 当 Express 库当前正在使用 Node OAuth 模块执行多个出站请求 例如 到 Facebook Twitter 等 时 它无法接受传入请求 我能够通过在代码中放置大