-
-
Save c93614/513d49ff80381fd2852463c656f7b57a to your computer and use it in GitHub Desktop.
Simple TCP load balancer in Go.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"flag" | |
"io" | |
"log" | |
"net" | |
"strings" | |
) | |
type Backends struct { | |
servers []string | |
n int | |
} | |
func (b *Backends) Choose() string { | |
idx := b.n % len(b.servers) | |
b.n++ | |
return b.servers[idx] | |
} | |
func (b *Backends) String() string { | |
return strings.Join(b.servers, ", ") | |
} | |
var ( | |
bind = flag.String("bind", "", "The address to bind on") | |
balance = flag.String("balance", "", "The backend servers to balance connections across, separated by commas") | |
backends *Backends | |
) | |
func init() { | |
flag.Parse() | |
if *bind == "" { | |
log.Fatalln("specify the address to listen on with -bind") | |
} | |
servers := strings.Split(*balance, ",") | |
if len(servers) == 1 && servers[0] == "" { | |
log.Fatalln("please specify backend servers with -backends") | |
} | |
backends = &Backends{servers: servers} | |
} | |
func copy(wc io.WriteCloser, r io.Reader) { | |
defer wc.Close() | |
io.Copy(wc, r) | |
} | |
func handleConnection(us net.Conn, server string) { | |
ds, err := net.Dial("tcp", server) | |
if err != nil { | |
us.Close() | |
log.Printf("failed to dial %s: %s", server, err) | |
return | |
} | |
go copy(ds, us) | |
go copy(us, ds) | |
} | |
func main() { | |
ln, err := net.Listen("tcp", *bind) | |
if err != nil { | |
log.Fatalf("failed to bind: %s", err) | |
} | |
log.Printf("listening on %s, balancing %s", *bind, backends) | |
for { | |
conn, err := ln.Accept() | |
if err != nil { | |
log.Printf("failed to accept: %s", err) | |
continue | |
} | |
go handleConnection(conn, backends.Choose()) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment