httptp

command
v0.0.0-...-81f5a7b Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 5, 2017 License: MIT, MIT Imports: 20 Imported by: 0

README

httptp

httptp is an http(s) proxy and load balancer that saves network bandwidth. It is built on top of httpteleport. It accepts incoming requests at -in address and forwards them to -out addresses. Each request is forwarded to the least loaded healthy -out address.

Any highly loaded http-based API service and microservice may benefit from httptp usage. Here are a few buzzwords related to such services:

Features

  • Easy to use and configure - just run a single httptp binary with required command-line options.

  • Easy integration with the existing HTTP-based API services.

  • httptp is fast. It is based on fasthttp. Easily handles more than 100K qps.

  • May reduce required network bandwidth between servers by up to 10x. I.e.:

    • 10Gbit HTTP traffic may be sent over 1Gbit link.
    • 1Gbit HTTP traffic may be sent over 100Mbit link.
    • 100Mbit HTTP traffic may be sent over 10Mbit link.

    This may have the following benefits:

    • Save a lot of money for expensive inter-datacenter traffic.
    • Free internal network bandwidth for other services.
  • Supports encrypted connections on both -in and -out ends.

  • HTTP keep-alive connections are used by default on both -in and -out ends. httptp easily handles more than 100K of incoming concurrent keep-alive connections.

  • May substitute nginx in reverse proxy mode, load balancer mode and TLS offloading mode.

  • Automatically generates and renews TLS certificates via letsencrypt.org.

  • Automatically adjusts load to upstream servers:

    • Faster servers receive more requests.
    • Slower and unhealthy servers receive less requests.
  • May limit the maximum number of open connections per upstream host.

  • May accept and/or forward http requests from/to unix sockets.

  • Collects and exports various stats at /expvar and /prometheus pages.

  • Easy to extend and customize. httptp is open source software written in Go - easy to read and hack language. It is released under MIT license, so it may be easily customized and extended.

Usage

go get -u github.com/valyala/httpteleport/cmd/httptp
httptp -help

Examples

Reducing network bandwidth between datacenters

Suppose you have an RTB partner sending you 50K requests per second. Each RTB request contains ~2Kb JSON body according to RTB spec. 50K * 2Kb * 8bits = 0.8Gbps network bandwidth is required between the partner and you. In reality the required network bandwidth exceeds 1Gbps due to network protocols overhead. This may be quite expensive if your servers and partner servers are located in distinct datacenters. This also may be limiting factor for growth.

Let's decrease the required network bandwidth and the corresponding expenses by 10x with httptp!

Suppose you have three worker servers hidden behind nginx running on the ip 69.69.69.69:

upstream rtb {
	rtb-server1:80;
	rtb-server2:80;
	rtb-server3:80;

	keepalive 100000;
}

server {
	listen 69.69.69.69:80;
	location / {
		proxy_pass http://rtb;
		proxy_http_version 1.1;
		proxy_set_header Connection "";
	}
}

Then start httptp on port 9876 on the same machine:

httptp -inType=teleport -in=69.69.69.69:9876 -outType=http -out=rtb-server1:80,rtb-server2:80,rtb-server3:80

Ask your partner starting httptp in his local network for proxying RTB traffic to you:

# let's assume httptp is started at the server with local ip 10.10.10.10
httptp -inType=http -in=10.10.10.10:6789 -outType=teleport -out=69.69.69.69:9876

Then the partner may send rtb traffic to 10.10.10.10:6789 in his local network. This traffic will be compressed and proxied to httptp listening 69.69.69.69:9876 in your network. The httptp will spread the traffic across your worker servers set in the -out parameter: rtb-server1:80,rtb-server2:80,rtb-server3:80.

The result: network traffic between you and the partner is decreased by 10x. So the partner may send 10x more RTB requests to you. This may allow you and your partner earning more money :)

Reducing network bandwidth in local networks

The previous example decreased inter-datacenter network traffic. But the amount of local traffic between httptp and worker servers didn't change. httptp may solve the issue - just start httptp on each worker server:

httptp -inType=teleport -in=:8345 -outType=http -out=127.0.0.1:80

Then restart httptp on proxy server, so it would route traffic to just started httptp instances on each worker server:

httptp -inType=teleport -in=69.69.69.69:9876 -outType=teleport -out=rtb-server1:8345,rtb-server2:8345,rtb-server3:8345

Great! What about the partner? It still requires a lot of internal network bandwidth between his servers and httptp running at 10.10.10.10:6789 in his local network.

This issue is easily solved - just run httptp on each of the server, so it bypasses the local httptp at 10.10.10.10:6789 and routes the traffic directly to our httptp at 69.69.69.69:9876:

