NGINX 시간 관리 메커니즘

3256 단어
nginx 는 사용자 에 게 시간 을 제공 하고 캐 시 시간 체 제 를 사용 하여 빈번 한 시스템 호출 (gettimeofday) 을 피하 고 처리 속 도 를 가속 화 합 니 다.
그러나 캐 시 시간 은 제때에 시간 을 업데이트 해 야 한다. 그렇지 않 으 면 시간 이 정확 하지 않 을 것 이다.그래서 NGINX 는 오 차 를 줄 이 는 일련의 조 치 를 취 했다.
void
ngx_process_events_and_timers(ngx_cycle_t *cycle)
{
    ngx_uint_t  flags;
    ngx_msec_t  timer, delta;

    if (ngx_timer_resolution) {
        timer = NGX_TIMER_INFINITE;   //-1
        flags = 0;

    } else {
        timer = ngx_event_find_timer();
        flags = NGX_UPDATE_TIME;
    }

    (void) ngx_process_events(cycle, timer, flags);
}
일단 은 ngxtimer_resolution, else 부분 만 주목, timer = ngxevent_find_timer(),
이 함수 가 첫 번 째 시간 초과 사건 으로 돌아 가 는 데 얼마나 남 았 습 니까? - 1 일 수 있 습 니 다. 즉, 현재 시간 초과 사건 이 등록 되 지 않 았 습 니 다.
동시에 flags 는 NGX 로 표 시 됩 니 다.UPDATE_TIME, 즉 캐 시 시간 을 업데이트 합 니 다.
ngx_process_이벤트 가 구체 적 인 이벤트 처리 함수 에 대응 하고 본 고 는 epoll 을 예 로 들 기 때문에 다음 과 같은 코드 에 대응 합 니 다.
static ngx_int_t
ngx_epoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)
{
    events = epoll_wait(ep, event_list, (int) nevents, timer);
    
    if (flags & NGX_UPDATE_TIME || ngx_event_timer_alarm) {
        ngx_time_update();
    }
}
timer 는 epollwait 기다 리 는 최대 시간, 즉 epollwait 가 돌아 오 면 flags 가 NGX 로 설정 되 어 있 습 니 다.UPDATE_TIME,
따라서, ngx 호출time_update 캐 시 시간 업데이트.
위 에 새로운 문 제 를 가 져 왔 습 니 다. 만약 에 timer 가 - 1 또는 너무 크 면 epollwait 에서 사용 가능 한 소켓 을 얻 지 못 했 습 니 다. 그렇다면, 이때,
오랫동안 업 데 이 트 를 받 지 못 해 오차 가 너무 크다.그래서 nginx 는 강제 업데이트 전략 을 도입 했다.
if (ngx_timer_resolution) {
    timer = NGX_TIMER_INFINITE;  //-1
    flags = 0;
}
ngx_timer_resolution 이 사용자 에 게 설정 한 매개 변수 값, 즉 ngxtimer_resolution 시간 이 지나 면 시간의 업 데 이 트 를 해 야 합 니 다.
이렇게 하면 오랫동안 업데이트 되 지 않도록 방지한다.timer = - 1, 이렇게, epollwait 는 끝 없 이 막 힙 니 다.
static ngx_int_t
ngx_event_process_init(ngx_cycle_t *cycle)
{
    if (ngx_timer_resolution && !(ngx_event_flags & NGX_USE_TIMER_EVENT)) {
        struct sigaction  sa;
        struct itimerval  itv;

        sa.sa_handler = ngx_timer_signal_handler;
        if (sigaction(SIGALRM, &sa, NULL) == -1) {}

        if (setitimer(ITIMER_REAL, &itv, NULL) == -1) {}
    }
}
먼저 신호 (SIGALRM) 처리 함 수 를 등록 한 다음 타이머 setitimer 를 설정 합 니 다. (timer resoluiton) 시간 이 초과 되면,
SIGALRM 이 벤트 를 보 내 면 이벤트 처리 함 수 는 어떤 기능 을 완 성 했 습 니까?
void
ngx_timer_signal_handler(int signo)
{
    ngx_event_timer_alarm = 1;
}
ngx event timer alarm 만 1 로 설정 합 니 다. 신호 중단 시스템 호출 지식 이 있 습 니 다.
따라서 SIGALRM 은 epoll wait 호출 을 중단 하고 epoll wait 가 돌아 오 면 errno 는 EINTR 로 설정 합 니 다.
events = epoll_wait(ep, event_list, (int) nevents, timer);
    
if (flags & NGX_UPDATE_TIME || ngx_event_timer_alarm) {
    ngx_time_update();
}
여기 서 ngx event timer alarm 은 신호 처리 함수 에서 1 로 설정 되 어 있 기 때문에 시간 업 데 이 트 를 실행 합 니 다.
강제 리 셋 전략 이 있 는 이상 왜 첫 번 째 전략 이 필요 합 니까? 저 는 그렇다 고 생각 합 니 다. 우선 이것 은 최적화 조치 라 고 할 수 있 습 니 다.
nginx 는 최소 설정 을 사용 할 수 있 도록 해 야 하기 때문에 이 설정 항목 은 설정 하지 않 아 도 됩 니 다. 장면 마다 다른 설정 이 있 습 니 다.
자주 방문 하 는 사 이 트 는 timer resolution 이 필요 하지 않 습 니 다. epoll wait 는 신속하게 돌아 오고 시간 은 제때에 업데이트 할 수 있 습 니 다.

좋은 웹페이지 즐겨찾기