Created
June 16, 2013 05:05
-
-
Save darkhelmet/5790838 to your computer and use it in GitHub Desktop.
Simple TCP load balancer in Go.
This file contains 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