티스토리 뷰
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 에 설정 정보를 입력한 뒤 프로그램에서 이를 읽도록 하는 방식을 굳이 고집할 필요도 없습니다.
'Programming > Java' 카테고리의 다른 글
Spring에서 OS Proxy 설정을 적용해 RestClinet(RestTemplate 포함)로 REST API 호출하기 (0) | 2024.01.15 |
---|---|
Spring Boot 을 언제 써야 할까? (2) 외장 WAS 가 반드시 필요한가? (5) | 2019.09.19 |
Spring Boot 을 언제 써야 할까? (1) Spring Boot 는 어떤 구조일까? (0) | 2019.09.18 |
Spring Boot 을 언제 써야 할까? (0) 프롤로그 (0) | 2019.09.18 |
MSA 구성을 위한 기술 (0) | 2019.09.10 |
- Total
- Today
- Yesterday
- 외장 WAS
- manjaro
- 워드프레스
- Phabricator
- NoSQL
- KDE
- 시니어 프로그래머
- 프로젝트 규모
- RestTemplate
- java config
- boot
- proxmox
- jooq
- 클라우드플레어
- docker
- 도입기
- SI
- 내장 WAS
- OracleJDK
- git
- couchbase
- Spring
- paging
- Spring Boot
- Spring MVC
- 페이징
- messages.properties
- Redmine
- Nas
- 엘지
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |