웹 서버는 IP 주소, 인터럽트 또는 폴링을 어떻게“수신”합니까?


87

웹 서버의 세부 사항을 이해하려고합니다. Apache와 같이 서버가 새로운 요청을 지속적으로 폴링하는지 또는 일종의 인터럽트 시스템으로 작동하는지 궁금합니다. 인터럽트 인 경우 인터럽트를 발생시키는 원인은 네트워크 카드 드라이버입니까?


1
이해해야 할 키워드는 "server" 입니다. 서버-클라이언트 모델 (마스터-슬레이브 모델)에서 서버 클라이언트의 요청을 기다립니다 . 이러한 요청은 서비스가 필요한 이벤트 입니다. 웹 서버는 응용 프로그램입니다. 귀하의 질문은 관련 개념을 동일한 추상화 계층에 유지하기보다는 응용 프로그램 SW와 HW 용어 (예 : 인터럽트 및 NIC)를 결합합니다. NIC 드라이버는 실제로 폴링을 사용할 수 있습니다. 예를 들어, 패킷이 많은 경우 Linux NAPI 드라이버가 폴링으로 회귀합니다. 그러나 이는 이벤트 처리 응용 프로그램 SW와 관련이 없습니다.
톱밥

1
@sawdust 매우 흥미 롭습니다. 문제는 실제로 SW 프로세스와 HW 프로세스 간의 연결을 이해하기위한 것입니다.
user2202911

1
명령 줄 (및 기타 GUI) 프로그램이 키보드를 듣는 방식과 매우 유사합니다. 특히 커널이 키보드 장치에서 데이터를 수신하여 창 관리자에게 전달하는 단계가있는 윈도우 시스템에서 포커스가있는 창을 식별하고 해당 창에 데이터를 제공합니다.
G-남자

@ G-Man : 이론이 맞습니다. 실제로 대부분의 타이피스트는 1Gbit / s로 타이핑하지 않으므로 두 가지 다른 아키텍처가 필요합니다. 하나는 깨끗하고 유연하며 느리고 어색하지만 고속입니다.
MSalters

답변:


181

짧은 대답은 일종의 인터럽트 시스템입니다. 기본적으로 이들은 차단 I / O를 사용합니다. 즉, 새 데이터를 기다리는 동안 절전 (차단)됩니다.

  1. 서버가 청취 소켓을 만든 다음 새 연결을 기다리는 동안 차단합니다. 이 시간 동안 커널은 프로세스를 인터럽트 가능한 휴면 상태로 만들고 다른 프로세스를 실행합니다. 프로세스 폴링을 지속적으로 수행하면 CPU가 낭비됩니다. 커널은 작업이 완료 될 때까지 프로세스를 차단하여 시스템 리소스를보다 효율적으로 사용할 수 있습니다.

  2. 네트워크에 새 데이터가 도착하면 네트워크 카드가 인터럽트를 발행합니다.

  3. 네트워크 카드에서 인터럽트가 발생하면 커널은 네트워크 카드 드라이버를 통해 네트워크 카드에서 새 데이터를 읽고 메모리에 저장합니다. (이 작업은 빠르게 수행해야하며 일반적으로 인터럽트 처리기 내부에서 처리됩니다.)

  4. 커널은 새로 도착한 데이터를 처리하여 소켓과 연결합니다. 해당 소켓에서 블로킹되는 프로세스는 실행 가능으로 표시되어 이제 실행할 수 있음을 의미합니다. 반드시 즉시 실행할 필요는 없습니다 (커널은 다른 프로세스를 계속 실행하기로 결정할 수 있습니다).

  5. 여가 시간에 커널은 차단 된 웹 서버 프로세스를 깨 웁니다. 이제는 실행할 수 있습니다.

  6. 시간이 지나지 않은 것처럼 웹 서버 프로세스가 계속 실행됩니다. 차단 시스템 호출이 리턴되고 새 데이터를 처리합니다. 그런 다음 ... 1 단계로 이동하십시오.


18
커널과 웹 서버 프로세스의 명확한 묘사를 위해 +1
Russell Borogove가

13
나는 이것이 매우 명확하고 간단하게 요약 될 수있는 것처럼 복잡한 것을 믿을 수는 없지만 당신은 그것을했습니다. +1
Brandon

8
+1 좋은 답변입니다. 또한 2에서 3 사이의 단계는 최신 NIC, OS 및 드라이버에서 조금 더 복잡해질 수 있습니다. 예를 들어, Linux에서 NAPI 를 사용하면 실제로 패킷이 인터럽트 컨텍스트에서 수신되지 않습니다. 대신 커널은 "괜찮아 NIC, 데이터가 있음을 이해합니다. 버그 처리를 중단하십시오 (인터럽트 소스 비활성화).이 패킷 그 이전에 도착할 수있는 후속 패킷을 곧 가져 오겠습니다 ."
Jonathon Reinhart 2018

8
약간의 nitpick : 실제로 차단할 필요는 없습니다. 서버 프로세스가 청취 소켓을 생성하자마자 커널은 내부에서 차단되지 않은 경우에도 해당 포트에서 SYN을 수락 accept합니다. 그들은 독립적으로, 비동기 적으로 실행되는 작업입니다 (행운스럽게도 아니면 완전히 빨려 요!). 연결이 들어 오면 연결을 accept끌어 오는 대기열에 배치됩니다 . 없는 경우에만 차단됩니다.
Damon

