Node.js 请求超时时停止处理请求
据我所知,由于Node.js中事件循环的性质,在将请求传递给回调函数之后,无法轻松阻止对其进行处理 由于每个事件回调都没有绑定到任何其他特定的流程或事件,因此一旦回调被添加到事件循环的队列或当前正在处理,即使触发了request.on('timeout')处理程序,它也将继续被处理 如果请求超时,有没有办法停止处理?我能想到的部分解决此问题的唯一方法是在请求期间执行的每个异步回调的顶部添加一个检查,以查看请求是否超时,如果超时,则立即返回并停止后续回调 但是,如果已经有一个从超时请求发出的未完成的异步调用正在处理,那么这并不能解决问题。在这种情况下,除非您破坏与正在进行异步处理(例如,执行MySQL查询)的任何对象的连接,否则它将继续并最终调用与其关联的异步回调 这在其他编程范例(如PHP+Apache)中不是问题,因为Apache为每个传入的请求创建一个新的PHP进程,因此如果请求超时,进程最终将被终止,整个执行流将停止 有没有人遇到过这个问题,并找到了一个现有的库或自定义方法来轻松解决这个问题 编辑:要添加特定示例,请执行以下操作: 现在我们有一个API内置节点,它处理传入的请求以跟踪分析,将请求数据发布到兔子队列,然后返回响应。如果请求进入并且由于某种原因请求处理时间超过30秒,则请求将超时,并向客户端发送错误响应。此时,客户端将再次尝试进行相同的呼叫(因此我们不会丢失分析) 但是,由于请求本身与发布到rabbit的调用之间没有任何联系(除了启动发布的是该请求),因此无法停止发布该数据。因此,如果rabbit服务器最终完成对发布请求的处理,那么现在将有重复的数据,因为客户端现在已经发出了2个(或更多)请求 阻止初始请求完成发布的唯一方法是在请求超时时破坏兔子连接。这样,初始发布将停止,来自客户端的重试请求将不会复制它。但是,对于在整个请求过程中进行的任何异步调用,都需要执行相同类型的手动销毁连接。如果在超时发生时有5个未完成的异步调用,我将需要销毁所有5个异步连接(无论它们是到rabbit、mysql、mongo等的连接)Node.js 请求超时时停止处理请求,node.js,timeout,request,Node.js,Timeout,Request,据我所知,由于Node.js中事件循环的性质,在将请求传递给回调函数之后,无法轻松阻止对其进行处理 由于每个事件回调都没有绑定到任何其他特定的流程或事件,因此一旦回调被添加到事件循环的队列或当前正在处理,即使触发了request.on('timeout')处理程序,它也将继续被处理 如果请求超时,有没有办法停止处理?我能想到的部分解决此问题的唯一方法是在请求期间执行的每个异步回调的顶部添加一个检查,以查看请求是否超时,如果超时,则立即返回并停止后续回调 但是,如果已经有一个从超时请求发出的未完成
然而,问题超出了请求超时时已经建立的连接。即使请求在发布到rabbit之前超时,为处理该请求而调用的函数已经执行,并且不会停止,除非在各个位置进行一些检查,以检查请求是否超时并立即返回。您可能会通过更具体的问题获得更好的答案。而像“mysql查询”这样的技术细节比像“请求”这样含糊不清的非技术性术语更容易讨论 我能想到的部分解决此问题的唯一方法是在请求期间执行的每个异步回调的顶部添加一个检查,以查看请求是否超时,如果超时,则立即返回并停止后续回调 您现在不需要,将来也不需要node.js中的代码。没有人会那样做,因为这不是问题。即使是这样,在堆栈中解决比在应用程序中更低的问题也是有意义的 这在其他编程范例(如PHP+Apache)中不是问题,因为Apache为每个传入的请求创建一个新的PHP进程,因此如果请求超时,进程最终将被终止,整个执行流将停止 这在node.js中甚至不是什么问题,因为对于传入的HTTP请求,甚至没有新进程或新线程。发生的结果本质上是:
- 客户端连接并发送GET请求
- 操作系统接收连接
- 节点接收GET请求
- 假设此时客户端进程(浏览器)在客户端计算机上突然停止
- 具体情况有几个场景。如果浏览器所在的房间断电,则不会有任何东西通过电线传输,在其他情况下,客户端会提前发送数据包以关闭TCP连接
- 但是这在节点端并不重要。您处理请求,进行DB查询,呈现HTML,最糟糕的情况是,一旦工作完成,没有人关心,但这只是一个GET请求。您的应用程序应该每秒执行许多这样的操作。将完成该请求的处理视为“问题”是错误的。这不是一个问题,我听说过的任何东西都不能用任何编程语言来解决它。服务器实际上无法区分刚刚正确等待响应的客户端和200毫秒前断电的客户端。HTTP没有“取消”方法。事实上,完成整个HTTP请求在语义上可能更正确。例如,如果一个web浏览器向您发送了一个完整的信用卡购买HTTP POST,但在您做出响应之前断开了连接,则该交易应一直进行到完成。启动后中止它是不正确的