nginx tcp 에이전트 와 부하 균형

6843 단어
nginx 의 tcp 에이전트 와 부하 균형 에 대해 들 어 보 셨 을 수도 있 습 니 다. 그 경 위 를 알 고 싶 습 니 다. 어떻게 사용 하 는 지 알 고 싶 습 니 다. 그 실현 원 리 를 알 고 싶 습 니까?이것 이 바로 본문의 내용 이다.
1. 민 담
nginx 는 http 서비스의 우수한 표현 으로 대중 에 게 인 정 받 지만 http 서버 뿐만 아니 라 mail 프 록 시 서버 이기 도 합 니 다.현재 이 가정 은 새로운 멤버 tcp 에 가입 했다.사실 nginx 홈 페이지 의 말 에서 stream 이 라 고 하 는데 여러분 앞 에 나타 난 이 유 는 tcp 의 원인 이 라 고 생각 합 니 다.
a: 프 록 시 수 요 를 해 결 했 습 니 다. 이 수 요 는 tcp 프 록 시 입 니 다. 그러나 원본 코드 에 stream 이 라 고 명명 되 어 tcp 가 보이 지 않 습 니 다.
b: 확실히 제3자 모듈 (ngx tcp proxy module) 이 같은 일 을 했 습 니 다. 이 우수한 모듈 은 시간 이 많 습 니 다. 관심 있 는 것 은 github 에 가 보 세 요.
c: tcp 는 stream 보다 입 에 잘 맞아요. 이 건 좀 쓸데없는 말 인 것 같 아 요. 어쨌든 그렇습니다.
왜 stream 을 강조 합 니까? stream 과 http 는 같은 등급 이 고 http 자체 에 proxy 기능 이 있 으 며 현재 stream 의 핵심 기능 도 proxy 입 니 다.그러나 앞으로 stream 의 기능 이 더욱 풍부 하고 강력 해 질 것 으로 예상 되 므 로 nginx 는 stream 의 것 이 있 습 니 다. tcp 프 록 시 기능 을 갖 추고 있 기 때 문 입 니 다.
2. stream 은 어떤 모습 인가요?
worker_processes auto;
error_log /var/log/nginx/error.log info;
stream {
    upstream backend {
        hash $remote_addr consistent;
        server backend1.example.com:12345 weight=5;
        server 127.0.0.1:12345            max_fails=3 fail_timeout=30s;
        server unix:/tmp/backend3;
    }
    server {
        listen 12345;
        proxy_connect_timeout 1s;
        proxy_timeout 3s;
        proxy_pass backend;
    }
    server {
        listen [::1]:12345;
        proxy_pass unix:/tmp/stream.socket;
    }
}
이것 은 홈 페이지 의 예 입 니 다. 우 리 는 stream 과 http 가 매우 비슷 하 다 는 것 을 알 게 되 었 습 니 다. 예, 이것 은 제 가 강조 하 는 nginx 가 http 서버 만 이 아 닙 니 다. http 에는 3 층, main, server, location 이 있다 는 것 을 알 고 있 습 니 다. 그러나 stream 은 main 과 server 만 있 습 니 다. http 의 업무 가 더욱 가 변 적 이 고 stream 은 이렇게 복잡 할 필요 가 없 기 때문에 작 가 는 2 층 으로 추상 화 되 었 을 뿐 입 니 다. 그러나 이것 은 그 업무 에 영향 을 주지 않 습사용. stream 도 ssl 을 지원 합 니 다.
3. stream 의 원리 와 실현
stream 의 소스 코드 는 http 의 간략화 판 이 라 고 할 수 있 습 니 다. 세심 한 독자 들 은 소스 코드 의 작가 가 Roman Arutyunyan 이라는 것 을 발견 해 야 합 니 다. 이것 도 rtmp 모듈 의 작가 입 니 다. 그 는 my sql handlersocket 이라는 모듈 도 있 습 니 다. 저 는 모듈 시리즈 에서 handlersocket 모듈 을 전문 적 으로 분석 할 것 입 니 다. 주의 하 시기 바 랍 니 다. 특히 웹 (api) 엔 지 니 어 는 이 모듈 이 매우 주목 할 만하 다 고 생각 할 것 입 니 다.
우선 main 과 server 의 구 조 는 http 와 똑 같 습 니 다. 이것 은 토론 하지 않 습 니 다.
init 에서 ls - > handler = ngx stream init connection;
처리 요청 중 
ngx_stream_init_connection(ngx_connection_t *c)
{ 
    ...
    ngx_stream_init_session(c);
}

static void
ngx_stream_init_session(ngx_connection_t *c)
{
    ngx_stream_core_srv_conf_t  *cscf;

    cscf = ngx_stream_get_module_srv_conf(s, ngx_stream_core_module);

    cscf->handler(s); /*       */
}

