안녕하세요.
이번 포스팅에서는 외국에 어떤 분이 Go를 활용해 Round Robin 구현 관련 내용이 있어 공유해보려고 합니다.
전체 코드는 다음과 같습니다:)
package schedular
import (
"errors"
"net/url"
"sync/atomic"
)
var ErrorServerNotExist = errors.New("server does not exist")
type roundRobin struct {
urls []*url.URL
next uint64
}
type RoundRobin interface {
Next() *url.URL
}
func New(urls ...*url.URL) (RoundRobin, error) {
if len(urls) == 0 {
return nil, ErrorServerNotExist
}
return &roundRobin{urls: urls}, nil
}
func (r *roundRobin) Next() *url.URL {
n := atomic.AddUint64(&r.next, 1)
return r.urls[(int(n)-1)%len(r.urls)]
}
코드에 대해 설명하겠습니다.
RoundRobin이라는 인터페이스와 roundRobin이라는 구조체를 만들었습니다.
type roundRobin struct {
urls []*url.URL
next uint64
}
type RoundRobin interface {
Next() *url.URL
}
New함수는 roundRobin 구조체를 생성하는 함수이면 인자로 url 배열을 받아 저장합니다. 이때 next에 값은 추가하지 않습니다. 또한, 전달 받은 url 배열에 길이가 0이면 에러를 리턴해줍니다.
func New(urls ...*url.URL) (RoundRobin, error) {
if len(urls) == 0 {
return nil, ErrorServerNotExist
}
return &roundRobin{urls: urls}, nil
}
Next함수는 roundRobin 구조체에 next에 값을 1 더해주고 현재 값을 리턴해줍니다.
func (r *roundRobin) Next() *url.URL {
n := atomic.AddUint64(&r.next, 1)
return r.urls[(int(n)-1)%len(r.urls)]
}
이를 활용해 메인 코드를 작성해보겠습니다.
package main
import (
"Algorithm/schedular"
"log"
"net/url"
)
func main() {
roundRobin, err := schedular.New(
&url.URL{Host: "192.168.33.10"},
&url.URL{Host: "192.168.33.11"}
)
if err != nil {
panic(err)
}
log.Println(roundRobin.Next())
log.Println(roundRobin.Next())
log.Println(roundRobin.Next())
}
실행하셨을 때 다음과 같은 결과가 나오신다면 성공입니다:)
다양한 곳에서 유용하게 쓰일 수 있을거라 생각이 들었습니다. Go 1.18부터 들어오는 제네릭을 활용한다면 좀 더 유연한 코드를 짤 수 있겠다는 생각이 들었습니다.
궁금하신 내용 혹은 잘못된 부분이 있다면 댓글 남겨주시면 감사드리겠습니다!!