httptp -inType=http -in=127.0.0.1:5438 -outType=teleport -out=69.69.69.69:9876

Don't forget modifying destination address from 10.10.10.10:6789 to 127.0.0.1:5438 on each of the servers.

Optimizing local inter-process communications

httptp in the previous example routes traffic to a locally running RTB service via 127.0.0.1. This isn't the fastest approach - unix sockets are usually faster. Luckily httptp supports unix sockets out of the box. Just run it on each of the worker server with the following options:

httptp -inType=teleport -in=:8345 -outType=unix -out=/path/to/rtb/unix.socket

RTB servers must be able to accept http traffic from local unix socket /path/to/rtb/unix.socket.

The same optimization applies to partner side:

httptp -inType=unix -in=/path/to/httptp/unix.socket -outType=teleport -out=69.69.69.69:9876

RTB servers must route http traffic to local unix socket /path/to/httptp/unix.socket.

Traffic encryption

In the previous examples RTB traffic is passed unencrypted over public networks when traveling between you and the partner. Luckily httptp supports TLS encryption out of the box - just use teleports traffic type instead of teleport.

Run httptp with the following options on your proxy server:

httptp -inType=teleports -inTLSCert=/path/to/tls.cert -inTLSKey=/path/to/tls.key \
	-in=69.69.69.69:4443 -outType=teleport -out=rtb-server1:8345,rtb-server2:8345,rtb-server3:8345

Note that you must have valid TLS certificate and key files for valid domain name pointing to ip 69.69.69.69. Path to TLS ceritificate file is passed via -inTLSCert, path to TLS key file is passed via -inTLSKey.

And ask your partner restarting httptp on each server with the following options:

httptp -inType=unix -in=/path/to/httptp/unix.socket -outType=teleports -out=domain-name-for.ip.69.69.69.69:4443

Where domain-name-for.ip.69.69.69.69 is a domain name from your certificate.

Batching

By default httptp forwards requests and responses immediately. This means that each request or response results in at least one network packet. Each network packet isn't free:

  • It consumes additional CPU time.
  • It consumes additional network resources.
  • It contains a header overhead, which may be quite big comparing to the request / response size.
  • It may hurt compression - multiple requests / responses are usually compressed better than a single request / response.

httptp allows sending multiple requests / responses in a single packet. This is called batching. Just set non-zero -inDelay and/or -outDelay when starting httptp.

Beware of the following batching issues:

  • Batching may introduce delays.
  • Batching may be useful only for high load, i.e. at least thousands of requests per second. Otherwise it is useless.

Compression

By default httptp compresses both requests and responses. While compression saves network bandwidth, it isn't free - it consumes an additional CPU time.

httptp supports the following compression levels independently for requests and responses via -inCompress and -outCompress options:

  • none - compression is disabled
  • flate - default compression
  • snappy - lightweight compression

Restricting access to httptp

httptp running on your proxy node 69.69.69.69 in examples above accepts incoming connections from any IP address. I.e. anybody across the internet may send requests to it. httptp supports restricting access only to the given IP list - just pass allowed IPs to -inAllowIP option:

httptp -inType=teleport -in=69.69.69.69:9876 -inAllowIP=partner-ip1,partner-ip2 \
	-outType=teleport -out=rtb-server1:8345,rtb-server2:8345,rtb-server3:8345

HTTP load balancing

The following command starts httptp accepting http requests at port 80 and forwarding them to three worker nodes listed in the -out option:

httptp -inType=http -in=:80 -outType=http -out=node1:8080,node2:8080,node3:8080

TLS offloading

The following command starts httptp accepting https requests at port 443 and forwarding them unencrypted to the given -out worker nodes:

httptp -inType=https -in=:443 -outType=http -out=node1:8080,node2:8080,node3:8080

httptp automatically generates and renews TLS certificates for the requested hosts matching -autocertHostRegexp and caches them at the -autocertCacheDir. The certificates are generated using letsencrypt.org.

It is possible using already existing TLS certificates - just pass comma-separated list of certificate paths to -inTLSCert and the corresponding comma-separated list of key paths to -inTLSKey.

Advanced usage

httptp features may be integrated directly into your services. Just use httpteleport package in your clients and/or applications. This will eliminate httptp hops from the path client <-> httptp <-> network <-> httptp <-> your application, thus saving network and CPU resources.

httptp contains other configuration options for advanced usage. See httptp -help for more details:

