1

After researching for these exceptions I have already tried a lot, but none of the suggested solutions has helped for me so far, hence another stackoverflow. Maybe I am missing something.

I am using the 'request' module and I've got 800 requests / second available for a REST Api I want to use. Therefore I wrote a wrapper class which includes rate limiting + methods for all the possible API endpoints. Whenever I try to perform more than ~100 requests / second (either as single instance or cluster) I get exceptions like these returned:

Error: getaddrinfo ENOTFOUND api.domain.com api.domain.com:80

Error:ESOCKETTIMEDOUT

Error: ETIMEDOUT

These are the default options I am using for my requests:

apiRequest = request.defaults({
    headers: {
      Authorization: `Bearer ${this.apiJwt}`,
    },
    json: true,
    timeout: 6000,
    baseUrl: this.baseUrl,
    pool: { maxSockets: Infinity },
  })

// First parameter is priority, second the function to be called, 
// third parameter is the first parameter for the called function
this.limiter.schedulePriority(priority, this.apiRequest, url)

What I've tried:

  1. Putting process.env.UV_THREADPOOL_SIZE = 128 right after my imports in index.js (see: Node.js request module getting ETIMEDOUT and ESOCKETTIMEDOUT)
  2. Adding pool: { maxSockets: Infinity } to the default request options (see code snippet above)
  3. Checking the network throughoutput which is around ~16-25mbps down and 1mbps up. I've got 10mbps upload and 50mbps download available on my localhost.
  4. Starting the application in a cluster of 8 instances where each instance would perform 100 requests / second

Is there something I am missing to perform that many concurrent requests? Maybe the process.env.UV_THREADPOOL_SIZE doesn't get applied (is there a way to check that) correctly?

Community
  • 1
  • 1
kentor
  • 16,553
  • 20
  • 86
  • 144
  • 1
    Try passing `UV_THREADPOOL_SIZE` from your shell: `env UV_THREADPOOL_SIZE=128 node app.js` (or the Windows equivalent). Are you connected to the internet through NAT? If so, you may be exhausting the NAT table of your router. If possible, try using the IP-number of the destination (and set a `Host` header if required) so there aren't any DNS lookups necessary. – robertklep Oct 12 '17 at 12:00
  • I tried setting the UV_THREADPOOL_SIZE using dotenv now, that didn't change anything though. Yes I am connected through NAT, unfortunately I can't use IP addresses as they use virtual hosts (no direct IP access possible). Isn't there a way to cache the resolved DNS lookups instead of performing a DNS request again and again? – kentor Oct 12 '17 at 12:22
  • You can still use IP-addresses if they use virtual hosting, because that works based on what the `Host` header contains (which you can set to the hostname). I'm not sure how DNS-lookups in Node are performed, and if they get cached or not. Also, your OS may also require tweaking (socket buffers and such). – robertklep Oct 12 '17 at 12:23
  • So I changed the baseUrl to `http://10.10.10.10/v1` and added a header called `Host` api.domain.com to the default options. It actually works, but I still receive these ETIMEDOUT and ESOCKETTIMEDOUT exceptions. Do you still have any ideas? – kentor Oct 12 '17 at 12:33
  • 1
    Again, look at NAT tables or network buffers filling up. – robertklep Oct 12 '17 at 12:40
  • You were right it's just my network / uplink here. It's working absolutely fine on the server. – kentor Oct 12 '17 at 14:07

0 Answers0