Nginx 놀 라 움 해결
7371 단어 운영 체제
Nginx 는 socket 의 프로 세 스 수량 과 ngx 선점 을 제어 합 니 다.accept_mutex 잠 금 으로 놀 라 움 을 해결 합 니 다.오직 하나의 ngxaccept_mutex 자물쇠, 누가 자 물 쇠 를 가 져 왔 는 지, 누가 이 socket 의 요청 을 처리 합 니까?
현재 프로 세 스 의 연결 수 > 최대 연결 수 * 7 / 8 이면 이 프로 세 스 는 이번 라운드 경쟁 에 참여 하지 않 습 니 다.
//nginx worker ngx_process_events_and_timers 。 ngx_process_events_and_timers() 。
void ngx_process_events_and_timers(ngx_cycle_t *cycle)
{
//ngx_use_accept_mutex accept 。 nginx worker >1 accept_mutex , 1
if (ngx_use_accept_mutex)
{
//ngx_accept_disabled , ,nginx.conf nginx worker , 7/8 ,ngx_accept_disabled , nginx worker , ,
if (ngx_accept_disabled > 0)
{
ngx_accept_disabled--;
}
else
{
// , ngx_accept_mutex_held 1。 , socket epoll , , socket epoll 。
// trylock , , , 。
if(pthread_mutex_trylock(&ngx_accept_mutex))
{
ngx_accept_mutex_held = 1;
}
else
{
// time ,500ms , worker , , fd 。
timer = 500;
ngx_accept_mutex_held = 0;
}
// , flag NGX_POST_EVENTS, ngx_process_events , , accept ngx_posted_accept_events ,epollin|epollout ngx_posted_events
if (ngx_accept_mutex_held)
{
flags |= NGX_POST_EVENTS;
}
}
// epoll_wait
int num = epoll_wait(epollfd, events, length, timer);
for(int i=0; i<num; ++i)
{
......
//
if (revents & EPOLLIN)
{
// NGX_POST_EVENTS , accept ngx_posted_accept_events , ngx_posted_events
// ngx_posted_accept_events
// ngx_posted_events
if (flags & NGX_POST_EVENTS)
{
queue = rev->accept ?
&ngx_posted_accept_events:
&ngx_posted_events;
ngx_post_event(rev, queue);
}
else//
{
rev->handler(rev);
}
}
//
if (revents & EPOLLOUT)
{
// , NGX_POST_EVENTS , , ngx_posted_events
if (flags & NGX_POST_EVENTS)
{
ngx_post_event(rev, &ngx_posted_events);
}
else//
{
rev->handler(rev);
}
}
}
//
ngx_event_process_posted(cycle, &ngx_posted_accept_events);
//
if(ngx_accept_mutex_held)
{
pthread_mutex_unlock(&ngx_accept_mutex);
}
//
ngx_event_process_posted(cycle, &ngx_posted_events);
}
nginx 는 자 물 쇠 를 빼 앗 고 자 물 쇠 를 풀 어 주 는 것 부터 사건 을 처리 하 는 전체 과정 까지 저 는 코드 와 결합 하여 설명 을 했 습 니 다. 여러분 들 이 전체 과정 에 대해 낯 설 지 않 을 것 이 라 고 믿 습 니 다.까지 pthreadmutex_trylock () 에서 프로 세 스 가 어떻게 자 물 쇠 를 선점 하 는 지 는 선점 을 실현 하 는 알고리즘 에 달 려 있다. 여 기 는 처리 과정 만 설명 할 뿐 선점 실현 원리 에 관심 이 없다.관심 있 는 학우 들 은 스스로 관련 자 료 를 검색 할 수 있다.
1. 새 사용자 의 연결 이 벤트 를 처리 하고 새 연결 을 처리 하 는 자 물 쇠 를 풀 어 줍 니 다. 왜 이렇게 디자인 합 니까?자 물 쇠 를 풀 자마자 새로운 연결 이 있 습 니 다. 자 물 쇠 를 얻 은 프로 세 스 가 대기 열 에 sockfd 를 추가 하려 면 원래 자 물 쇠 를 얻 은 프로 세 스 도 대기 열 에서 sockfd 를 삭제 해 야 합 니 다. TCP 의 세 번 악수 연결 은 비 스 레 드 가 안전 합 니 다.오류 가 발생 하지 않도록 sockfd 를 대기 열 에서 삭제 한 후 새로운 프로 세 스 가 자 물 쇠 를 선점 하여 새로운 연결 을 처리 합 니 다.
2. 자 물 쇠 를 가 져 와 임 무 를 퀘 스 트 대기 열 에 두 고 바로 처리 하 는 것 이 아니 라 왜 이렇게 설계 합 니까?모든 프로 세 스 가 새 연결 이 벤트 를 처리 하려 면 자 물 쇠 를 가 져 와 야 합 니 다. 현재 프로 세 스 는 새 연결 이벤트 의 sokect 를 작업 대기 열 에 추가 하고 자 물 쇠 를 즉시 풀 어 다른 프로 세 스 가 빨리 자 물 쇠 를 가 져 와 사용자 의 연결 을 처리 하도록 합 니 다.
잠 금 을 추가 하지 않 으 면 새로운 이벤트 연결 이 있 을 때 모든 프로 세 스 가 깨 어 나 accept 를 실행 합 니 다. 또한 하나의 프로 세 스 만 accept 를 성공 적 으로 되 돌려 주 고 다른 프로 세 스 는 다시 수면 상태 로 들 어 갑 니 다.현재 자물쇠 가 있 습 니 다. accept 가 발생 하기 전에 프로 세 스 들 이 자 물 쇠 를 선점 해 야 합 니 다. 또한 하나의 프로 세 스 만 자 물 쇠 를 빼 앗 고 다른 프로 세 스 도 다시 수면 상태 로 들 어 갑 니 다.즉, accept 자물쇠 가 있 든 없 든 많은 프로 세 스 가 깨 어 나 다시 수면 상태 로 들 어 가 는 과정 이 있 습 니 다. 그 놀 라 운 현상 은 어떻게 설명 합 니까?
사실 자 물 쇠 는 놀 라 움 현상 을 해결 하지 못 하고 놀 라 움 현상 은 해결 할 수 없 으 며 많은 과정 이 동시에 깨 어 나 는 것 은 필연 적 인 과정 이다.Nginx 에 서 는 현재 프로 세 스 의 연결 수 > 최대 연결 수 * 7 / 8 을 검사 하여 현재 프로 세 스 가 새로운 연결 을 처리 할 수 있 는 지 판단 하고 깨 어 난 프로 세 스 의 수 를 줄 이 며 간단 한 부하 균형 을 이 루 었 습 니 다.잠 금 은 모든 프로 세 스 가 accept 함 수 를 호출 하지 않도록 보장 할 수 있 습 니 다. 많은 프로 세 스 가 accept 를 호출 하여 오 류 를 되 돌려 주 었 습 니 다. 잠 금 은 놀 라 운 현상 을 해결 하 는 오 류 를 해결 하 는 것 이지 놀 라 운 현상 을 해결 하 는 것 이 아 닙 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Shell 기본 동작스 크 립 트 에 전 달 된 모든 인 자 를 단일 문자열 로 표시 합 니 다. PS: $@ 과 $의 차이 점: (1) 방문 할 때 argA = $@ 이 라 고 쓰 면;argB = $, argA 는 argB 와 같 습...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.