$ httptp -help
Usage of ./httptp:
  -autocertCacheDir string
    	Path to directory where automatically generated TLS certificates are cached for -inType=https.
	The certificates are generated using https://letsencrypt.org/ (default "autocert-cache")
  -autocertHostRegexp string
    	TLS certificates are automatically generated only for hostnames matching the given regexp (default "^.*$")
  -clientIPHeader string
    	HTTP request header for sending the original client ip.
	For instance, -clientIPHeader=X-Forwarded-For. Empty -clientIPHeader disables sending client ip in request headers
  -concurrency int
    	The maximum number of concurrent requests httptp may process.
	This also limits the maximum number of open connections per -out address if -outType=http or https (default 100000)
  -expvarAddr string
    	TCP address for exporting httptp metrics. They are exported at the following pages:
	http://expvarAddr/expvar - in expvar format
	http://expvarAddr/prometheus - in prometheus format
 (default "localhost:8040")
  -in string
    	-inType address to listen to for incoming requests (default "127.0.0.1:8080")
  -inAllowIP string
    	Comma-separated list of IP addresses allowed for establishing connections to -in.
	All IP addresses are allowed if empty
  -inCompress string
    	Which compression to use for responses if -inType=teleport.
	Supported values:
	none - responses aren't compressed. Low CPU usage at the cost of high network bandwidth
	flate - responses are compressed using flate algorithm. Low network bandwidth at the cost of high CPU usage
	snappy - responses are compressed using snappy algorithm. Balance between network bandwidth and CPU usage (default "flate")
  -inDelay duration
    	How long to wait before sending batched responses back if -inType=teleport
  -inGetOnly
    	Accept only GET -in requests if set to true
  -inMaxBodySize int
    	Maximum body size for -in requests (default 4194304)
  -inMaxHeaderSize int
    	Maximum header size for -in requests (default 4096)
  -inTLSCert string
    	Comma-separated list of paths to TLS certificate files if -inType=https or teleports.
	Certificates for -inType=https are automatically generated using https://letsencrypt.org/ and cached at -autocertCacheDir if empty (default "")
  -inTLSKey string
    	Comma-separated list of paths to TLS key files if -inType=https or teleports.
	Keys for -inType=https are automatically generated using https://letsencrypt.org/ and cached at -autocertCacheDir if empty (default "")
  -inTLSSessionTicketKey string
    	TLS sesssion ticket key if -inType=https or teleports. Automatically generated if empty.
	See https://blog.cloudflare.com/tls-session-resumption-full-speed-and-secure/ for details
  -inType string
    	Type of -in address. Supported values:
	http - accept http requests over TCP, e.g. -in=127.0.0.1:8080
	https - accept https requests over TCP, e.g. -in=127.0.0.1:443
	unix - accept http requests over unix socket, e.g. -in=/var/httptp/sock.unix
	teleport - accept httpteleport connections over TCP, e.g. -in=127.0.0.1:8043
	teleports - accept httpteleport connections over encrypted TCP, e.g. -in=127.0.0.1:8443 (default "http")
  -logAllErrors
    	Log all the error while serving clients. This option may be useful for debugging
  -out string
    	Comma-separated list of -outType addresses to forward requests to.
	Each request is forwarded to the least loaded address (default "127.0.0.1:8043")
  -outCompress string
    	Which compression to use for requests if -outType=teleport.
	Supported values:
	none - requests aren't compressed. Low CPU usage at the cost of high network bandwidth
	flate - requests are compressed using flate algorithm. Low network bandwidth at the cost of high CPU usage
	snappy - requests are compressed using snappy algorithm. Balance between network bandwidth and CPU usage (default "flate")
  -outConnsPerAddr int
    	How many connections must be established per each -out server if -outType=teleport.
	Usually a single connection is enough. Increase this value if the compression
	on the connection occupies 100% of a single CPU core.
	Alternatively, -inCompress and/or -outCompress may be set to snappy or none in order to reduce CPU load (default 1)
  -outDelay duration
    	How long to wait before forwarding incoming requests to -out if -outType=teleport
  -outMaxHeaderSize int
    	Maximum header size for -out responses (default 4096)
  -outTimeout duration
    	The maximum duration for waiting responses from -out server (default 3s)
  -outType string
    	Type of -out address. Supported values:
	http - forward requests to http servers on TCP, e.g. -out=127.0.0.1:80
	https - forward requests to https servers on TCP, e.g -out=127.0.0.1:443
	unix - forward requests to http servers on unix socket, e.g. -out=/var/nginx/sock.unix
	teleport - forward requests to httpteleport servers over TCP, e.g. -out=127.0.0.1:8043
	tepelorts - forward requests to httpteleport servers over encrypted TCP, e.g. -out=127.0.0.1:8043. The server must properly set -inTLS* flags in order to accept encrypted TCP connections (default "teleport")
  -reusePort
    	Whether to enable SO_REUSEPORT on -in if -inType is http or teleport

Documentation

The Go Gopher

There is no documentation for this package.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL