Nginx 내 장 된 부하 균형 전략 - 가중 폴 링 (Weighted Round Robin)
7446 단어 nginxnginx 개발 및 분석
upstream backend {
server a weight=5;
server b weight=3;
server c weight=1;
}
예 를 들 어 세 대의 백 스테이지 서버 를 설 치 했 는데 차지 하 는 비중 은 각각 5, 3, 1 이다.그렇다면 요청 을 받 았 을 때 비율 에 따라 백 스테이지 서버 세 대 를 배정 하 는 방법 은 무엇 일 까?생각 할 수 있 는 가장 간단 한 방법 은 바로 현재 가중치 가 0 보다 크 면 이 서버 에 보 내 고 가중치 가 1 을 줄 이 는 것 이다. 그러나 이런 방법 으로 나 누 어 주 는 요청 결 과 는 [a, a, a, a, b, b, b, c] 이다. 목표 의 비례 에 달 했 지만 한 동안 요청 은 모두 a 로 보 냈 고 다른 한 부분 은 b 로 보 냈 다. 이것 은 좋 은 처리 방식 이 아니다.기계 마다 바 쁘 고 한가 한 셈 이지 평균 적 으로 요 구 를 받 지 못 했다.
그러면 nginx 에 서 는 어떻게 부하 균형 을 잡 고 모든 기계 가 받 는 요청 빈 도 를 더욱 고 르 게 합 니까?정 답 은 weighted round robin (WRR) 이라는 알고리즘 입 니 다. 알고리즘 의 데이터 해석 과 증명 에 대해 시간 이 있 으 면 따로 토론 할 수 있 습 니 다. 먼저 Nignx 가 어떻게 이 알고리즘 을 실현 하 는 지 직접 보 세 요.
nginx 에서 몇 대의 서버 에서 유효한 서버 를 선택 하 는 과정 을 ngx 라 고 합 니 다.http_upstream_get_peer 의 함수 중에서 먼저 전체적인 함 수 를 직접 보 세 요.
/* */
static ngx_http_upstream_rr_peer_t *
ngx_http_upstream_get_peer(ngx_http_upstream_rr_peer_data_t *rrp)
{
time_t now;
uintptr_t m;
ngx_int_t total;
ngx_uint_t i, n;
ngx_http_upstream_rr_peer_t *peer, *best;
now = ngx_time();
best = NULL;
total = 0;
/* */
for (i = 0; i < rrp->peers->number; i++) {
/* n */
n = i / (8 * sizeof(uintptr_t));
m = (uintptr_t) 1 << i % (8 * sizeof(uintptr_t));
/* , , continue */
if (rrp->tried[n] & m) {
continue;
}
/* , , */
peer = &rrp->peers->peer[i];
/* down , 1 , continue */
if (peer->down) {
continue;
}
/*
* down 0, max_fails;
* fail_timeout, ,continue ;
*/
if (peer->max_fails
&& peer->fails >= peer->max_fails
&& now - peer->checked <= peer->fail_timeout)
{
continue;
}
/* , */
/*
* current_weight = 0,effective_weight = weight;
* , current_weight effective_weight;
* effective_weight;
*/
peer->current_weight += peer->effective_weight;
total += peer->effective_weight;
/* , effective_weight */
if (peer->effective_weight < peer->weight) {
peer->effective_weight++;
}
/* current_weight best , */
if (best == NULL || peer->current_weight > best->current_weight) {
best = peer;
}
}
if (best == NULL) {
return NULL;
}
/* i */
i = best - &rrp->peers->peer[0];
/* ngx_http_upstream_rr_peer_data_t current , */
rrp->current = i;
/* */
n = i / (8 * sizeof(uintptr_t));
m = (uintptr_t) 1 << i % (8 * sizeof(uintptr_t));
/* */
rrp->tried[n] |= m;
/* */
best->current_weight -= total;
if (now - best->checked > best->fail_timeout) {
best->checked = now;
}
/* */
return best;
}
함수 에서 nginx 는 현재 서버 가 선택 되 었 는 지, 유효 하 는 지 등 다른 검사 와 같은 동작 도 많이 했 습 니 다.단순히 선택 알고리즘 에 만 관심 을 가지 면 다른 과정 을 삭제 하고 남 을 수 있 습 니 다.
/* */
static ngx_http_upstream_rr_peer_t *
ngx_http_upstream_get_peer(ngx_http_upstream_rr_peer_data_t *rrp)
{
....
best = NULL;
total = 0;
/* */
for (i = 0; i < rrp->peers->number; i++) {
........
/* , */
/*
* current_weight = 0,effective_weight = weight;
* , current_weight effective_weight;
* effective_weight;
*/
peer->current_weight += peer->effective_weight;
total += peer->effective_weight;
/* , effective_weight */
if (peer->effective_weight < peer->weight) {
peer->effective_weight++;
}
/* current_weight best , */
if (best == NULL || peer->current_weight > best->current_weight) {
best = peer;
}
}
if (best == NULL) {
return NULL;
}
........
/* */
best->current_weight -= total;
if (now - best->checked > best->fail_timeout) {
best->checked = now;
}
/* */
return best;
}
모든 백 엔 드 peer 에는 세 개의 가중치 변수 가 있 습 니 다.
(1) weight
설정 파일 에서 지정 한 이 백 엔 드 의 가중치 입 니 다. 이 값 은 고정 적 으로 변 하지 않 습 니 다.
(2) effective_weight
백 엔 드 의 유효 가중치, 초기 값 은 weight 입 니 다.
왜 effective 가 나 와 요?weight? 그냥 weight 가 아 닌 데?현재 서버 에 오류 가 발생 하면 effective 를 줄 일 수 있 기 때 문 입 니 다.weight, 이 기계 가 선 택 될 확률 을 낮 춥 니 다.물론 서버 가 정상 이 라면, effective_weight 는 항상 weight 와 같 습 니 다.
오류 가 발생 한 서버 가 다시 정상 으로 돌아 오 면 선택 하 는 과정 에서 effective 가 점점 증가 합 니 다.weight, 결국 weight 로 회 복 됩 니 다.
(3) current_weight
백 엔 드 의 현재 가중치 는 처음에는 0 이 고 선택 할 때마다 조정 되 며 백 엔 드 마다 currentweight 그것 의 effective 증가weight,
동시에 모든 백 엔 드 를 누적 하 는 effectiveweight, totalk 로 저장.
이 백 엔 드 의 currentweight 가 가장 큽 니 다. 이 백 엔 드 를 선택 하고 currentweight 에서 total 을 빼다.
이 백 엔 드 가 선택 되 지 않 았 다 면 currentweight 줄 일 필요 없어 요.
세 개의 weight 필드 의 의 미 를 파악 한 후 가중 폴 링 알고리즘 은 다음 과 같이 설명 할 수 있 습 니 다.
1. 모든 요청 에 대해 클 러 스 터 의 모든 사용 가능 한 백 엔 드 를 옮 겨 다 니 며 모든 백 엔 드 peer 를 실행 합 니 다.
peer->current_weight += peer->effecitve_weight。
동시에 모든 peer 의 effective 를 누적 합 니 다.weight, totalk 로 저장.
2. 클 러 스 터 에서 current 선택weight 가 가장 큰 peer 는 이번 선 택 된 백 엔 드 입 니 다.
3. 이번 선 택 된 백 엔 드 에 대해 실행: per - > currentweight -= total。
위의 소스 코드 를 직접 대조 하여 이해 할 수 있다.
처음 설정 을 예 로 들다
upstream backend {
server a weight=5;
server b weight=3;
server c weight=1;
}
처음 엔 currentweight = { 0, 0, 0 }, effective_weight = { 5, 3, 1 }。서버 가 중간 에 고장 이 나 지 않 는 다 고 가정 하면 토 탈 은 모든 effectiveweight 의 총화, 즉 9.
번호
current_weight 선택 전
게다가 effective무게 후
선택 하 다.
토 탈 빼 고.
1
{ 0, 0, 0 }
{ 5, 3, 1 }
a
{ -4, 3, 1 }
2
{ -4, 3, 1 }
{1, 6, 2 }
b
{ 1, -3, 2 }
3
{ 1, -3, 2 }
{6, 0, 3 }
a
{ -3, 0, 3 }
4
{ -3, 0, 3 }
{ 2, 3, 4 }
c
{ 2, 3, -5 }
5
{ 2, 3, -5 }
{ 7, 6, -4 }
a
{ -2, 6, -4 }
6
{ -2, 6, -4 }
{ 3, 9, -3 }
b
{ 3, 0, -3 }
7
{ 3, 0, -3 }
{ 8, 3, -2 }
a
{ -1, 3, -2 }
8
{ -1, 3, -2 }
{ 4, 6, -1 }
b
{ 4, -3, -1 }
9
{ 4, -3, -1 }
{ 9, 0, 0 }
a
{ 0, 0, 0 }
9 개의 요청 은 윤회 이 고 완전한 서열 은 [a, b, a, c, a, b, a, b, a, b, a] 이 며 상대 적 으로 평균 적 인 과정 으로 알고리즘 의 유효성 을 검증 할 수 있 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
간단! Certbot을 사용하여 웹 사이트를 SSL(HTTPS)화하는 방법초보자가 인프라 주위를 정돈하는 것은 매우 어렵습니다. 이번은 사이트를 간단하게 SSL화(HTTP에서 HTTPS통신)로 변경하는 방법을 소개합니다! 이번에는 소프트웨어 시스템 Nginx CentOS7 의 환경에서 S...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.