본문 바로가기
프로그래밍/Web Basic

Apache 웹서버 정리

by YuminK 2023. 11. 12.

Apache

다양한 플랫폼에서 실행되는 것을 목표로 설계되었다. 모듈 기반의 기반으로 되어 있어 컴파일/런타임 시기에 원하는 모듈을 추가할 수 있다. 서버는 요청을 처리하고 네트워크 포트에 바인딩하는 MPM과 같이 제공된다. 

 

오래된 소프트웨어와의 안전성을 생각한다면 prefork 방식을, 확장성을 고려한다면 worker나 event 방식을 선택할 수 있다. mpm_winnt 방식을 통해 윈도우 서버에서 네이티브 네트워킹 기능을 사용할 수 있다. (다른 OS에서도 적용됨)

https://httpd.apache.org/docs/2.4/en/mpm.html

 

prefork 방식

각 서버 프로세스는 들어오는 요청을 처리한다. 부모 프로세스는 서버풀의 사이즈를 관리한다. 쓰레드에 안전하지 않은 라이브러리와의 호환성을 위해 쓰레딩을 피해야 하는 사이트에서 적절하다. 

제어 프로세스는 요청이 들어왔을 때 자식 프로세스를 시작하여 처리하도록 한다. 항상 여분의 프로세스가 남아 있도록 하며, 바로 요청을 처리할 수 있도록 한다. 

https://httpd.apache.org/docs/2.4/en/mod/prefork.html

 

worker 방식

여러 쓰레드를 가지는 프로세스를 사용하여 안정성을 유지한다. 

컨트롤 프로세스가 자식 프로세스를 관리한다. 각 자식 프로세스는 고정된 서버 쓰레드를 생성하고 요청을 인식하고 서버 쓰레드에게 넘기는 리스너 쓰레드도 생성된다.

서버 쓰레드의 여분을 유지하여 클라이언트가 새로운 쓰레드나 프로세스를 기다리지 않도록 한다. 초기에 여러 프로세스가 시작되며  작동 중에 총 여유 쓰레드를 평가한다. 그리고 프로세스를 죽이거나 fork한다. (MinSpareThreads and MaxSpareThreads 범위에 따라) 

https://httpd.apache.org/docs/2.4/en/mod/worker.html

 

event 방식

프로세스와의 연결에만 쓰레드를 사용하는 목적을 가진 worker 방식의 변형이다. 동시에 많은 수의 요청을 받아들이기 위해 설계되었다. 리스너 쓰레드에게 요청 프로세싱 작업을 넘기고 worker 쓰레드가 새로운 요청을 처리하게 한다.

 

컨트롤 프로세스가 자식 프로세스의 시작을 담당한다. 각 자식 프로세스는 고정된 수의 서버 쓰레드를 생성하며 요청을 인식하고 워커 스레드에게 넘기는 리스너 쓰레드도 같이 생성된다. 

 

MPM은 HTTP의 keep alive problem을 수정하려고 시도한다. 한 클라이언트가 첫 요청을 끝낸 이후에, 커넥션을 유지하며 같은 소켓을 가지고 TCP 연결의 상당한 오버헤드를 절약한다. 아파치 웹 서버는 전통적으로 전체 자식 프로세스/스레드가 클라이언트로부터 데이터를 받기를 기다리게 한다. 이에 대한 단점을 해결하고자 MPM은 지정된 리스너 쓰레드를 각 프로세스에서 사용한다. 

 

리스너 쓰레드는 리스닝하는 소켓, keet Alive 상태인 소켓, 핸들러/프로토콜 필터가 작업을 완료하고 데이터를 보내기만 하면 되는 소켓들을 처리한다. 

 

Writing

응답을 클라이언트에게 보낼 때 연결이 느려서 TCP Write Buffer가 다 찰 가능성이 있다. 이런 상황에서 소켓에 write()을 하는 것은 EWOULDBLOCK or EAGAIN 같은 이벤트를 반환한다. (일정 시간 이후에 다시 쓸 수 있도록) 소켓을 잡고있는 소켓은 기다리는 테스크를 리스너 쓰레드에게 준다. 이후 소켓에게 이벤트가 발생하면 다시 가능한 Worker 쓰레드가 받아서 처리한다.

 

Keep-Alive

일단 Worker 쓰레드가 클라이언트에게 응답을 처리한 이후에 소켓 핸들링을 리스너 쓰레드에게 넘긴다. OS로부터 해당 소켓을 읽을 수 있다는 이벤트가 오면 리스너 쓰레드는 가능한 worker 쓰레드에게 준다. 만약 KeepAliveTimeout이 발생하면 소켓은 리스너에 의해 종료된다. 이 경우 워커 쓰레드는 idle sockets을 관리하지 않으며 다른 요청을 받는데 사용된다. 

 

Closing

MPM은 지속적 close를 실행할 필요가 있따. 즉, 클라이언트가 데이터를 보낼 때 에러를 전달해주는 것이다. 응답을 보내고 바로 연결을 끊는 것은 좋은 방식이 아니다. 클라이언트가 연결 reset이 되며, httpd의 응답을 받지 못하기 때문이다. 지속적 close는 시간 제한이 있고 상대적으로 오랜 시간이 걸릴 수 있다. 따라서 워커 쓰레드에 offload 된다. 

https://httpd.apache.org/docs/2.4/en/mod/event.html

 

mpm_winnt(Windows NT)

Windows NT OS를 위한 MPM이다. 제어 프로세스는 자식 프로세스를 생성한다. 자식 프로세스는 요청을 처리하기위해 스레드를 생성한다. 

https://httpd.apache.org/docs/2.4/en/mod/mpm_winnt.html

 

아파치 윈도우 서버

윈도우에서 아파치는 서비스로 동작하거나 콘솔 프로그램으로 동작할 수 있다.

윈도우에서 돌아가는 아파치 서버는 멀티쓰레드 환경으로 처리된다.

주로 부모 프로세스와 자식 프로세스가 있으며 자식 프로세스의 각 쓰레드에서 요청을 처리한다. 

 

부모 프로세스와 여러 요청을 멀티쓰레드로 관리하는 자식 프로세스로 관리된다.

https://httpd.apache.org/docs/2.4/en/platform/windows.html

 

윈도우 서비스

장기간 실행되는 프로그램이며 동일 PC를 사용하는 유저를 방해하지 않는다. 컴퓨터 부팅시 자동으로 시작되며 재시작시 멈춘다. 유저 인터페이스를 보이지 않는다. 서버로 사용하거나 장기간 처리되는 기능에 적합하다. 

 

비쥬얼 스튜디오에서 코드를 정의하여 서비스에게 어떤 커맨드를 받을지, 어떤 액션을 취해야 하는지를 정의할 수 있다. 커스텀 커맨드 혹은 시작, 정지, 재개, 정지 등의 커맨드를 정의할 수 있다.

https://learn.microsoft.com/en-us/dotnet/framework/windows-services/introduction-to-windows-service-applications

 

아파치 웹서버에는 프로세스를 따거나(prefork), 쓰레드를 많이 따거나(worker)

worker 기반의 MPM이나 개선이 이루어진 event 방식이 있다.

 

Apache + PHP + MySQL(APM)

Linux, Apache, MySQL, and PHP(LAMP)

댓글