- 웹서버 웹서버는 주로 정적 컨텐츠를 처리하는 데 사용된다. 이는 HTML, CSS, JavaScript 파일과 같은 고정된 파일을 클라이언트, 즉 사용자의 웹 브라우저에 제공하는 역할을 한다. 사용자가 웹 브라우저를 통해 특정 웹 페이지에 접속 요청을 하면, 웹서버는 요청받은 파일을 찾아 사용자에게 전송한다. 대표적인 웹서버로는 Apache, Nginx, Microsoft IIS 등이 있다.
- 웹 애플리케이션 서버(WAS) 웹 애플리케이션 서버는 동적 컨텐츠를 처리하기 위해 사용된다. 클라이언트의 요청에 따라 서버에서 실시간으로 처리를 해야 하는 경우에 쓰인다. 예를 들어, 데이터베이스 조회, 각종 로직 처리, 사용자 입력 처리 등 복잡한 동작을 수행하고 그 결과를 사용자에게 전송한다. 웹 애플리케이션 서버는 서버 사이드 스크립트를 실행하여 동적으로 웹 페이지를 생성할 수 있다. 주요 웹 애플리케이션 서버로는 Apache Tomcat, JBoss, WebLogic 등이 있다.
차이점
- 기능: 웹서버는 주로 정적인 파일을 처리하고, 웹 애플리케이션 서버는 복잡한 비즈니스 로직이나 데이터베이스 연동과 같은 동적인 컨텐츠를 처리한다.
- 복잡도: 웹서버는 비교적 단순한 반면, 웹 애플리케이션 서버는 훨씬 더 복잡한 기능을 제공한다.
- 용도: 웹서버는 파일 서비스에 집중하고, 웹 애플리케이션 서버는 애플리케이션의 구동과 관리에 집중한다.
• 효율적인 리소스 관리
• 정적 리소스가 많이 사용되면 Web 서버 증설
• 애플리케이션 리소스가 많이 사용되면 WAS 증설
• 정적 리소스만 제공하는 웹 서버는 잘 죽지 않음
• 애플리케이션 로직이 동작하는 WAS 서버는 잘 죽음
• WAS, DB 장애시 WEB 서버가 오류 화면 제공 가능
서블릿 컨테이너는 웹 서버와 함께 작동하여 HTTP 요청을 받고, 서블릿을 실행시켜 그 결과를 웹 클라이언트에게 돌려주는 역할을 한다. 이러한 컨테이너는 서블릿의 생명 주기를 관리하며, 웹 애플리케이션의 요청을 처리하는 중요한 기능을 수행한다.
서블릿 컨테이너의 주요 기능
- 생명주기 관리 서블릿 컨테이너는 서블릿의 생명주기를 관리한다. 서블릿 클래스를 로드하고, 인스턴스화하며, 초기화 메서드(init)를 호출한다. 이후 서블릿에 요청이 들어올 때마다 적절한 서비스 메서드(doGet, doPost 등)를 호출하고, 서블릿이 더 이상 필요하지 않을 때는 종료 메서드(destroy)를 호출하여 리소스를 정리한다.
- 멀티스레딩 관리 서블릿 컨테이너는 각 요청을 별도의 스레드에서 처리함으로써 동시성을 관리한다. 이는 여러 사용자의 요청을 동시에 효율적으로 처리할 수 있도록 해준다.
- 네트워크 통신 클라이언트와 서버 간의 소켓 연결을 관리하고, HTTP 요청을 파싱하여 서블릿에 전달하며, 서블릿의 실행 결과를 HTTP 응답으로 클라이언트에게 전송한다.
- 보안 보안 관리 기능을 통해 요청의 인증, 권한 부여 등을 처리할 수 있다. 또한, SSL 같은 보안 프로토콜을 사용하여 데이터 전송을 암호화한다.
- 세션 관리 HTTP 세션을 통해 사용자별 상태 정보를 관리한다. 이를 통해 상태가 없는 HTTP 프로토콜에서도 사용자별 상태를 유지할 수 있다.
대표적인 서블릿 컨테이너
- Apache Tomcat: 가장 널리 사용되는 오픈 소스 서블릿 컨테이너로, 소규모에서 중규모 애플리케이션에 적합하다.
- Jetty: 경량 서블릿 컨테이너로, 간단하고 빠르며 통합이 용이하여 개발 및 테스트 환경에 자주 사용된다.
- JBoss/WildFly: 엔터프라이즈급 애플리케이션을 지원하며, 강력한 클러스터링, 메시징, 분산 캐싱 기능을 제공한다.
서블릿 컨테이너는 자바 웹 개발의 핵심 컴포넌트로서, 복잡한 웹 애플리케이션과 서비스를 지원하는 데 필수적인 역할을 수행한다.
멀티 쓰레딩의 주요 개념
- 쓰레드
- 쓰레드는 프로그램 내에서 실제로 작업을 수행하는 최소 단위로, 프로세스 내에서 코드, 데이터 및 기타 리소스를 공유한다.
- 각 쓰레드는 독립적인 실행 흐름을 가지며, 고유한 실행 상태(예: 실행 중, 대기 중, 종료)를 갖는다.
- 컨텍스트 스위칭
- 멀티 쓰레딩 환경에서 CPU는 하나의 쓰레드에서 다른 쓰레드로 실행을 전환하는데, 이를 컨텍스트 스위칭이라고 한다.
- 이 과정에서 쓰레드의 상태 정보(컨텍스트)를 저장하고 복원하는 비용이 발생한다.
- 스레드 안전(Thread Safety)
- 멀티 쓰레딩 환경에서 여러 쓰레드가 동시에 같은 데이터에 접근할 때 발생할 수 있는 문제를 방지하기 위해 필요한 개념이다.
- 데이터 무결성을 보장하기 위해 동기화 기술(예: 뮤텍스, 세마포어)을 사용한다.
- 병렬 처리
- 멀티 쓰레딩은 하드웨어의 멀티코어 또는 다중 CPU 기능을 활용하여 여러 쓰레드를 실제로 동시에 실행할 수 있게 해 준다.
- 이를 통해 작업 처리량을 크게 향상시킬 수 있다.
멀티 쓰레딩의 장점
- 효율성: I/O 작업이 많은 프로그램에서 쓰레드 하나가 데이터를 기다리는 동안 다른 쓰레드가 계산을 수행할 수 있어, 자원의 사용률을 극대화한다.
- 응답성: 사용자 인터페이스와 같은 프로그램에서는 백그라운드 쓰레드가 긴 작업을 처리하는 동안에도 사용자와의 상호작용이 계속 유지될 수 있다.
- 경제성: 프로세스 간의 전환보다 쓰레드 간의 전환 비용이 낮아, 리소스를 효율적으로 사용할 수 있다.
멀티 쓰레딩의 단점
- 복잡도: 쓰레드 간의 동기화를 관리해야 하므로 프로그램의 복잡도가 증가한다.
- 디버깅 어려움: 쓰레드가 동시에 실행되기 때문에 발생하는 문제를 추적하고 디버깅하기 어렵다.
- 자원 공유 문제: 공유 자원에 대한 동시 접근이 문제를 일으킬 수 있다.
멀티 쓰레딩은 잘 설계되고 관리된다면 프로그램의 성능을 대폭 향상시킬 수 있는 강력한 도구이지만, 그 사용은 신중하게 접근해야 한다.
쓰레드 풀(thread pool)은 멀티 쓰레딩 프로그래밍에서 효율성과 성능을 최적화하기 위해 사용되는 기술로, 사전에 생성된 쓰레드 집합을 관리하는 방식이다. 쓰레드 풀은 특정 수의 쓰레드를 미리 생성하고, 이 쓰레드들을 여러 작업에 재사용함으로써, 쓰레드 생성과 소멸에 따르는 비용을 줄이고 시스템의 반응 시간을 개선한다.
쓰레드 풀의 주요 구성 요소
- 작업 큐(Task Queue)
- 대기 중인 작업들이 저장되는 큐. 쓰레드 풀에 들어오는 각 작업은 이 큐에 쌓이고, 쓰레드가 사용 가능할 때 큐에서 작업을 꺼내 처리한다.
- 작업 처리 쓰레드(Worker Threads)
- 쓰레드 풀에 의해 생성되고 유지되는 쓰레드들. 이 쓰레드들은 작업 큐에서 작업을 가져와 실행한다.
- 쓰레드 풀 관리자(Thread Pool Manager)
- 쓰레드 풀의 생성, 관리 및 작업 할당을 담당하는 구성 요소. 작업 큐의 상태를 모니터링하고, 쓰레드를 효율적으로 할당한다.
쓰레드 풀의 주요 이점
- 리소스 관리
- 쓰레드 풀은 쓰레드를 미리 생성하고 필요에 따라 재사용하기 때문에, 쓰레드 생성과 종료에 따른 리소스 소모를 줄일 수 있다.
- 성능 향상
- 작업 처리 시, 새로운 쓰레드를 매번 생성하는 것이 아니라 기존의 쓰레드를 재사용함으로써 시스템의 반응 시간과 성능이 향상된다.
- 쓰레드 수 제한
- 쓰레드 풀은 생성 가능한 쓰레드 수를 제한하여, 과도한 쓰레드 생성으로 인한 시스템 오버헤드를 방지한다.
- 작업 부하 관리
- 쓰레드 풀을 사용하면 서버의 작업 부하를 더욱 쉽게 조절하고 관리할 수 있다.
쓰레드 풀의 단점
- 복잡도 증가
- 쓰레드 풀을 효율적으로 관리하려면 추가적인 로직이 필요하며, 설계와 구현이 복잡해진다.
- 자원 공유 문제
- 여러 쓰레드가 자원을 공유할 때 발생할 수 있는 동기화 문제를 고려해야 한다.