ngx_event_pipe_write_to_downstream 분석
5508 단어 nginxHTTP_proxy
이 블 로그 에서 우 리 는 nginx http proxy 모듈 이 클 라 이언 트 에 어떻게 응답 을 보 내 는 지 에 중심 을 두 고 논술 합 니 다.이것 도 비교적 복잡 한 과정 입 니 다. 우 리 는 서술 하 는 과정 에서 필터 모듈 의 갈고리 함 수 를 생략 하고 응답 데 이 터 를 보 내 는 처리 논리 에 직접 들 어 갑 니 다. http proxy 모듈 이 응답 을 보 내 는 함 수 는 ngx 입 니 다.event_pipe_write_to_downstream, 이 블 로 그 는 이 함수 에 대해 간단 한 분석 을 한다.
이루어지다
전반적 으로 말 하면, ngxevent_pipe_write_to_downstream 구현 에는 주로 세 가지 과정 이 있 습 니 다. 1. 쓸 버퍼 를 준비 합 니 다.2. 클 라 이언 트 에 게 버퍼 를 보 내기;3. 로 컬 캐 시 상 태 를 업데이트 합 니 다.우 리 는 각각 이 세 가지 점 에서 완전한 데이터 전송 과정 을 분석한다.
따라서 우리 가 보 내 는 순 서 는 busy 링크, out 링크, in 링크 (body 의 오프셋 순서에 따라 보 내야 합 니 다) 입 니 다.또한 매번 몇 개의 버퍼 를 보 낼 때마다 설정 할 수 있 습 니 다. nginx 는 proxy 를 통 해busy_bufs 는 매번 보 낼 응답 크기 를 설정 합 니 다.따라서 전체 준비 버퍼 코드 는 다음 과 같 습 니 다.
for (cl = p->busy; cl; cl = cl->next) {
if (cl->buf->recycled) {
// ʲôÇé¿öÏ»á³öÏÖÇ°Ò»¸ö»º³åÇøºÍºóÒ»¸ö»º³åÇø
// µÄÆðʼµØÖ·Ïàͬ?
if (prev == cl->buf->start) {
continue;
}
bsize += cl->buf->end - cl->buf->start;
prev = cl->buf->start;
}
}
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, p->log, 0,
"pipe write busy: %uz", bsize);
out = NULL;
// busy buffers , out in , flush
if (bsize >= (size_t) p->busy_size) {
flush = 1;
goto flush;
}
flush = 0;
ll = NULL;
prev_last_shadow = 1;
for ( ;; ) {
if (p->out) { // out ,
cl = p->out;
if (cl->buf->recycled) {
ngx_log_error(NGX_LOG_ALERT, p->log, 0,
"recycled buffer in pipe out chain");
}
p->out = p->out->next;
} else if (!p->cacheable && p->in) {
cl = p->in;
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, p->log, 0,
"pipe write buf ls:%d %p %z",
cl->buf->last_shadow,
cl->buf->pos,
cl->buf->last - cl->buf->pos);
if (cl->buf->recycled && prev_last_shadow) {
if (bsize + cl->buf->end - cl->buf->start > p->busy_size) {
flush = 1;
break;
}
bsize += cl->buf->end - cl->buf->start;
}
prev_last_shadow = cl->buf->last_shadow;
p->in = p->in->next;
} else {
break;
}
cl->next = NULL;
if (out) {
*ll = cl;
} else {
out = cl;
}
ll = &cl->next;
}
// ngx_http_write_filter()
rc = p->output_filter(p->output_ctx, out);
다만 우리 가 알 아야 할 것 은 이 발송 과정 이 모든 준 비 된 응답 데 이 터 를 보 내지 않 았 을 수도 있 고 일부분 만 보 냈 을 수도 있 습 니 다. 또한 발송 과정 에서 여러 가지 이유 로 오류 가 발생 할 수도 있 습 니 다. 발송 함수 에서 여러 가지 오류 코드 를 설정 할 수 있 습 니 다. // , free
// busy ,
ngx_chain_update_chains(p->pool, &p->free, &p->busy, &out, p->tag);
또한 발송 오류 에 대해 오류 코드 를 설정 해 야 합 니 다. if (rc == NGX_ERROR) {
p->downstream_error = 1;
return ngx_event_pipe_drain_chains(p);
}
위 에서 방금 전 송 된 버퍼 를 free 링크 에 추 가 했 기 때문에 주의: 버퍼 를 관리 하 는 데이터 구 조 를 free 링크 에 만 방출 할 뿐 실제 원본 버퍼 는 아직 방출 되 지 않 았 을 수 있 습 니 다 (free raw bufs 링크 에 삽입).따라서, 다음 에 우 리 는 이러한 상황 을 처리 해 야 합 니 다. free 링크 의 모든 buffer 를 옮 겨 다 녀 야 합 니 다. 만약 원본 데이터 버퍼 가 아직 풀 리 지 않 았 다 면 free it.for (cl = p->free; cl; cl = cl->next) {
if (cl->buf->temp_file) {
if (p->cacheable || !p->cyclic_temp_file) {
continue;
}
/* reset p->temp_offset if all bufs had been sent */
if (cl->buf->file_last == p->temp_file->offset) {
p->temp_file->offset = 0;
}
}
/* TODO: free buf if p->free_bufs && upstream done */
/* add the free shadow raw buf to p->free_raw_bufs */
if (cl->buf->last_shadow) {
if (ngx_event_pipe_add_free_buf(p, cl->buf->shadow) != NGX_OK) {
return NGX_ABORT;
}
cl->buf->last_shadow = 0;
}
cl->buf->shadow = NULL;
}
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 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에 따라 라이센스가 부여됩니다.