fproxy is a generic tcp, load-balacing, IPv6-ready (reverse) proxy, which can
operate on Unix sockets as well. It claims to be fast, since it avoids forking
for each connection. Instead, it uses the epoll framework and splice provided
by recent versions of Linux (support for kqueue on FreeBSD may come some day).
Configuration is done through command line parameters only. For
reconfiguration, you have to send a SIGQUIT to the running instance of fproxy
to exit nicely, and then start with modified parameters. To avoid service
downtime, you can run two or more instances in parallel, even if they are
bound to the same cluster address (read: same listening socket). If you send
SIGHUP, it will close and re-open its log and errorlog files. On SIGTERM it
will exit immediately.
If compiled with -DUSE_SPLICE, fproxy will use splice() instead of
read()/write(), but will also disable Unix sockets.
If compiled with -DUSE_LOCALTIME, timestamps will be in local time
instead of GMT, although GMT avoids calling stat() on /etc/localtime
every second.
fproxy V0.7 - non-forking tcp proxy using the epoll() framework Compile time flags: DIETLIBC USE_SPLICE fproxy [-o<logfile>] [-e<errorlog>] [-p<pidfile>] [-f] [-d] [-y<# bytes>] [-t<timeout>] [-g<grace>] [-s0] [-s1] [-s2] [-s3] [-s4] <cluster[:port]> [ ... ] -- <backend[:port]> [ ... ] fproxy -h -h this help ;-) -o<logfile> use <logfile> for logging instead of /var/log/fproxy.log -e<errorlog> use <errorlog> for error messages instead of /var/log/fproxy.err -p<pidfile> write process id into <pidfile>, not into /var/run/fproxy.pid -f do not fork and detach from controlling terminal; do not use pidfile -d do not fork and detach from controlling terminal; do use neither logfile, errorlog, nor pidfile -y<# bytes> open new connection to backend servers only if the client wrote <# bytes>, eg. use -y6 for preventing a SYN attack against a webserver (nb. strlen("GET /\n") = 6); -y0 disables this feature, which is also the default -t<timeout> drop idle client connections after <timeout> seconds; -t0 disables timeout handling, which is also the default -g<grace> reenables a failed backend after <grace> seconds; defaults to 60 seconds -s0 select backends in a round robin fashion -s1 select backend with least connections handled so far -s2 select backend with least bytes (in + out) processed so far -s3 select backend with least connection time consumed so far -s4 (default) select backend in a weighted fashion, using number of connections, processed bytes and connection time to calculate to workload of each backend <cluster[:port]> path to Unix socket, or IPv4 or IPv6 address w/ optional tcp port on which this machine accepts connections; surround IPv6 addresses in square brackets; port defaults to 80 <backend[:port]> path to Unix socket, or IPv4 or IPv6 address w/ optional tcp port to which client connections be proxied; surround IPv6 addresses in square brackets; port defaults to 80 send SIGHUP to reopen logfile and errorlog send SIGQUIT to exit nicely (don't accept any new client connections, wait for active connections to finish normally) send SIGTERM to exit immediatelly
redirect all web traffic on localhost to three backends:
$ ./fproxy 127.0.0.1 -- 192.168.1.10 192.168.1.11 192.168.1.12
fproxy utilizes a httpd-like log format:
127.0.0.1 - - [31/Jul/2011:13:00:00 +0200] "POST 192.168.0.1" 200 848 8 940087 8where:
127.0.0.1 | client's ip address |
- - | ident user and authuser are always unset |
[31/Jul/2011:13:00:00 +0200] | date, time, and offset from UTC when the client disconnected |
POST | request method; GET if command line argument -y is zero, POST otherwise |
192.168.0.1 | backend's ip address |
200 | status code |
848 | number of bytes received from the client |
8 | number of seconds the client was connected |
9400087 | number of bytes received from the backend |
8 | number of seconds the backend was connected |