cscf - > handler 라 는 갈 고 리 는 마음대로 확장 할 수 있 기 때문에 stream 의 미래 가 더욱 강해 질 것 이 라 고 언급 한 적 이 있 습 니 다. 현재 등 록 된 것 은 ngx stream proxy handler 라 는 모듈 이기 때문에 ngx 가 tcp 프 록 시 기능 을 갖 추고 있 는 이 유 를 잘 알 고 있 습 니 다. 바로 이러한 메커니즘 입 니 다. stream 을 분석 하 는 것 은 기본적으로 ngx stream proxy handler 모듈 을 분석 하 는 것 입 니 다.
static void
ngx_stream_proxy_handler(ngx_stream_session_t *s)
{
    u = ngx_pcalloc(c->pool, sizeof(ngx_stream_upstream_t));

    s->upstream = u;

    u->peer.log = c->log;

    uscf = pscf->upstream;

    uscf->peer.init(s, uscf);

    p = ngx_pnalloc(c->pool, pscf->downstream_buf_size);

    u->downstream_buf.start = p;
    u->downstream_buf.end = p + pscf->downstream_buf_size;
    u->downstream_buf.pos = p;
    u->downstream_buf.last = p;

    c->write->handler = ngx_stream_proxy_downstream_handler;
    c->read->handler = ngx_stream_proxy_downstream_handler;

    ngx_stream_proxy_process(s, 0, 0);

    ngx_stream_proxy_connect(s);
}

여기 서 두 가 지 를 했 습 니 다. upstream 과 연결 읽 기 쓰기 동작 을 선택 하 십시오. upstream 이 든 읽 기 쓰기 든 http 보다 훨씬 간소화 되 었 습 니 다. http 부분 을 잘 아 는 친구 들 은 읽 기 가 매우 간단 합 니 다. http upstream 의 경 위 를 쓴 적 이 있 습 니 다. 여 기 는 downstream, upstream 두 단어 가 있 습 니 다. nginx 에 비해 클 라 이언 트 는 downstream 이 고 백 엔 드 서버 는 downstream 입 니 다.upstream 입 니 다. nginx 는 중간 에 끼어 있 습 니 다. ngx stream proxy connect 는 부하 균형 을 이 루 는 일 을 합 니 다. 위의 글 은 이미 분석 되 었 습 니 다. 이 를 생략 합 니 다.
이어서 읽 기와 쓰기 요청 을 처리 하 는 코드 를 보십시오.
static ngx_int_t
ngx_stream_proxy_process(ngx_stream_session_t *s, ngx_uint_t from_upstream, ngx_uint_t do_write)
{
    ...
    c = s->connection;
    pc = u->upstream_buf.start ? u->peer.connection : NULL;

    if (from_upstream) {
        src = pc;
        dst = c;
        b = &u->upstream_buf;

    } else {
        src = c;
        dst = pc;
        b = &u->downstream_buf;
    }

    for ( ;; ) {
        if (do_write) {
            size = b->last - b->pos;
            if (size && dst && dst->write->ready) {
                n = dst->send(dst, b->pos, size);

                if (n == NGX_ERROR) {
                    ngx_stream_proxy_finalize(s, NGX_DECLINED);
                    return NGX_ERROR;
                }

                if (n > 0) {
                    b->pos += n;

                    if (b->pos == b->last) {
                        b->pos = b->start;
                        b->last = b->start;
                    }
                }
            }
        }

        size = b->end - b->last;

        if (size && src->read->ready) {
            n = src->recv(src, b->last, size);
            if (n == NGX_AGAIN || n == 0) {
                break;
            }
            if (n > 0) {
                if (from_upstream) {
                    u->received += n;

                } else {
                    s->received += n;
                }
                do_write = 1;
                b->last += n;
                continue;
            }

            if (n == NGX_ERROR) {
                src->read->eof = 1;
            }
        }
        break;
    }
    ...

    return NGX_OK;
}

클 라 이언 트 를 읽 고 백 엔 드 로 보 내 고 백 엔 드 응답 을 받 으 며 클 라 이언 트 에 게 응답 하 는 것 이 재 미 있 지 않 습 니까? mail 의 에이전트 도 마찬가지 입 니 다. http 의 해석 없 이 chain, buf 재 활용, 이벤트 pipe 가 없습니다. 읽 기 에 전혀 힘 들 지 않 습 니 다. 4. 밟 을 수 있 는 작은 구덩이 라 고 할 수 있 습 니 다.
프 록 시가 하 는 일 은 매우 간단 합 니 다. client 가 보 낸 데 이 터 를 백 엔 드 서버 에 일일이 전달 합 니 다. 따라서 프 록 시가 모든 데이터 처 리 를 도와 줄 것 이 라 고 기대 하지 마 십시오. 이것 은 http 프 록 시 에 도 적 용 됩 니 다. 프 록 시 설정 에 서 는 port: ip 만 주목 합 니 다. 아래 의 예 를 보 세 요.
location / {
    proxy_pass   http://127.0.0.1:8082/xxx; \ # 이렇게 하 는 것 은 옳지 않 습 니 다. 실행 할 수 있 지만.
}
나 를 포함 하여 뒤의 / xxx 는 아무런 효과 가 없다.
5. 소결:
현재 nginx 1.9 는 개발 판 입 니 다. 현재 안정 판 은 stream 기능 이 없 지만 다음 안정 판 이 발 표 될 때 이 기능 이 통합 되 기 때문에 나중에 http proxy 를 사용 하 는 학생 들 은 tcp proxy 로 바 꾸 는 것 을 고려 할 수 있 습 니 다.
간단 한 에이전트 일 뿐 이 고 성능 도 우수 합 니 다. 이것 도 오픈 소스 를 지원 하 는 작은 방식 이 아 닙 니까 ^ - ^.
본문 끝! 오리지널 주목:
http://nglua.com/reads/6.html

좋은 웹페이지 즐겨찾기