왜 Nginx 의 성능 이 Apache 보다 훨씬 높 습 니까?

6033 단어
왜 Nginx 의 성능 은 Apache 보다 훨씬 높 습 니까?이 는 Nginx 가 최신 epoll (Linux 2.6 커 널) 과 kquue (freebsd) 네트워크 I / O 모델 을 사 용 했 고 아파 치 는 전통 적 인 select 모델 을 사용 한 덕분이다.
현재 Linux 에서 높 은 동시 방문 을 견 딜 수 있 는 Squid, Memcached 는 모두 epoll 네트워크 I / O 모델 을 사용 하고 있다.
대량의 연결 을 처리 하 는 읽 기와 쓰기, 아파 치가 사용 하 는 select 네트워크 I / O 모델 은 매우 비효 율 적 이다.
다음은 Apache 가 사용 하 는 select 모델 과 Nginx 가 사용 하 는 epoll 모델 의 차 이 를 비유 적 으로 해석 합 니 다.
만약 당신 이 대학 에서 공부한다 고 가정 하면 기숙사 건물 에 방 이 많 습 니 다. 당신 의 친구 가 당신 을 찾 아 올 것 입 니 다.
selection 판 숙 관 아 줌 마 는 친 구 를 데 리 고 방 을 찾 아 갈 것 이다.
그리고 epoll 판 숙 관 아 줌 마 는 먼저 모든 친구 들 의 방 번 호 를 적 습 니 다.
당신 의 친구 가 올 때, 당신 의 친구 에 게 당신 이 어느 방 에 사 는 지 만 알려 주면 됩 니 다. 당신 의 친 구 를 직접 데 리 고 빌딩 에 사람 을 찾 지 않 아 도 됩 니 다.
10000 명 이 오 면 이 건물 에 사 는 친 구 를 찾 아야 할 때 select 판 과 epoll 판 숙 관 아 줌 마 는 누구의 효율 이 더 높 은 지 는 자명 하 다.
마찬가지 로 높 은 병발 서버 에서 폴 링 I / O 는 가장 시간 을 소모 하 는 작업 중 하나 이 며, select 와 epoll 의 성능 은 누구의 성능 이 더 높 은 지, 마찬가지 로 10 이 분명 하 다.
 
  
epoll - I/O event notification facility

