👣 Тестовое задание на разработки балансировщика нагрузки на Go



В данном случае используется довольно простой алгоритм Round-Robin.



Начнем с базового объекта server, который содержит 3 атрибута, связанных с сервером



Address()

IsAlive()

Функция Serve() для работы с запросами



type Server interface {

Address() string

IsAlive() bool

Serve(rw http.ResponseWriter, req *http.Request)

}




В дальнейшем используется второй тип объекта – simpleServer.



type simpleServer struct {

addr string

proxy *httputil.ReverseProxy

}




После определения методов, используемых в указанных объектах, мы создаем loadbalancer вместе с функцией getNextAvailableServer().

func NewLoadBalancer(port string, servers []Server) *LoadBalancer {

return &LoadBalancer{

port: port,

roundRobinCount: 0,

servers: servers,

}

}




func (lb *LoadBalancer) getNextAvailableServer() Server {

server := lb.servers[lb.roundRobinCount%len(lb.servers)]

for !server.IsAlive() {

lb.roundRobinCount++

server = lb.servers[lb.roundRobinCount%len(lb.servers)]

}

lb.roundRobinCount++

return server

}




Вызываем main()

func main() {

servers := []Server{

newSimpleServer("https://snapcraft.io"),

newSimpleServer("https://github.com/sambhavsaxena"),

newSimpleServer("http://localhost:3001"),

}

lb := NewLoadBalancer("3000", servers)

handleRedirect := func(rw http.ResponseWriter, req *http.Request) {

lb.serveProxy(rw, req)

}

http.HandleFunc("/", handleRedirect)

fmt.Printf("distributing requests fired at 'localhost:%s'\n", lb.port)

http.ListenAndServe(":"+lb.port, nil)

}




Статья

Полный код



@golang_interview