서버를 실행한다는 것은 무엇을 의미할까?
개발자들이 “서버를 실행했어요”, “서버를 켰어요”라고 말하는 것을 들어보셨을 겁니다. 또는 “서버가 다운됐다”, “서버를 재시작해야 한다”는 말도 자주 듣죠. 그런데 정확히 서버를 실행한다는 것은 무엇을 의미할까요? 이번 글에서는 서버 실행의 의미와 그 뒤에서 일어나는 일들을 쉽게 설명하겠습니다.
서버 실행의 기본 개념
서버를 실행한다는 것은 컴퓨터나 프로그램이 클라이언트의 요청을 받아들일 준비를 하고 대기 상태에 들어가는 것을 의미합니다. 쉽게 말해, “손님을 맞을 준비를 마치고 가게 문을 여는 것”과 같습니다.
식당에 비유하면 이해하기 쉽습니다. 식당 주인이 아침 일찍 가게에 와서 조명을 켜고, 식재료를 준비하고, 테이블을 정리하고, 주방 기구를 점검한 후 “영업 중” 간판을 걸고 문을 여는 과정이 바로 서버를 실행하는 것과 같습니다. 손님(클라이언트)이 올 때까지 가게 안에서 대기하면서, 손님이 오면 즉시 서비스를 제공할 준비가 되어 있는 상태죠.
서버를 실행하면 컴퓨터는 특정 포트에서 요청을 기다립니다. 예를 들어 웹 서버를 실행하면 80번이나 443번 포트를 열고, “이 포트로 들어오는 모든 요청을 처리하겠다”고 선언하는 것입니다. 마치 식당이 “우리는 12번 테이블까지 준비되어 있으니 손님 받을 수 있습니다”라고 알리는 것과 같습니다.
서버 실행 시 일어나는 일들
서버를 실행하면 컴퓨터 내부에서 여러 가지 일이 순차적으로 일어납니다.
프로그램 로딩이 가장 먼저 일어납니다. 서버 소프트웨어(Apache, Nginx, Node.js 등)가 메모리에 적재됩니다. 이것은 식당에서 조리 도구를 꺼내 준비하는 것과 같습니다. 프로그램이 메모리에 올라가야 실제로 작동할 수 있습니다.
다음으로 설정 파일 읽기가 진행됩니다. 서버는 설정 파일을 읽어서 어떤 포트를 사용할지, 어떤 디렉토리의 파일을 서비스할지, 최대 몇 명의 사용자를 동시에 처리할지 등의 정보를 확인합니다. 식당으로 치면 오늘의 메뉴판을 확인하고, 영업시간을 체크하는 과정입니다.
**포트 바인딩(Port Binding)**도 중요한 단계입니다. 서버는 특정 포트 번호를 “예약”합니다. 예를 들어 웹 서버가 80번 포트를 사용하겠다고 운영체제에 알리면, 이제 80번 포트로 들어오는 모든 네트워크 요청은 이 서버 프로그램이 처리하게 됩니다. 하나의 포트는 동시에 하나의 프로그램만 사용할 수 있기 때문에, 만약 이미 다른 프로그램이 80번 포트를 사용 중이라면 서버 실행이 실패합니다.
데이터베이스 연결도 이 시점에 이루어집니다. 많은 서버는 데이터베이스와 연결을 미리 설정해둡니다. 식당에서 냉장고를 열어 식재료를 확인하는 것처럼, 서버도 필요한 데이터에 접근할 수 있는지 확인합니다.
마지막으로 대기 상태(Listening State) 진입입니다. 모든 준비가 끝나면 서버는 요청을 기다리는 상태가 됩니다. 이제 클라이언트가 요청을 보내면 즉시 응답할 수 있습니다. 터미널이나 로그에 “Server is running on port 3000” 같은 메시지가 표시되는 것을 보셨다면, 바로 이 대기 상태에 들어갔다는 의미입니다.
로컬 서버 실행 예시
개발자가 자신의 컴퓨터에서 로컬 서버를 실행하는 과정을 살펴보겠습니다.
Node.js로 간단한 웹 서버를 만들었다고 가정해봅시다. 개발자는 터미널에서 “node server.js”라는 명령어를 입력합니다. 그러면 Node.js가 server.js 파일을 읽고 실행하기 시작합니다.
코드 안에는 “3000번 포트에서 대기하라”는 명령이 있습니다. Node.js는 운영체제에게 “3000번 포트를 사용하겠다”고 요청하고, 허가를 받으면 그 포트에서 요청을 기다립니다. 터미널에 “Server listening on port 3000″이라는 메시지가 표시되면 서버 실행이 완료된 것입니다.
이제 개발자는 웹 브라우저를 열고 “localhost:3000” 또는 “127.0.0.1:3000″을 입력합니다. 브라우저는 자신의 컴퓨터의 3000번 포트로 요청을 보내고, 방금 실행한 서버가 이 요청을 받아 응답을 보냅니다. 화면에 웹페이지가 표시되면 성공입니다.
이 모든 과정이 자신의 컴퓨터 안에서 일어나기 때문에 인터넷 연결이 없어도 작동합니다. 개발자는 이렇게 로컬 서버에서 개발하고 테스트한 후, 완성되면 실제 서버에 배포합니다.
실제 서버 실행
실제 운영 환경에서 서버를 실행하는 것은 좀 더 복잡합니다.
클라우드 서비스(AWS, Google Cloud 등)에 서버를 구축했다면, 원격으로 접속해서 서버를 실행합니다. SSH(Secure Shell)라는 프로토콜을 사용해 터미널로 서버에 접속한 후, 서버 프로그램을 실행하는 명령어를 입력합니다.
하지만 실제 서버는 개발자가 로그아웃하거나 터미널을 닫아도 계속 실행되어야 합니다. 24시간 내내 사용자의 요청을 처리해야 하니까요. 그래서 PM2, systemd, Docker 같은 도구를 사용해서 서버를 “백그라운드”에서 실행시킵니다.
예를 들어 PM2를 사용하면 “pm2 start server.js”라는 명령 하나로 서버가 백그라운드에서 실행되고, 에러가 나서 종료되면 자동으로 재시작되며, 서버가 재부팅되어도 자동으로 다시 실행됩니다. 마치 자동화된 무인 식당처럼 주인이 없어도 계속 운영되는 것이죠.
서버 실행 중 모니터링
서버가 실행되면 끝이 아니라 지속적인 모니터링이 필요합니다.
CPU 사용률을 확인합니다. 서버가 요청을 처리하면서 CPU를 얼마나 사용하는지 체크합니다. 너무 높으면 서버가 과부하 상태라는 뜻이고, 응답 속도가 느려집니다.
메모리 사용량도 중요합니다. 서버는 데이터를 메모리에 올려서 처리하는데, 메모리가 부족하면 프로그램이 비정상 종료될 수 있습니다. 메모리 누수(Memory Leak)가 있는지도 확인해야 합니다.
네트워크 트래픽을 모니터링합니다. 얼마나 많은 요청이 들어오고, 얼마나 많은 데이터를 전송하는지 확인합니다. 갑자기 트래픽이 급증하면 서버를 증설해야 할 수도 있습니다.
로그(Log) 파일도 계속 확인합니다. 서버는 모든 활동을 로그 파일에 기록합니다. 어떤 요청이 왔는지, 에러가 발생했는지, 어떤 사용자가 접속했는지 등의 정보가 담겨 있습니다. 문제가 생기면 로그를 분석해서 원인을 찾습니다.
서버를 멈춘다는 것
서버를 실행하는 것만큼 적절히 멈추는 것도 중요합니다.
서버를 급작스럽게 강제 종료하면 문제가 생길 수 있습니다. 처리 중이던 요청이 중간에 끊기고, 저장 중이던 데이터가 손실될 수 있습니다. 그래서 Graceful Shutdown(우아한 종료)이라는 개념이 있습니다.
우아한 종료는 식당이 문을 닫을 때와 비슷합니다. 갑자기 “지금 당장 나가세요”라고 하지 않고, “신규 손님은 받지 않지만 식사 중인 손님은 다 마칠 때까지 기다리겠습니다”라고 하는 것이죠. 서버도 마찬가지로 새로운 요청은 거부하지만, 처리 중인 요청은 모두 완료한 후에 종료됩니다.
서버를 재시작할 때도 마찬가지입니다. 무중단 배포(Zero-downtime Deployment)라는 기법을 사용하면, 서비스 중단 없이 새 버전으로 업데이트할 수 있습니다. 두 대의 서버를 번갈아가며 재시작하는 방식으로, 사용자는 서버가 재시작되는지도 모르게 계속 서비스를 이용할 수 있습니다.
서버를 실행한다는 것은 단순히 프로그램을 켜는 것 이상의 의미입니다. 사용자에게 서비스를 제공할 준비를 완료하고, 24시간 요청을 처리할 자세를 갖추는 것입니다. 이 과정을 이해하면 웹 서비스가 어떻게 작동하는지 더 깊이 이해할 수 있을 것입니다.
Leave a Reply