같은 컴퓨터라도 서비스를 해주느냐 제공받느냐에 따라 서버와 클라이언트로 나뉜다.
그런데 이렇게만 말하면 서버라는 게 뭔가 하드웨어에 국한되는 느낌이다.
서버는 소프트웨어일 수 있다.
서버에 관해 이야기 할 때 꼭 등장하는 웹서버
와 웹 애플리케이션 서버
가 있다.
이에 대해 자세히 알아보면서 소프트웨어로서의 서버에 대한 감을 잡아보자.
어떤 컴퓨터로 하여금 서버 역할을 하도록 해주는 소프트웨어를 ㅇㅇ서버 라고 부르기도 한다. 그래서 백엔드 개발자가 "서버를 개발한다"
라고 하는것은 소프트웨어를 개발하는 것
이다.
즉 이 웹서버도 소프트웨어의 개념이다. 아파치
와 NginX
가 대표적인 제품이다.
웹!서버!니까 서버들 중에서도 웹사이트를 제공하는 서버로 만들어주는 서비스인것이다.
이러한 웹 서버는 웹사이트가 서비스 될 때 필요한 것들(브라우저가 읽을 수 있는 파일들 HTML, CSS, JS 파일들과 각종 이미지, 기타 여러 데이터들) 을 서버에서 사용자에 컴퓨터로 보내줄 수 있어야한다.
이 파일들은 원래 서버 컴퓨터에 저장이 되어있다.
이 서버의 특정 폴더, 디렉토리에 이것들을 넣어두면, 이 폴더를 외부에서 접근 가능하도록 개방해서 서버에 지정된 웹사이트 주소로 접속하면 이것들을 받아갈 수 있도록하는 것이 웹서버의 기본적인 역할 중 하나이다.
대표적인 웹 서버 : 아파치, NginX[엔진엑스], IIS(윈도우 서버)
이 프로그램들로 서버 컴퓨터에 있는 어떤 폴더를 개방해서 거기에 들어있는 HTML등 파일들로 웹사이트를 제공할 수 있는것이다.
하지만 단순히 이렇게만 하면 정적웹을 제공하는 것에 불과하다.
동적웹을 제공하는 것을 웹서버의 고유 역할로 정의해야할지는 애매하지만 아파치나 NginX의 모듈로 어느정도 할 수 있긴하다.
이를테면 오랫동안 사용되어온 방법으로 아파치, PHP, MySQL (이 셋의 조합을 APM이라고 부르기도 했다.)을 연동시켜서 동적인 PHP웹사이트를 제공하는 방식이 있다.
아파치에 PHP를 해석할 수 있는 모듈을 세팅해놓으면 웹 접근이 있을 때마다 PHP코드에 적힌 레시피
대로 MySQL에 있는 식재료
들을 가져와서 아파치가 (동적으로) 요리
를 해준다고 비유할 수 있겠다. (NginX도 다 가능)
사실 웹 동적웹을 전문적으로 다루는 전문 요리사
들(동적웹을 전문적을 담당)이 따로 있다. 이것들이 웹 애플리캐이션 서버(톰캣이나 Node.js Django 내장 서버 등)이다.
아파치가 주방 보조 정도
의 역할만 한다고 할 수 있다. 전문 요리사들
과 손님
들 사이에서 서빙이나 매니지먼트를 담당하기도 한다.
: Web Application Sever(WAS[와스])
web 과 server사이에 application 이라는 말이 들어간다. 단순히 무엇을 갖다주는게 아니라 뭔가 프로그래밍된 걸 더 한다는 것이다.
이것은 동적 사이트를 전문적으로 처리해준 것이라고 보면된다.
아파치
나 NginX
같은 웹서버
도 어느정도 동적 사이트를 처리할 수 있지만 복잡한 동적 사이트 처리는 톰캣
같은 WAS
의 손을 빌려야하는 것이다.
"아파치를 톰캣과 연동한다"
이와 같은 말을 들어본적이 있을 것이다.
자바 바이트 코드로 컴파일 되는 언어들에 쓰이는 걸로 가장 흔히 사용되는 톰캣
,Jetty
, undertow
등이 있다.
요즘은 스프링 부트에 톰캣이 내장되기 때문에 직접은 많이 접하지는 않지만 JAVA와 JSP로 만든 웹 또는 API어플리케이션을 실행할때
이 톰캣
같은 WAS
가 사용된다.
톰캣의 원리(심화)
: 톰캣을 사용하는 방법은, 스프링으로 코딩한 웹앱을 war파일로 빌드하면 그 안에 .class파일들이랑, jsp, 이미지, CSS, 자바스크립트 파일 등이 압축되어 있다.
톰캣을 다운받아 보면 여러 폴더들과 파일들이 들어있는 하나의 폴더로 되어 있는데, 그 중 틀정 폴더에 방금 말한 war파일을 넣고 명령어를 실행하면 스프링 서비스가 톰캣을 사용해서 돌게 되는 것이다.
요즘에는 반대로 스프링을 톰캣이 들어있는 jar파일로 빌드해서 배포하곤 한다.
대표적인 웹 애플리케이션 서버 : 톰캣, jeus(제우스), IBM, websphere
WAS를 검색하면 주로 JAVA것만 나오는데, 사실 이것이 다 정의하기 나름이고 진영마다 배포구조들도 달라서 다른 진영에서는 딱히 "어떤것이 WAS의 역할이다!" 이렇게 딱히 구분해서 용어를 쓰지는 않는 걸로 보인다.
Node.js의 경우는 어플리케이션이 WAS의 역할까지한다거나 하는 것처럼 쓰는 말이 다르다고 보면 된다. 공통적인 것은!
웹서버를 앞단에 두고 (손님들을 웹서버가 응접실에서 접대하도록 하고 뒤에서 [WAS든 뭐라고 부르든] 전문 요리사가 요리를 하고 있는 것이다.)
사실 톰캣들의 WAS들도 방문자에서 동적으로 생성한 웹 뿐만 아니라, 정적 리소스를 건내주는 일을 할 수도 있다. 아파치 없이도 웹사이트를 제공할 수는 있다는 것이다.
예전에는 톰캣이 정적요소를 넘겨주는 늦어서 아파치가 대신해줬지만, 이제 톰캣이 성능이 좋아여 어느정도 아파치와 비슷한 수준의 성능을 보인다.
하지만 그럼에도 아파치나 NginX를 앞단에 두어 손님들을 맞게하는 이유가 따로있다.
웹서버가 위에서 말한 기본적으로 하는 일들 말고도 다양한 기능들을 제공한다.
정확히 말하면 reverse proxy 기능이다.
reverse proxy : 손님들에게 서버의 주소를 감추는 것이다. (방문자가 본인의 IP감추는 것은 forward proxy임)
서버가 어디있는지 다 알고 손님들이 찾아왔긴했지만, 보안상 서버의 내부 구조는 감출 필요가 있기 때문에 프록시를 사용한다. 서버 내부적으로 파일이 어느 폴더에 들어있는지. 서비스가 몇 번 포트로 돌고 있는지 등을 감추는 것이다.
이처럼 어떤 웹 프레임워크든 앞단에 '아파치'나 'NginX'를 두는 이유가 이러한 보안 측면 때문인 것이다.
웹서버의 또다른 기능으로 (리버스 프록시의 기능으로 여겨지긴 함) 로드 밸런싱이 있다.
톰캣이 여러게 돌고 있을 때 밸런스를 맞춰주는 것을 말한다.
톰캣 뿐 아니라 다른 종류의 WAS들도 마찬가지다.
손님들이 여럿 몰릴 때 여러 분산해서 주문을 넣어주는 역할을 하는 것이다.
서버 한 대에서 사이트 하나를 돌릴 때, 톰캣을 여러개 두는 경우가 있는데 이는 지속성을 위함이다.
스프링으로 만든 웹 등의 서비스에 새 기능을 추가해서 동적부분까지 업데이트 해줘야 하는 경우에는 돌던 서비스를 종료하고 다시 실행을 해줘야 한다.
짧은 차이지만 그 사이 사용자가 접근하면 오류가 뜬다.
이를 방지하기 위해 톰캣을 여러개 두면 이것들이 차례차례 업데이트를 하고, 웹서버가 다른 톰캣들로 주문들을 분산해줘서 사용자 입장에서 서비스를 끊김 없이 이용할 수 있도록 할 수 있다.
또한 톰캣 등의 인스턴스를 여럿 돌려서 작업을 분산하는게 성능 측면에서 나은 경우들이 있기 때문에 톰캣을 여러개 두기도한다.
이런 조건들을 감안해서 다수의 인스턴스로 서비스를 돌리고 이를 웹서버로 밸런싱하는 것이다.
웹서버의 또 다른 중요 기능으로 캐싱이 있다. 여기서 말하는 캐싱은 reverse proxy의 캐싱이다.
forword proxy의 캐싱 기능이 사용자 관점에서의 캐싱이라면, reverse proxy의 캐싱은 서버 단에서의 캐시다.
서버로 찾아오는 손님들이 자주, 반복적으로 찾을 만한 리소스들을 응접실에 쌓아뒀다가 바로 건내주는 것이다. 어느쪽이든 사용자 입장에서 빨라지는 건 마찬가지다.
이 외에도 웹서버는 수많은 모듈들을 사용해서 뒷단 WAS들이 정상작동하는지를 주기적으로 헬스체크 하는 등 서비스를 안정적이고 안전하게 돌리기 위한 다양한 기능들을 제공한다.
정리하자면 웹서버와 WAS의 역할이 겹치는 부분도 있지만 각자가 특화된 부분들을 활용해서 보안성 유지와 운영을 응접실에서 손님을 직접 상대하고, WAS나 다른 비슷한 어플리케이션들은 뒤에서 동적 요소들을 만들어내는데 집중하는 것이다.
아파치가 오래전부터 널리 사용되어 오던 것이고, NgixX가 등장한 이후 아파치의 점유율을 따라잡는 추세이다.
이 둘은 작동방식에 있어 근본적인 차이가 있다.
아파치
는 다중 프로세스
, NginX는
이벤트
로 일을 처리한다는 것이다.
아파치는 MPM(멀티 프로세스 모듈)방식으로 일을한다.
이것에는 두가지 방식이 있다. 손님이 올때마다 프로세스를 새로 생성하는 방식(mpm-prefork)
과, 한 프로세스 안에서 스레드를 새로 생성하는 방식(mpm-worker)
이다.
즉 손님마다 프로세스를 두는 방식은 말하지면 손님이 새로 올 때마다 상담 테이블을 따로 가져와서 앉히는 것이다. 그리고 이 테이블들을 계속 돌아니면서 여러 손님들을 동시에 상대하는 것이다.
즉 한 프로세스에서 손님마다 스레드를 생성한 다는 건, 가로로 길다란 테이블을 하나 두고, 손님이 올 때마다 나란히 앉힌 다음 역시 좌우로 돌아다니면서 동시에 업무를 처리하는 것이다.
두번째 방식이 그나마 낫겠지만 둘 다 이리저리 계속 돌아다녀야한다. 그리고 이 자리들이 또 다 메모리이다. 때문에 이 방식은 컴퓨터 자원을 많이 소모한다.
컨텍스트 스위칭 : 프로세스나 스레드가 이거 하다 저거 하러 가는 거.
반면 NginX의 event driven 방식은 비유하자면, 작은 데스크 하나만을 두고 손님들을 한 줄로 쭉 세우는 것
이다. 그리고 다음 손님이 오는대로 업무별로 집중해서 일을 처리하는 것이다. 때문에 컴퓨터에 부담이 덜하다
.
성능으로는 NginX가 더 낫다.
이를 보완하기 위해 아파치도 이벤트 방식을 추가했다.
여튼 그래서 성능과 가벼움을 중요시하는 서비스
에서는 Ngix
, 다양하고 검증된 기능들을 필요로 하는 서비스
에서는 오랜 기간 사용되면서 안정성을 갖춰온 아파치
를 사용한다.
참고문헌 : 얄팍한 코딩사전