简体   繁体   English

限制事件驱动的Node.js HTTP请求

[英]Throttling event-driven Nodejs HTTP requests

I have a Node net.Server that listens to a legacy system on a TCP socket. 我有一个节点net.Server ,它侦听TCP套接字上的旧系统。 When a message is received, it sends an http request to another http server. 收到消息后,它将向另一个http服务器发送一个http请求。 Simplified, it looks like this: 简化后,它看起来像这样:

var request = require('request-promise');

...

socket.on('readable', function () {
  var msg = parse(socket.read());
  var postOptions = {
    uri: 'http://example.com/go',
    method: 'POST',
    json: msg,
    headers: {
      'Content-Type': 'application/json'
    }
  };

  request(postOptions);
})

The problem is that the socket is readable about 1000 times per second. 问题是套接字每秒可读取约1000次。 The requests then overload the http server. 然后,请求会使http服务器超载。 Almost immediately, we get multiple-second response times. 几乎立即,我们获得了几秒钟的响应时间。

In running Apache benchmark, it's clear that the http server can handle well over 1000 requests per second in under 100ms response time - if we limit the number of concurrent requests to about 100. 在运行Apache基准测试时,很明显,如果我们将并发请求的数量限制为100个左右,则http服务器可以在100ms的响应时间内每秒处理1000多个请求。

So my question is, what is the best way to limit the concurrent requests outstanding using the request-promise (by extension, request , and core.http.request ) library when each request is fired separately within an event callback? 所以我的问题是,当在事件回调中分别触发每个请求时,使用request-promise (通过扩展, requestcore.http.request )库来限制未完成的并发请求的最佳方法是什么?

Request's documentation says: 请求的文档说:

Note that if you are sending multiple requests in a loop and creating multiple new pool objects, maxSockets will not work as intended. 请注意,如果要在循环中发送多个请求并创建多个新的池对象,则maxSockets将无法按预期工作。 To work around this, either use request.defaults with your pool options or create the pool object with the maxSockets property outside of the loop. 要解决此问题,请在您的池选项中使用request.defaults,或者在循环外使用maxSockets属性创建池对象。

I'm pretty sure that this paragraph is telling me the answer to my problem, but I can't make sense of it. 我很确定本段告诉了我问题的答案,但我无法理解。 I've using defaults to limit the number of sockets open: 我使用默认值来限制打开的套接字数:

var rp = require('request-promise');
var request = rp.defaults({pool: {maxSockets: 50}});

Which doesn't help. 这没有帮助。 My only thought at the moment is to manually manage a queue, but I expect that would be unnecessary if I only knew the conventional way to do it. 目前,我唯一的想法是手动管理队列,但是如果我只知道传统的处理方式,那将是不必要的。

Well you need to throttle your request right? 好吧,您需要限制您的请求吧? I have workaround this in two ways, but let me show you one patter I always use. 我有两种解决方法,但让我向您展示一个我一直使用的模式。 I often use throttle-exec and Promise to make wrapper for request . 我经常使用throttle-execPromise来包装request You could install it with npm install throttle-exec and use Promise natively or third-party. 您可以使用npm install throttle-exec并以本机或第三方方式使用Promise。 Here is my gist for this wrapper https://gist.github.com/ans-4175/d7faec67dc6374803bbc 这是我的包装要点https://gist.github.com/ans-4175/d7faec67dc6374803bbc

How do you use it? 你如何使用它? It's simple, just like ordinary request. 这很简单,就像普通的请求一样。

var Request = require("./Request")
Request({
    url:url_endpoint,
    json:param,
    method:'POST'
})
.then(function(result){
    console.log(result)
})
.catch(reject)

Tell me after you implement it. 实施后告诉我。 Either way I have another wrapper :) 无论哪种方式,我都有另一个包装器:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM