티스토리 뷰

반응형

2019/09/19 - [Programming/Java] - Spring Boot 을 언제 써야 할까? (2) 외장 WAS 가 반드시 필요한가?

외장 WAS 만이 할 수 있는 것이 있기 때문에 Spring Boot 는 작은 프로젝트에 적합하고 Spring 이 큰 프로젝트에 적합하다는 이야기를 하는 분들이 계실꺼라 생각합니다. 실제로 제가 들은 주장에서도, 처음 프롤로그에 있는 제타건담 님의 댓글 내용에서도 외장 WAS 에서만 되는 것, 혹은 되는 것 처럼 알려진 것들을 이유로 외장 WAS 을 써야 한다는 주장을 하는 사람도 있었습니다.

 

실제 있었던 일인데, Spring Security 하위 프로젝트인 Spring Security oAuth 을 이용해 사내의 oAuth2 Server 에 인증을 요청하는 Client 을 이용한 프로젝트를 개발한 것이 있었습니다. 제가 사내 개발자들이 사용하기 쉽도록 공통 라이브러리를 만들고 문서를 만들어서 제공했는데, 이게 문제가 좀 있었습니다. Load Balancer 장비에서 HTTPS 로 요청된 것을 HTTP 로 변환해 프로그램에 요청을 보내줬는데, Spring Security oAuth Client 에서는 요청이 HTTP 이면 HTTPS 으로 요청을 보내라고 다시 REDIRECT 을 시키기 때문에 무한반복이 되는 문제였습니다. 일단, 이 문제는 장비에서 HTTPS 로 보내는 형태로 변경해서 넘어갔습니다. 제가 개발하던 프로그램도 아니었고, 내부 문제로 제가 다른 팀으로 가게 되면서 라이브러리를 손대기 애매한 상황이었거든요. 나중에 다른 팀에서 만든 프로그램에서 다시 그 라이브러리를 제가 쓰게 되면서 사실 옵션 하나 주면 끝나는 문제인데, 이전 프로그래머가 이것저것 적용해보다가 꼬여서 안됐던 것으로 보였습니다.

문제는, 이 증상이 나타났을 때 Spring Boot 에서 tomcat-embed 을 쓰던 그 프로그램을 외장 Tomcat 으로 바꾸라고 계속 이야기하던 한 사람이 있었기 때문입니다. 모든 문제는 tomcat-embed 가 문제인 것 처럼 말이죠. 위에서 언급했듯이 이건 WAS 와는 아무런 관련이 없는 문제인데, embed 라는 단어에 현혹되어 무슨 일만 생기면 이게 나쁘다고 생각하는 것이 문제였습니다.

 

서론이 좀 길었습니다. 어쨌든, 위와 같이 외장 WAS 와 내장(embed) WAS 가 가지는 차이가 무엇인지 알아야 이러한 혼선이 없을꺼라 생각하기에, 제가 아는 선에서 가장 크게 느끼는 차이를 이야기 해보고자 합니다.

 

가장 큰 차이는 Virtual Host 가능 여부입니다. Spring Boot 은 그 자체가 하나의 프로그램이기 때문에 Servlet Container 으로 동작 시 하나의 포트를 독자적으로 점유하게 됩니다. 그렇기 때문에 여러 프로그램이 같은 포트를 이용해 서비스 할 수 없습니다. 하지만, 외장 WAS 은 스스로 하나의 포트를 점유한 뒤, 내부에서 여러 도메인을 각자 서비스 할 수 있는 기능이 있습니다. Apache HTTPd 에서 <VirtualHost> 로 선언할 수 있는 기능이기 때문에 흔히 Virtual Host 라고 부르며, Tomcat 에서는 <Host> 설정에서 도메인을 구분하여 여러 <Host> 을 선언하여 동시에 여러 웹서비스를 하나의 포트로 서비스 할 수 있게 해줍니다.

그럼, 이 기능이 대형 서비스에서 정말 필수불가결한 요소이며, Spring Boot 은 이것이 안되기에 크게 문제가 될까요?

아닙니다. 이 기능은 최근의 Infra 와는 잘 맞지 않는 형태입니다. 이 기능은 예전같이 Web Server 을 IDC 에 입주시키는 형태일 때 유용한 기능이었습니다. IDC 에는 물리적 Server 의 크기(U 단위의 높이 기준)에 따라 비용 변동이 가장 심하기 때문에 예산 대비 적정한 크기의 서버를 최대한 고사양으로 구입해 운영하는 형태가 유리했습니다. 당연히 하나의 서버는 아주 고사양이었고, 많은 트래픽을 처리할 수 있었기 때문에 서비스 별로 이런 고사양의 서버를 운영하는 것 보다는 하나의 서버에 여러 서비스를 운영하는 것이 훨씬 이득이었습니다.

하지만, 현재는 Cloud 나 Docker 가 대세가 된 상황이라 하나의 서버에 여러 개를 운영하는 것보다는 하나의 VM 이나 Docker Image 에 하나의 서비스만 구성하고 여러 개로 나누어서 서비스하는 것이 대세입니다. 기존의 Virtual Host 은 외부의 다른 서비스(L4/L7)에서 대신 처리해주기 때문에 가능한 일입니다. 기존의 물리 서버의 경우는 증설 시 비용도 상당하고 하드웨어 준비 기간도 소모되고 축소 시에 장비의 처분도 곤란했지만, VM 이나 Docker 에서는 그럴 필요가 없기 때문에 무거운 WAS 을 개별 VM 이나 Image 에 넣는건 의미가 없습니다.

 

또다른 차이로 JNDI 와 같은 WAS 의 변수를 프로그램이 전달받아 사용하는 것도 언급한 것도 있지만, 이 또한 잘못된 사실입니다. Spring Boot 은 초기부터 application properites 을 지원하였는데, 이 properties 에는 Spring Boot Starter 에서 사용하는 고정된 key 도 존재하지만 사용자가 임의로 지정한 key 도 사용 가능합니다. 아마 이 properties 가 보통 src/main/resources/application.properties 에 기본 생성되어 있어서 jar 로 Packaging 될 때 포함이 되어 이를 외부에서 수정할 수 없을꺼라 생각해서 이런 주장이 나온 것 같은데, 분명히 공식 문서에도 나오지만 내부의 properties 파일보다 더 우선되어 읽는 파일들이 있습니다. 실제로 제가 작성했던 application.properties 살펴보기 라는 문서를 읽어보시면 외부에서 읽어올 수 있습니다. (사실 뒤에서 언급하겠지만, 더 큰 비밀이 있습니다)

 

그 외 몇 가지 기능이 더 있지만, 사실 HAProxy 나 nginx 의 reverse proxy 등을 요즘 많이 사용하는데, 이것들을 이용하면 위에서 언급한 Virtual Host 을 포함하여 대부분 대체할 수 있습니다.

 

그런데, 일부 사람들은 이걸 모르면서 Spring 은 대형 프로젝트(프로그램)에, Spring Boot 은 소형 프로젝트에 적합하다고 얘기하는 것 같습니다. 바로, "Spring Boot 역시 외장 WAS 에 배포(Deploy) 할 수 있다" 는 것을 말입니다. 이전 글에서 언급했지만, Spring Boot 은 Spring 을 포함하고 일종의 간편 사용을 위한 Facade 인 형태이기 때문에 성능상 큰 차이가 없습니다. 그래서 WAS 가 외장이냐 내장이냐의 차이로 성능이 많이 차이난다면 그냥 Spring Boot 을 외장 WAS 에 배포할 수 있도록 war 로 Packaging 되도록 Maven/Gradle 에서 약간의 설정만 하면 됩니다. 이 때에도 application properties 정보를 외부에서 읽어올 수 있도록 할 수도 있고 JNDI 도 사용할 수 있기 때문에 Spring Boot 가 불가능한 부분은 없습니다.

심지어 Spring Cloud 프로젝트 중 Spring Cloud Config 이  생기면서 application properites 을 외부의 Config Server 에서 읽어오는 방법도 추가되었습니다. 설정 내용을 File 이나 SVN/GIT 저장소에 저장해두고 각 서버에서 이 정보를 읽어올 수 있게 할 수 있으며, 심지어 프로그램을 재시작하지 않아도 변경된 내용을 적용시키게 할 수도 있습니다. 그렇기 때문에 WAS 에 설정 정보를 입력한 뒤 프로그램에서 이를 읽도록 하는 방식을 굳이 고집할 필요도 없습니다.

반응형
댓글
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함