Liux 의 네트워크 프로 그래 밍 에서 오랫동안 select 를 사용 하여 이벤트 트리거 를 합 니 다.
Liux 의 새로운 커 널 에 교체 메커니즘 이 있 는데 그것 이 바로 epoll 입 니 다.
select 에 비해 epoll 의 가장 큰 장점 은 감청 fd 수가 증가 함 에 따라 효율 을 떨 어 뜨리 지 않 는 다 는 것 이다.
커 널 의 select 실현 에서 폴 링 으로 처리 되 기 때문에 폴 링 의 fd 수량 이 많 을 수록 자 연 스 럽 게 시간 이 많이 걸린다.
그리고 linux / posixtypes. h 헤더 파일 에 다음 과 같은 성명 이 있 습 니 다:
#define __FD_SETSIZE    1024
select 가 최대 1024 개의 fd 를 동시에 감청 한 다 는 뜻 입 니 다. 물론 헤더 파일 을 수정 하고 커 널 을 재 편집 하여 이 수 를 확대 할 수 있 지만 이것 은 근본 적 인 해결 이 아 닌 것 같 습 니 다.
epoll 의 인 터 페 이 스 는 매우 간단 합 니 다. 모두 세 개의 함수 만 있 습 니 다.
1. int epoll_create(int size);
epoll 의 핸들 을 만 듭 니 다. size 는 커 널 의 감청 수량 이 모두 얼마나 되 는 지 알려 줍 니 다.
이 매개 변 수 는 select () 의 첫 번 째 매개 변수 와 달리 최대 감청 fd + 1 의 값 을 보 여 줍 니 다.
주의해 야 할 것 은 epoll 핸들 을 만 들 면 fd 값 을 사용 합 니 다. Liux 에서 / proc / 프로 세 스 id / fd / 를 보면,
이 fd 를 볼 수 있 기 때문에 epoll 을 사용 한 후에 close () 를 호출 하여 닫 아야 합 니 다. 그렇지 않 으 면 fd 가 소 진 될 수 있 습 니 다.
2. int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
epoll 의 이벤트 등록 함수 와 달리 select () 는 이 벤트 를 감청 할 때 커 널 에 어떤 종류의 이 벤트 를 감청 해 야 하 는 지 알려 줍 니 다.
여기 서 감청 할 사건 유형 을 먼저 등록 하 는 겁 니 다.첫 번 째 매개 변 수 는 epoll 입 니 다.create () 의 반환 값,
두 번 째 매개 변 수 는 동작 을 표시 하고 세 개의 매크로 로 표시 합 니 다.
EPOLL_CTL_ADD: 새로운 fd 를 epfd 에 등록 합 니 다.
EPOLL_CTL_MOD: 등 록 된 fd 의 감청 사건 을 수정 합 니 다.
EPOLL_CTL_DEL: epfd 에서 fd 를 삭제 합 니 다.
세 번 째 매개 변 수 는 감청 이 필요 한 fd 입 니 다. 네 번 째 매개 변 수 는 커 널 이 무엇 을 감청 해 야 하 는 지 알려 주 는 것 입 니 다. struct epoll이벤트 구 조 는 다음 과 같 습 니 다.
 
  
typedef union epoll_data {
void *ptr;
int fd;
__uint32_t u32;
__uint64_t u64;
} epoll_data_t;
struct epoll_event {
__uint32_t events; /* Epoll events */
epoll_data_t data; /* User data variable */
};

