Создание балансировщика нагрузки в Go
Здравствуйте,
Я начал свой путь в программировании с Javascript, но позже понял, что есть другие мощные инструменты и пакеты, позволяющие создавать вещи, которые невозможно создать только на JS. Поэтому я начал усердно изучить Golang и узнал, что огромные организации используют Go для настройки своих серверных приложений.
Это привело меня к созданию собственной программы-балансировщика нагрузки на 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)
}
Вот и все!
Полный код здесь