2

I have a set of SOCKS proxies, which are sitting behind a load balancer (an AWS Network Load Balancer, to be specific). When the load balancer receives a request on the SOCKS port, it forwards the request to the Docker container (proxy) with the fewest active connections.

I have a Go application that uses the standard HTTP package. I'd like to use the built-in support that this package has for SOCKS proxies, and point it to my load balancer's address.

My question is, does the Go HTTP client:

  1. Open and maintain a TCP connection to the SOCKS proxy I point it to (a single TCP connection for all HTTP connections that it keeps open),
  2. Open and maintain a TCP connection to the SOCKS proxy for each HTTP connection (i.e. a one-to-one relationship of SOCKS proxy connections to open/idle HTTP connections),
  3. Open and subsequently close a TCP connection to the SOCKS proxy for each HTTP/S request, regardless of the concurrent/idle connection settings on the HTTP client, or
  4. Do something else entirely?

If the answer is (1) or (2), is there a way to prevent this behavior and ensure it always re-connects to the SOCKS proxy for each HTTP/S request?

The reason I'd like to do this is to ensure that the requests are balanced across the many proxies, instead of the clients (each of which may have many concurrent requests) being balanced across the proxies.

Specifically, say I have 3 proxies behind the load balancer, labeled A, B, and C. And say I have two applications, 1 and 2. Application 1 makes 5 HTTP requests per second, and Application 2 makes 500 HTTP requests per second.

What I want to avoid is having Application 1 make a SOCKS connection to the load balancer, and having it forwarded to proxy A, and that connection to the proxy being maintained, while Application 2 makes a SOCKS connection to the load balancer and has it forwarded to proxy B, which is also maintained. If that occurs, proxy A will be handling 5 requests/second while proxy B will be handling 500 requests/second, which is obviously massively imbalanced. I'd rather all three proxies each get ~168 requests/second.

Jordan
  • 3,998
  • 9
  • 45
  • 81

1 Answers1

1

SOCKS is protocol agnostic. It has no idea of what a HTTP request is but only what a TCP connection is which gets tunneled by the proxy. Thus every TCP connection caused by the HTTP stack will mean a new connection through the proxy - no reuse. If you want to make sure that every HTTP/S requests gets its own connection through the proxy you must disable HTTP keep-alive. See this question on how to do this.

Steffen Ullrich
  • 114,247
  • 10
  • 131
  • 172
  • OK, so would it be fair to say that point (2) in my question is most accurate? i.e. it's a 1-to-1 relationship; every connection that the HTTP client opens and maintains is a SOCKS proxy connection that gets opened and maintained? – Jordan Jun 30 '22 at 23:12
  • @Jordan: correct, each TCP connection created by the HTTP client means a new tunnel over the SOCKS proxy. – Steffen Ullrich Jul 01 '22 at 03:25
  • I've been working on this, but some odd behaviour is happening. I have a single HTTP client/transport that's being used by several hundred different goroutines, all making concurrent requests (to the same server). The latency is high (other side of the world) and these routines are doing no other work, so realistically there should be at least 100 open connections on this HTTP client at any given time. Even so, my load balancer metrics are showing a single open connection from the application. It seems like all of the HTTP connections on the client are using the same SOCKS tunnel. – Jordan Jul 09 '22 at 18:05
  • @Jordan: I think this description needs to be more detailed, i.e. description of your setup and specifically the role of the load balancer in it and also the code of your client. Better ask a new question with all these details. – Steffen Ullrich Jul 10 '22 at 05:12