3
"네트워크 카드에서 새 데이터를 읽고 메모리에 저장합니다.이 작업은 신속하게 수행해야하며 일반적으로 인터럽트 처리기 내에서 처리됩니다."직접 메모리 액세스를 사용하지 않습니까?
Siyuan Ren

9

"더 낮은"세부 사항이 많이 있습니다.

먼저, 커널에 프로세스 목록이 있고 주어진 시간에 이러한 프로세스 중 일부가 실행 중이고 일부는 실행 중이 아님을 고려하십시오. 커널은 각각의 실행중인 프로세스가 CPU 시간 조각을 허용 한 다음 중단하고 다음 프로세스로 이동합니다. 실행 가능한 프로세스가없는 경우 커널은 하드웨어 인터럽트가있을 때까지 CPU를 일시 중단시키는 HLT 와 같은 명령 을 CPU에 발행합니다 .

서버 어딘가에 "할 일을 줘" 라는 시스템 호출 이 있습니다. 이를 수행 할 수있는 방법에는 두 가지 범주가 있습니다. 아파치의 경우, accept아파치가 포트 80에서 수신 대기중인 아파치가 이전에 연 소켓을 호출 합니다. 커널은 연결 시도 큐를 유지하고 TCP SYN 이 수신 될 때마다 해당 큐에 추가합니다 . 커널이 TCP SYN이 수신되었음을 알 수있는 방법은 장치 드라이버에 따라 다릅니다. 많은 NIC의 경우 네트워크 데이터가 수신 될 때 하드웨어 인터럽트가있을 수 있습니다.

accept커널에게 다음 연결 시작으로 돌아 오도록 요청합니다. 대기열이 비어 있지 않으면 accept즉시 반환됩니다. 큐가 비어 있으면 프로세스 (Apache)가 실행중인 프로세스 목록에서 제거됩니다. 연결이 나중에 시작되면 프로세스가 재개됩니다. 이것을 "블로킹"이라고합니다. 호출하는 프로세스 accept()는 결과가 나올 때까지 반환되지 않는 함수처럼 보입니다. 이 시간 동안 프로세스는 다른 작업을 수행 할 수 없습니다.

일단 accept돌아 가면 Apache는 누군가 연결을 시도하고 있음을 알고 있습니다. 그런 다음 포크 를 호출 하여 Apache 프로세스를 두 개의 동일한 프로세스로 분할합니다. 이러한 프로세스 중 하나는 계속해서 HTTP 요청을 처리하고 다른 프로세스 accept는 다음 연결을 얻기 위해 다시 호출 합니다. 따라서 항상 accept하위 프로세스를 호출 하고 스폰하는 것 외에는 아무것도하지 않는 마스터 프로세스가 있으며 각 요청마다 하나의 하위 프로세스가 있습니다.

이것은 단순화입니다. 프로세스 대신 스레드를 사용하여이를 fork수행 할 수 있으며, 요청을 수신 할 때 작업자 프로세스 를 미리 준비하여 시작 오버 헤드를 줄일 수도 있습니다. Apache가 구성된 방식에 따라 다음 중 하나를 수행 할 수 있습니다.

즉, 작업을 수행하는 방법의 첫 번째 광범위한 범주이고, 그것은이라고 IO를 차단 시스템처럼 호출하기 때문에 accept하고 read그리고 write그들이 돌아 뭔가를 때까지 프로세스를 일시 중단합니다 소켓에서 작동한다.

이를 수행하는 다른 광범위한 방법은 비 차단 또는 이벤트 기반 또는 비동기 IO라고 합니다. 이것은 select또는 과 같은 시스템 호출로 구현됩니다 epoll. 이것들은 모두 똑같은 일을합니다. 소켓 (또는 일반적으로 파일 디스크립터)의 목록과 그것들과 함께하고 싶은 일, 커널 블록은 그 중 하나를 수행 할 준비가 될 때까지 제공합니다.

이 모델을 사용하면 커널에을 사용하여 epoll"포트 80에 새로운 연결이 있거나 내가 연 9471 개의 다른 연결에서 읽을 새 데이터가있을 때 알려주십시오" 라고 말할 수 있습니다 . epoll그 중 하나가 준비 될 때까지 차단하면됩니다. 그런 다음 반복하십시오. 시스템 호출 같은 acceptreadwrite블록, 부분적으로 당신이 그들을 호출 할 때마다 때문에, 결코 epoll그냥 차단 할 이유가 없을 것, 그래서 그들은 준비가되어 있다는 것을, 당신은 소켓 또는 지정한 파일을 열 때 당신이 그들을 원하는 것이 있기 때문에 당신을 말해주지 비 차단 모드에서는 EWOULDBLOCK차단 대신 통화가 실패 합니다.

이 모델의 장점은 하나의 프로세스 만 필요하다는 것입니다. 즉, 각 요청에 대해 스택 및 커널 구조를 할당 할 필요가 없습니다. NginxHAProxy 는이 모델을 사용하므로 비슷한 하드웨어에서 Apache보다 더 많은 연결을 처리 할 수있는 큰 이유입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.