이 벤트 는 다음 과 같은 매크로 의 집합 일 수 있 습 니 다. EPOLLIN: 해당 하 는 파일 설명 자 를 읽 을 수 있 음 을 표시 합 니 다 (엔 드 SOCKET 의 정상 적 인 닫 기 포함).EPOLLOUT: 대응 하 는 파일 설명 자 를 표시 합 니 다.EPOLLPRI: 대응 하 는 파일 설명자 에 읽 을 수 있 는 긴급 한 데이터 가 있 음 을 표시 합 니 다 (여 기 는 외부 데이터 가 왔 음 을 표시 해 야 합 니 다).EPOLLERR: 대응 하 는 파일 설명자 에 오류 가 발생 했 음 을 표시 합 니 다.EPOLLHUP: 대응 하 는 파일 설명자 가 끊 겼 음 을 표시 합 니 다.EPOLLET: EPOLL 을 가장자리 트리거 (Edge Triggered) 모드 로 설정 합 니 다. 이것 은 수평 트리거 (Level Triggered) 에 비해 말 합 니 다.EPOLLONESHOT: 사건 을 한 번 만 감청 합 니 다. 이번 사건 을 감청 한 후에 도 이 socket 을 계속 감청 해 야 한다 면 이 socket 을 다시 EPOLL 대기 열 에 넣 어야 합 니 다.
3. int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout);
이벤트 가 발생 하 기 를 기다 리 는 것 은 select () 호출 과 유사 합 니 다.매개 변수 events 는 커 널 에서 이벤트 의 집합 을 얻 는 데 사 용 됩 니 다. maxevents 는 커 널 이 이벤트 가 얼마나 큰 지 알려 줍 니 다. 이 maxevents 의 값 은 epoll 을 만 드 는 것 보다 클 수 없습니다.create () 시의 size, 인자 timeout 은 시간 초과 (밀리초, 0 은 즉시 돌아 갑 니 다. - 1 은 확실 하지 않 고 영구적 으로 차단 된다 는 말 도 있 습 니 다).이 함 수 는 처리 해 야 할 이벤트 수 를 되 돌려 줍 니 다. 0 을 되 돌려 주 는 것 은 시간 이 초과 되 었 음 을 표시 합 니 다.
4. ET, LT 두 가지 작업 모델:
이러한 결론 을 얻 을 수 있다. ET 모드 는 상태 가 변 했 을 때 만 통 지 를 받 을 수 있다. 여기 서 이른바 상태의 변 화 는 버퍼 에 처리 되 지 않 은 데 이 터 를 포함 하지 않 는 다. 즉, ET 모드 를 사용 하려 면 오류 가 발생 할 때 까지 계속 읽 기 / 쓰기 가 필요 하 다. 많은 사람들 이 왜 ET 모드 를 사용 하여 일부 데이터 만 받 으 면 더 이상 통 지 를 받 지 못 하 는 지 나타 낸다.대부분 그 렇 기 때문이다.LT 모드 는 데이터 가 처리 되 지 않 으 면 계속 알려 줍 니 다.그렇다면 과연 epoll 을 어떻게 사용 할 것 인가?사실 매우 간단 하 다.하나의 헤더 파일 을 포함 하 는 \ # include 와 몇 개의 간단 한 API 를 통 해 네트워크 서버 의 지원 자 를 크게 향상 시 킬 수 있 습 니 다.우선 create 를 통 해epoll (int maxfds) 은 epoll 의 핸들 을 만 듭 니 다. 그 중에서 maxfds 는 epoll 이 지원 하 는 최대 핸들 수 입 니 다.이 함 수 는 새로운 epoll 핸들 을 되 돌려 줍 니 다. 이후 의 모든 작업 은 이 핸들 을 통 해 이 루어 집 니 다.사용 한 후에 만 든 epoll 핸들 을 close () 로 닫 는 것 을 기억 하 십시오.이후 네트워크 메 인 순환 에서 프레임 당 epoll 호출wait (int epfd, epoll event events, int max events, int timeout) 는 모든 네트워크 인 터 페 이 스 를 조회 하여 읽 을 수 있 는 것, 쓸 수 있 는 것 을 봅 니 다.기본 문법: nfds = epollwait(kdpfd, events, maxevents, -1); 그 중 kdpfd 는 epollcreate 생 성 후 핸들, events 는 epoll 입 니 다.이벤트 * 지침, epollwait 이 함수 조작 성공 후, epoll이벤트 에는 모든 읽 기와 쓰기 이벤트 가 저 장 됩 니 다.max_이 벤트 는 현재 감청 해 야 할 모든 socket 핸들 수 입 니 다.마지막 timeout 은 epollwait 의 시간 초과, 0 일 때 는 바로 돌아 가 는 것 을 표시 하고, - 1 일 때 는 사건 범위 가 있 을 때 까지 기다 리 는 것 을 표시 하 며, 임의의 정수 일 때 는 이렇게 긴 시간 을 기다 리 는 것 을 표시 하 며, 사건 이 없 으 면 범 위 를 표시 합 니 다.일반적으로 네트워크 의 주 순환 이 단독 스 레 드 라면 - 1 로 등 을 할 수 있 습 니 다. 그러면 일부 효율 을 확보 할 수 있 습 니 다. 주 논리 와 같은 스 레 드 라면 0 으로 주 순환 의 효율 을 확보 할 수 있 습 니 다.epoll_wait 범 위 를 넘 으 면 모든 사건 이 순환 되 어야 합 니 다.거의 모든 epoll 프로그램 은 아래 프레임 워 크 를 사용 합 니 다:

for( ; ; )
 {
  nfds = epoll_wait(epfd,events,20,500);
  for(i=0;ifd;
    send( sockfd, md->ptr, strlen((char*)md->ptr), 0 );  //    
    ev.data.fd=sockfd;
    ev.events=EPOLLIN|EPOLLET;
    epoll_ctl(epfd,EPOLL_CTL_MOD,sockfd,&ev); //     ,            
   }
   else
   {
    //     
   }
  }
 }

좋은 웹페이지 즐겨찾기