Loadcat으로 간소화된 NGINX 로드 밸런싱

게시 됨: 2022-03-11

수평으로 확장 가능하도록 설계된 웹 애플리케이션에는 종종 하나 이상의 로드 밸런싱 노드가 필요합니다. 주요 목적은 들어오는 트래픽을 공정한 방식으로 사용 가능한 웹 서버에 배포하는 것입니다. 단순히 노드 수를 늘리고 로드 밸런서가 이러한 변경 사항에 적응하도록 하여 웹 애플리케이션의 전체 용량을 늘리는 기능은 프로덕션에서 매우 유용한 것으로 판명될 수 있습니다.

NGINX는 다른 많은 기능 중에서 고성능 로드 밸런싱 기능을 제공하는 웹 서버입니다. 이러한 기능 중 일부는 구독 모델의 일부로만 사용할 수 있지만 무료 및 오픈 소스 버전은 여전히 ​​기능이 풍부하고 가장 기본적인 로드 밸런싱 기능이 함께 제공됩니다.

Loadcat으로 간소화된 NGINX 로드 밸런싱

Loadcat으로 간소화된 NGINX 로드 밸런싱
트위터

이 튜토리얼에서는 NGINX 인스턴스를 로드 밸런서로 작동하도록 구성할 수 있는 실험적 도구의 내부 메커니즘을 탐색하고 깔끔한 웹을 제공하여 NGINX 구성 파일의 모든 핵심 세부 정보를 추상화합니다. 기반 사용자 인터페이스. 이 기사의 목적은 그러한 도구를 구축하는 것이 얼마나 쉬운지 보여주는 것입니다. Loadcat 프로젝트가 Linode의 NodeBalancers에서 크게 영감을 받았다는 점을 언급할 가치가 있습니다.

NGINX, 서버 및 업스트림

NGINX의 가장 널리 사용되는 용도 중 하나는 클라이언트에서 웹 서버 애플리케이션으로 요청을 역 프록시하는 것입니다. Node.js 및 Go와 같은 프로그래밍 언어로 개발된 웹 애플리케이션은 자급자족할 수 있는 웹 서버일 수 있지만 실제 서버 애플리케이션 앞에 리버스 프록시가 있으면 많은 이점이 있습니다. NGINX 구성 파일에서 이와 같은 간단한 사용 사례에 대한 "서버" 블록은 다음과 같이 보일 수 있습니다.

 server { listen 80; server_name example.com; location / { proxy_pass http://192.168.0.51:5000; } }

이렇게 하면 NGINX가 example.com을 가리키는 모든 요청에 ​​대해 포트 80에서 수신 대기하고 각각을 192.168.0.51:5000에서 실행되는 일부 웹 서버 응용 프로그램에 전달합니다. 웹 애플리케이션 서버가 로컬에서 실행 중인 경우 루프백 IP 주소 127.0.0.1을 사용할 수도 있습니다. 위의 스니펫에는 역 프록시 구성에서 자주 사용되는 몇 가지 분명한 조정이 없지만 간결함을 위해 이 방식으로 유지됩니다.

그러나 동일한 웹 응용 프로그램 서버의 두 인스턴스 간에 들어오는 모든 요청의 균형을 유지하려면 어떻게 해야 할까요? 여기서 "upstream" 지시문이 유용합니다. NGINX에서 "upstream" 지시문을 사용하면 NGINX가 들어오는 모든 요청의 균형을 맞출 여러 백엔드 노드를 정의할 수 있습니다. 예를 들어:

 upstream nodes { server 192.168.0.51:5000; server 192.168.0.52:5000; } server { listen 80; server_name example.com; location / { proxy_pass http://nodes; } }

두 개의 서버로 구성된 "노드"라는 이름의 "업스트림" 블록을 어떻게 정의했는지 주목하십시오. 각 서버는 IP 주소와 수신 대기 중인 포트 번호로 식별됩니다. 이를 통해 NGINX는 가장 단순한 형태의 로드 밸런서가 됩니다. 기본적으로 NGINX는 들어오는 요청을 라운드 로빈 방식으로 배포합니다. 여기서 첫 번째 요청은 첫 번째 서버로, 두 번째 요청은 두 번째 서버로, 세 번째 요청은 첫 번째 서버로 프록시 처리되는 식입니다.

그러나 NGINX는 로드 밸런싱과 관련하여 훨씬 더 많은 것을 제공합니다. 이를 통해 각 서버에 대한 가중치를 정의하고, 일시적으로 사용할 수 없는 것으로 표시하고, 다른 균형 알고리즘을 선택할 수 있습니다(예: 클라이언트의 IP 해시를 기반으로 작동하는 알고리즘이 있음). 이러한 기능 및 구성 지시문은 모두 nginx.org에 문서화되어 있습니다. . 또한 NGINX를 사용하면 거의 중단 없이 구성 파일을 즉시 변경하고 다시 로드할 수 있습니다.

NGINX의 구성 가능성과 간단한 구성 파일을 사용하면 많은 요구 사항에 쉽게 적용할 수 있습니다. 그리고 NGINX를 로드 밸런서로 구성하는 방법을 정확히 알려주는 수많은 자습서가 이미 인터넷에 있습니다.

Loadcat: NGINX 구성 도구

스스로 무언가를 하는 대신 다른 도구를 구성하여 수행하도록 하는 프로그램에는 매력적인 것이 있습니다. 그들은 사용자 입력을 받고 몇 개의 파일을 생성하는 것 외에는 많은 일을 하지 않습니다. 이러한 도구에서 얻는 대부분의 이점은 사실 다른 도구의 기능입니다. 그러나 그들은 확실히 삶을 쉽게 만듭니다. 내 프로젝트 중 하나를 위해 로드 밸런서를 설정하려고 하는 동안 NGINX 및 로드 밸런싱 기능에 대해 유사한 작업을 수행하지 않는 이유가 무엇인지 궁금했습니다.

로드캣 탄생!

Go로 구축된 Loadcat은 아직 초기 단계입니다. 현재 이 도구를 사용하면 로드 밸런싱 및 SSL 종료 전용으로 NGINX를 구성할 수 있습니다. 사용자를 위한 간단한 웹 기반 GUI를 제공합니다. 도구의 개별 기능을 살펴보는 대신 아래에 있는 내용을 살펴보겠습니다. 그러나 누군가가 NGINX 구성 파일을 손으로 작업하는 것을 좋아한다면 그러한 도구에서 거의 가치를 찾지 못할 수도 있습니다.

이를 위한 프로그래밍 언어로 Go를 선택한 데에는 몇 가지 이유가 있습니다. 그 중 하나는 Go가 컴파일된 바이너리를 생성한다는 것입니다. 이를 통해 종속성 해결에 대한 걱정 없이 Loadcat을 컴파일된 바이너리로 빌드 및 배포하거나 원격 서버에 배포할 수 있습니다. 설정 프로세스를 크게 단순화하는 것입니다. 물론 바이너리는 NGINX가 이미 설치되어 있고 이를 위한 시스템 단위 파일이 있다고 가정합니다.

Go 엔지니어가 아니더라도 전혀 걱정하지 마십시오. Go는 시작하기에 매우 쉽고 재미있습니다. 또한 구현 자체가 매우 간단하여 쉽게 따라할 수 있어야 합니다.

구조

Go 빌드 도구는 애플리케이션을 구성하는 방법에 몇 가지 제한을 부과하고 나머지는 개발자에게 맡깁니다. 우리의 경우 목적에 따라 몇 가지 Go 패키지로 나눴습니다.

  • cfg: 구성 값을 로드, 구문 분석 및 제공합니다.
  • cmd/loadcat: 기본 패키지, 진입점 포함, 바이너리로 컴파일
  • 데이터: "모델"을 포함하고 지속성을 위해 내장된 키/값 저장소를 사용합니다.
  • 고양이: 구성 파일 생성, 재로드 메커니즘 등과 같은 핵심 기능을 포함합니다.
  • ui: 템플릿, URL 처리기 등을 포함합니다.

특히 feline 패키지 내에서 패키지 구조를 자세히 살펴보면 모든 NGINX 특정 코드가 feline/nginx 하위 패키지 내에 보관되었음을 알 수 있습니다. 이는 나머지 애플리케이션 로직을 일반으로 유지하고 향후 다른 로드 밸런서(예: HAProxy)에 대한 지원을 확장할 수 있도록 수행됩니다.

진입 지점

"cmd/loadcatd"에 있는 Loadcat의 기본 패키지부터 시작하겠습니다. 애플리케이션의 진입점인 주요 기능은 세 가지를 수행합니다.

 func main() { fconfig := flag.String("config", "loadcat.conf", "") flag.Parse() cfg.LoadFile(*fconfig) feline.SetBase(filepath.Join(cfg.Current.Core.Dir, "out")) data.OpenDB(filepath.Join(cfg.Current.Core.Dir, "loadcat.db")) defer data.DB.Close() data.InitDB() http.Handle("/api", api.Router) http.Handle("/", ui.Router) go http.ListenAndServe(cfg.Current.Core.Address, nil) // Wait for an “interrupt“ signal (Ctrl+C in most terminals) }

작업을 단순하게 유지하고 코드를 읽기 쉽게 하기 위해 모든 오류 처리 코드는 위의 스니펫(및 이 문서의 뒷부분)에서 제거되었습니다.

코드에서 알 수 있듯이 "-config" 명령줄 플래그(기본값은 현재 디렉터리에서 "loadcat.conf"로 설정됨)를 기반으로 구성 파일을 로드하고 있습니다. 다음으로 몇 가지 구성 요소, 즉 핵심 고양이 패키지와 데이터베이스를 초기화합니다. 마지막으로 웹 기반 GUI용 웹 서버를 시작합니다.

구성

구성 파일을 로드하고 구문 분석하는 것은 여기에서 아마도 가장 쉬운 부분일 것입니다. TOML을 사용하여 구성 정보를 인코딩합니다. Go에 사용할 수 있는 깔끔한 TOML 구문 분석 패키지가 있습니다. 사용자로부터 필요한 구성 정보는 거의 없으며 대부분의 경우 이러한 값에 대한 정상적인 기본값을 결정할 수 있습니다. 다음 구조체 는 구성 파일의 구조를 나타냅니다.

 struct { Core struct { Address string Dir string Driver string } Nginx struct { Mode string Systemd struct { Service string } } }

그리고 일반적인 "loadcat.conf" 파일은 다음과 같습니다.

 [core] address=":26590" dir="/var/lib/loadcat" driver="nginx" [nginx] mode="systemd" [nginx.systemd] service="nginx.service"

우리가 볼 수 있듯이 TOML로 인코딩된 구성 파일의 구조 와 그 위에 표시된 구조 사이에는 유사점이 있습니다. 구성 패키지는 구조체 의 특정 필드에 대해 정상적인 기본값을 설정하는 것으로 시작한 다음 구성 파일을 구문 분석합니다. 지정된 경로에서 구성 파일을 찾지 못한 경우 구성 파일을 만들고 그 안에 있는 기본값을 먼저 덤프합니다.

 func LoadFile(name string) error { f, _ := os.Open(name) if os.IsNotExist(err) { f, _ = os.Create(name) toml.NewEncoder(f).Encode(Current) f.Close() return nil } toml.NewDecoder(f).Decode(&Current) return nil }

데이터 및 지속성

볼트를 만나보세요. 순수한 Go로 작성된 임베디드 키/값 저장소입니다. 매우 간단한 API가 포함된 패키지로 제공되며 즉시 사용 가능한 트랜잭션을 지원하며 매우 빠릅니다 .

패키지 데이터 내에는 각 엔터티 유형을 나타내는 구조체 가 있습니다. 예를 들어 다음이 있습니다.

 type Balancer struct { Id bson.ObjectId Label string Settings BalancerSettings } type Server struct { Id bson.ObjectId BalancerId bson.ObjectId Label string Settings ServerSettings }

… 여기서 Balancer 의 인스턴스는 단일 로드 밸런서를 나타냅니다. Loadcat을 사용하면 NGINX의 단일 인스턴스를 통해 여러 웹 애플리케이션에 대한 요청의 균형을 효과적으로 조정할 수 있습니다. 모든 밸런서는 그 뒤에 하나 이상의 서버를 가질 수 있으며, 여기서 각 서버는 별도의 백엔드 노드가 될 수 있습니다.

Bolt는 키-값 저장소이고 고급 데이터베이스 쿼리를 지원하지 않기 때문에 이를 수행하는 애플리케이션 측 논리가 있습니다. Loadcat은 각각에 수천 대의 서버가 있는 수천 개의 밸런서를 구성하기 위한 것이 아니므로 자연스럽게 이 순진한 접근 방식이 잘 작동합니다. 또한 Bolt는 바이트 슬라이스인 키와 값으로 작동하므로 Bolt에 저장하기 전에 구조체 를 BSON 인코딩합니다. 데이터베이스에서 Balancer 구조체 목록을 검색하는 함수의 구현은 다음과 같습니다.

 func ListBalancers() ([]Balancer, error) { bals := []Balancer{} DB.View(func(tx *bolt.Tx) error { b := tx.Bucket([]byte("balancers")) c := b.Cursor() for k, v := c.First(); k != nil; k, v = c.Next() { bal := Balancer{} bson.Unmarshal(v, &bal) bals = append(bals, bal) } return nil }) return bals, nil }

ListBalancers 함수는 읽기 전용 트랜잭션을 시작하고 "balancers" 버킷 내의 모든 키와 값을 반복하고 각 값을 Balancer 구조체 의 인스턴스로 디코딩하고 배열로 반환합니다.

버킷에 밸런서를 저장하는 것도 거의 똑같이 간단합니다.

 func (l *Balancer) Put() error { if !l.Id.Valid() { l.Id = bson.NewObjectId() } if l.Label == "" { l.Label = "Unlabelled" } if l.Settings.Protocol == "https" { // Parse certificate details } else { // Clear fields relevant to HTTPS only, such as SSL options and certificate details } return DB.Update(func(tx *bolt.Tx) error { b := tx.Bucket([]byte("balancers")) p, err := bson.Marshal(l) if err != nil { return err } return b.Put([]byte(l.Id.Hex()), p) }) }

Put 함수는 일부 기본값을 특정 필드에 할당하고, HTTPS 설정에서 연결된 SSL 인증서를 구문 분석하고, 트랜잭션을 시작하고, 구조체 인스턴스를 인코딩하고, 밸런서의 ID에 대해 버킷에 저장합니다.

SSL 인증서를 구문 분석하는 동안 표준 패키지 인코딩/pem을 사용하여 두 가지 정보가 추출되고 설정 필드 아래의 SSLOptions 에 저장됩니다. DNS 이름과 지문입니다.

밸런서별로 서버를 조회하는 기능도 있습니다.

 func ListServersByBalancer(bal *Balancer) ([]Server, error) { srvs := []Server{} DB.View(func(tx *bolt.Tx) error { b := tx.Bucket([]byte("servers")) c := b.Cursor() for k, v := c.First(); k != nil; k, v = c.Next() { srv := Server{} bson.Unmarshal(v, &srv) if srv.BalancerId.Hex() != bal.Id.Hex() { continue } srvs = append(srvs, srv) } return nil }) return srvs, nil }

이 기능은 우리의 접근 방식이 실제로 얼마나 순진한지를 보여줍니다. 여기서 우리는 어레이를 반환하기 전에 전체 "서버" 버킷을 효과적으로 읽고 관련 없는 엔터티를 필터링하고 있습니다. 그러나 다시 말하지만 이것은 잘 작동하며 변경할 실제 이유가 없습니다.

서버용 Put 함수는 기본값과 계산된 필드를 설정하는 많은 코드 줄을 필요로 하지 않기 때문에 Balancer 구조체 의 함수보다 훨씬 간단합니다.

NGINX 제어

Loadcat을 사용하기 전에 생성된 구성 파일을 로드하도록 NGINX를 구성해야 합니다. Loadcat은 밸런서의 ID(짧은 16진 문자열)로 디렉토리 아래 각 밸런서에 대해 "nginx.conf" 파일을 생성합니다. 이 디렉토리는 cwd 의 "out" 디렉토리 아래에 생성됩니다. 따라서 생성된 구성 파일을 로드하도록 NGINX를 구성하는 것이 중요합니다. 이것은 "http" 블록 내에서 "include" 지시문을 사용하여 수행할 수 있습니다.

/etc/nginx/nginx.conf를 편집하고 "http" 블록 끝에 다음 줄을 추가합니다.

 http { include /path/to/out/*/nginx.conf; }

이렇게 하면 NGINX가 "/path/to/out/" 아래에 있는 모든 디렉토리를 검색하고 각 디렉토리에서 "nginx.conf"라는 파일을 찾은 다음 찾은 각 파일을 로드합니다.

핵심 패키지인 feline에서 인터페이스 Driver 를 정의합니다. 올바른 서명과 함께 생성다시 로드 라는 두 가지 기능을 제공하는 모든 구조체 는 드라이버로 간주됩니다.

 type Driver interface { Generate(string, *data.Balancer) error Reload() error }

예를 들어, feline/nginx 패키지 아래의 구조체 Nginx 는 다음과 같습니다.

 type Nginx struct { sync.Mutex Systemd *dbus.Conn } func (n Nginx) Generate(dir string, bal *data.Balancer) error { // Acquire a lock on n.Mutex, and release before return f, _ := os.Create(filepath.Join(dir, "nginx.conf")) TplNginxConf.Execute(f, /* template parameters */) f.Close() if bal.Settings.Protocol == "https" { // Dump private key and certificate to the output directory (so that Nginx can find them) } return nil } func (n Nginx) Reload() error { // Acquire a lock on n.Mutex, and release before return switch cfg.Current.Nginx.Mode { case "systemd": if n.Systemd == nil { c, err := dbus.NewSystemdConnection() n.Systemd = c } ch := make(chan string) n.Systemd.ReloadUnit(cfg.Current.Nginx.Systemd.Service, "replace", ch) <-ch return nil default: return errors.New("unknown Nginx mode") } }

생성 은 출력 디렉토리에 대한 경로와 Balancer 구조체 인스턴스에 대한 포인터를 포함하는 문자열로 호출할 수 있습니다. Go는 NGINX 드라이버가 최종 NGINX 구성 파일을 생성하는 데 사용하는 텍스트 템플릿을 위한 표준 패키지를 제공합니다. 템플릿은 "업스트림" 블록과 밸런서 구성 방식에 따라 생성된 "서버" 블록으로 구성됩니다.

 var TplNginxConf = template.Must(template.New("").Parse(` upstream {{.Balancer.Id.Hex}} { {{if eq .Balancer.Settings.Algorithm "least-connections"}} least_conn; {{else if eq .Balancer.Settings.Algorithm "source-ip"}} ip_hash; {{end}} {{range $srv := .Balancer.Servers}} server {{$srv.Settings.Address}} weight={{$srv.Settings.Weight}} {{if eq $srv.Settings.Availability "available"}}{{else if eq $srv.Settings.Availability "backup"}}backup{{else if eq $srv.Settings.Availability "unavailable"}}down{{end}}; {{end}} } server { {{if eq .Balancer.Settings.Protocol "http"}} listen {{.Balancer.Settings.Port}}; {{else if eq .Balancer.Settings.Protocol "https"}} listen {{.Balancer.Settings.Port}} ssl; {{end}} server_name {{.Balancer.Settings.Hostname}}; {{if eq .Balancer.Settings.Protocol "https"}} ssl on; ssl_certificate {{.Dir}}/server.crt; ssl_certificate_key {{.Dir}}/server.key; {{end}} location / { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_pass http://{{.Balancer.Id.Hex}}; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; } } `))

Reload 는 NGINX가 구성 파일을 다시 로드하도록 하는 Nginx 구조체 의 다른 기능입니다. 사용되는 메커니즘은 Loadcat이 구성된 방식을 기반으로 합니다. 기본적으로 NGINX는 [sudo] systemd reload nginx.service 가 작동하도록 nginx.service로 실행되는 시스템 서비스라고 가정합니다. 그러나 쉘 명령을 실행하는 대신 github.com/coreos/go-systemd/dbus 패키지를 사용하여 D-Bus를 통해 systemd에 연결합니다.

웹 기반 GUI

이 모든 구성 요소가 제자리에 있으면 일반 Bootstrap 사용자 인터페이스로 모든 것을 마무리합니다.

간단한 GUI로 포장된 NGINX 로드 밸런싱 기능

간단한 GUI로 포장된 NGINX 로드 밸런싱 기능
트위터

이러한 기본 기능의 경우 몇 가지 간단한 GET 및 POST 경로 처리기로 충분합니다.

 GET /balancers GET /balancers/new POST /balancers/new GET /balancers/{id} GET /balancers/{id}/edit POST /balancers/{id}/edit GET /balancers/{id}/servers/new POST /balancers/{id}/servers/new GET /servers/{id} GET /servers/{id}/edit POST /servers/{id}/edit

각각의 개별 경로를 살펴보는 것은 여기에서 하는 가장 흥미로운 일이 아닐 수도 있습니다. 왜냐하면 이것들은 거의 CRUD 페이지이기 때문입니다. 패키지 ui 코드를 살펴보고 이러한 각 경로에 대한 처리기가 어떻게 구현되었는지 확인하십시오.

각 핸들러 함수는 다음 중 하나를 수행하는 루틴입니다.

  • 데이터 저장소에서 데이터를 가져오고 렌더링된 템플릿으로 응답합니다(가져온 데이터 사용).
  • 들어오는 양식 데이터를 구문 분석하고 데이터 저장소에서 필요한 변경을 수행하고 고양이 패키지를 사용하여 NGINX 구성 파일을 재생성합니다.

예를 들어:

 func ServeServerNewForm(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) bal, _ := data.GetBalancer(bson.ObjectIdHex(vars["id"])) TplServerNewForm.Execute(w, struct { Balancer *data.Balancer }{ Balancer: bal, }) } func HandleServerCreate(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) bal, _ := data.GetBalancer(bson.ObjectIdHex(vars["id"])) r.ParseForm() body := struct { Label string `schema:"label"` Settings struct { Address string `schema:"address"` } `schema:"settings"` }{} schema.NewDecoder().Decode(&body, r.PostForm) srv := data.Server{} srv.BalancerId = bal.Id srv.Label = body.Label srv.Settings.Address = body.Settings.Address srv.Put() feline.Commit(bal) http.Redirect(w, r, "/servers/"+srv.Id.Hex()+"/edit", http.StatusSeeOther) }

ServeServerNewForm 함수가 하는 모든 일은 데이터 저장소에서 밸런서를 가져오고 밸런서의 Servers 함수를 사용하여 관련 서버 목록을 검색하는 템플릿(이 경우 TplServerList )을 렌더링하는 것입니다.

반면에 HandleServerCreate 함수는 본체에서 구조체 로 들어오는 POST 페이로드를 구문 분석하고 해당 데이터를 사용하여 패키지 고양이를 사용하여 밸런서에 대한 NGINX 구성 파일을 재생성하기 전에 데이터 저장소에서 새 Server 구조체 를 인스턴스화하고 유지합니다.

모든 페이지 템플릿은 "ui/templates.go" 파일에 저장되며 해당 템플릿 HTML 파일은 "ui/templates" 디렉토리에서 찾을 수 있습니다.

그것을 밖으로 시도

Loadcat을 원격 서버 또는 로컬 환경에 배포하는 것은 매우 쉽습니다. Linux(64비트)를 실행하는 경우 저장소의 릴리스 섹션에서 사전 빌드된 Loadcat 바이너리로 아카이브를 가져올 수 있습니다. 약간 모험심이 느껴진다면 리포지토리를 복제하고 코드를 직접 컴파일할 수 있습니다. 그러나 이 경우의 경험은 Go 프로그램을 컴파일하는 것이 실제로 어려운 일이 아니기 때문에 약간 실망스러울 수 있습니다. Arch Linux를 실행하는 경우 운이 좋은 것입니다! 배포의 편의를 위해 패키지를 만들었습니다. 다운로드하고 패키지 관리자를 사용하여 설치하기만 하면 됩니다. 관련된 단계는 프로젝트의 README.md 파일에 자세히 설명되어 있습니다.

Loadcat을 구성하고 실행했으면 웹 브라우저를 "http://localhost:26590"으로 지정합니다(로컬에서 실행 중이고 포트 26590에서 수신 대기한다고 가정). 다음으로, 밸런서를 만들고, 몇 대의 서버를 만들고, 정의된 포트에서 무언가가 수신 대기하는지 확인하고, 짜잔~ NGINX가 실행 중인 서버 간에 들어오는 요청을 로드 밸런싱해야 합니다.

무엇 향후 계획?

이 도구는 완벽하지 않으며 사실 상당히 실험적인 프로젝트입니다. 이 도구는 NGINX의 모든 기본 기능도 다루지 않습니다. 예를 들어 NGINX 계층에서 백엔드 노드가 제공하는 자산을 캐시하려는 경우 여전히 NGINX 구성 파일을 수동으로 수정해야 합니다. 그리고 그것이 일을 흥미진진하게 만드는 것입니다. 여기에서 수행할 수 있는 작업이 많이 있으며 이것이 바로 다음 단계입니다. 기본 기능과 NGINX Plus가 제공해야 하는 기능 등 NGINX의 로드 밸런싱 기능을 훨씬 더 많이 다룹니다.

Loadcat을 사용해 보십시오. 코드를 확인하고, 분기하고, 변경하고, 가지고 놀아보세요. 또한 다른 소프트웨어를 구성하는 도구를 구축했거나 아래 설명 섹션에서 정말 마음에 드는 도구를 사용한 적이 있는지 알려주십시오.