정윤진 피보탈 랩 프린시플 테크놀로지스트

[컴퓨터월드]

▲ 정윤진 Pivotal Lab Principal Technologist

1. 스프링 부트 <이번호>
2. 스프링 클라우드 Config server
3. 스프링 클라우드 Service discovery
4. 스프링 클라우드 Zuul
5. 스프링 클라우드 Hystrix
6. 스프링 클라우드 Zipkin


한국에도 이제 다양한 클라우드 서비스가 존재한다. 아마존 웹 서비스를 필두로 마이크로소프트 애저, 그리고 아직 데이터센터는 한국에 없지만 구글 클라우드 플랫폼과 같은 대형 클라우드 사업자가 모두 한국에서 사업을 전개해 관련 서비스에 대한 사용이 가능하다. 필요하다면 다양한 장소에서 진행되는 관련 소모임이나, 해당 클라우드 업체에서 제공하는 다양한 행사 및 교육에 참여할 수도 있다. 국내의 많은 기술자 및 기업에서도 높은 관심 역시 함께 증가하는 추세라고 할 수 있다.

이렇게 클라우드에 대한 관심이 높은 데는 많은 이유가 있는데, 첫째는 언제든 필요할 때 컴퓨팅 자원을 할당받아 사용할 수 있다는 점, 그리고 이 자원을 할당받은 만큼 비용을 지불한다는 점이 모든 클라우드 서비스 공급자가 입을 모아 말하는 클라우드 서비스의 장점이라고 할 수 있다. 그리고 대부분 기업에서는 바로 이 클라우드의 장점을 올바로 사용하지 못함으로 인해 비용, 가용성, 업데이트 등 모든 부분에 문제를 겪고 있다. 이런 일이 발생하는 이유는 명확하다. 인프라는 선진화됐는데, 그 위에 동작하는 서비스 소프트웨어(SW)를 개발하고 업데이트하고 운영하는 방법은 1990년대에 사용하던 방법을 동일하게 사용하기 때문이다.

본 기고문에서는 크게 ‘몇 가지’ 기술을 소개하며 이것들이 종전의 어떤 문제를 해결하고 있는지, 그리고 어떻게 사용이 가능한지에 대해 소개하고자 한다. 소개되는 기술들은 대부분 넷플릭스와 같이 클라우드에 최적화된 서비스를 만들어내고 있는 기업이 공개하고 있는 패턴에 기인하며, 자바 스프링을 사용하고 있는 개발자라면 손쉽게 구현해볼 수 있을 것이다.


시작에 앞서

2011년 즈음 처음 발표된 개념인 12팩터(12 Factor)에는 최신 애플리케이션이 가져야 할 12가지 패턴이 소개된다. 페이지의 제일 하위에 보면 한국어로도 제공되므로 한번 읽어보는 것을 권고한다. 여기에 소개되는 내용은 어떤 서비스를 개발하고자 할 때 참조해야 할 가이드라인으로 생각해도 좋다. 전체 내용을 이해하고 나서 현재 현업에서는 어떻게 하고 있는지, 그것이 서로 어떻게 다른지 곰곰이 생각해보는 것도 좋은 접근방법이 될 것이라고 생각한다.

‘릴리즈 잇!(Release it!)’이라는 책이 있다. 마이클 T. 나이가드(Micheal T. Nigard)라는 이가 쓴 책인데, 한국에 번역서도 존재한다. 이 책에서는 서비스의 개발과 운영, 배포 등에 대해 어떤 부분을 고려해야 하는지에 대해 저자의 경험과 함께 다양한 사례가 소개된다. 역시 현재 운용중인 서비스와는 어떻게 다른지 생각해볼 것을 권고한다.

마지막으로는 다양한 회사들의 엔지니어링 블로그의 내용을 특정 토픽을 통한 검색이나 아니면 주기적인 열람을 통해 읽어볼 것을 추천한다. 피보탈이나 넷플릭스 엔지니어링 블로그를 살펴보면 클라우드 서비스에서 특정 기능을 구현할 때 사례에 대해 제법 자세히 소개돼있으며, 이를 사용해볼 수 있는 오픈소스를 함께 공개하기 때문에 이해한 것을 실제로 구현해보는데 큰 도움이 될 것이라 믿는다. 또한 자신의 전문분야가 아닌 다른 부분에서도 문제해결을 위해 어떤 구현방법을 사용했는지에 대한 간접경험에 의한 학습도 수행할 수 있겠다.

전술했듯이 클라우드 서비스를 가장 잘 사용하는 방법은 아래 두 가지 특성을 먼저 이해할 필요가 있다. 이후 기술되는 모든 내용은 아래 두 가지 대한 인식을 기본으로 한다.

▶ 클라우드 환경에서는 리소스의 할당과 제거가 빠르게 이뤄진다.
▶ 할당받은 자원을 효과적으로 사용해야 비용이 최적화된다.


시장은 아직도 1990년대 방법

시장을 선도하는 서비스들은 모두 매우 빠른 개선속도를 갖고 있는 동시에, 매우 안전하게 서비스를 업데이트하고 있다. 은행들이 수행하는 전산업무들이 매우 미션크리티컬하다고 하지만, 결제가 연동되는 서비스는 모두 어느 정도 미션크리티컬한 작업을 수행하고 있다고 할 수 있다. 최근 많은 서비스들에서 제공하는 각종 결제 서비스나, 물건을 주문하고 판매하는 서비스, 또는 스마트팩토리 등으로 인해 그 중요성이 날로 높아지고 있는 센서와 서버 간 통신 같은 것들이 그렇다. 무엇하나 유실돼서는 안 되고, 유입된 요청은 가급적 빠르게 처리가 될 필요가 있다.

서비스를 중요하게 취급할수록 업데이트와는 멀어진다. 이는 서비스가 중단되면 그만큼 회사에 끼치는 손해가 크기 때문이다. 즉, 업데이트는 곧 서비스의 중단이라는 공식으로 연결되며, “만약 업데이트가 실패하면 어떡하지?”라는 공포가 사업부서와 전산팀을 지배한다. 그래서 기능의 반영보다는 기존 서비스의 정상적 동작에 조금 더 무게를 두고 서비스를 운영한다.

이런 상황이 몇 년 반복되다보면 서비스는 업데이트되지 않은 채 유지된다. 수많은 보안 허점, 시대에 뒤떨어진 서비스 품질, 경쟁사에 비해 느린 서비스 개선속도, 이런 것들은 궁극적으로 안전하게 지키려고 했던 서비스가 점점 더 불안정해지는 결과를 초래한다. 게다가 자본과 기술을 앞세운 인터넷 기업들은 다른 시장의 진입영역이 끝이 없다.

전술한 바와 같이 이런 서비스들 역시 서비스가 중지되면 매우 치명적인데, 그들은 어떻게 별 문제 없이 지속적으로 업데이트가 가능한 것일까? 왜 우리 회사의 서비스는 추석 3일 연휴에 업데이트를 하고 있는데, 저들의 서비스는 한 번의 다운타임도 없이 계속 개선될 수 있는 것인가? 왜 우리 서비스에 2주에 한번 돌아오는 서비스 업데이트 공지는 고객의 불만이 없는데, 저런 서비스들은 10분이라도 중지가 발생하면 주가가 춤을 추고 트위터와 각종 사회관계망 서비스에 메시지가 폭발하는가.

이들이 하는 방법은, 업데이트가 곧 서비스 중단이 아니기 때문이다. 지속적인 업데이트를 통해 고객의 요구사항을 반영하고, 보안 취약점을 개선하고, 드라이버를 업데이트하고, 유닉스 서버들을 x86으로 바꿔내는 작업을 하고 있다.

클라우드를 사용하는 것은 많은 장점을 가져다주지만, 전술한 바와 같이 그 사용방법이 1990년대와 같다면 클라우드는 오히려 운영 안정성이 떨어지는 환경이 될 수 있다. 그리고 이런 특징은 어떤 특정 클라우드 서비스를 사용한다고 해결되는 일이 절대 아니다.

자바로 개발된 애플리케이션을 운영하는 환경들을 대표적으로 예를 들어보면, 바로 웹 애플리케이션 서버(WAS)의 존재다. 자바 기반의 웹 애플리케이션이 있다. 이 애플리케이션은 WAR로 패킹됐으며, JBoss와 같은 WAS를 사용 중이다. 데이터베이스(DB)는 거대한 관계형 데이터베이스(RDB) 하나만을 사용하고 있다. 애플리케이션은 수백만 줄로 구성된 다양한 기능을 포함한 상태로 동작 중이고, 이 애플리케이션에 필요한 대부분의 데이터들은 클러스터링된 하나의 DB 안에 존재한다. 따라서 DB는 서비스 품질을 위해 필연적으로 매우 복잡한 다양한 애플리케이션들로부터 유입되는 질의를 처리하기 위해 매우 고성능의, 그리고 고기능의 제품을 필요로 한다.

설명된 환경에서 애플리케이션을 업데이트하려면 어떤 과정이 필요한가? 먼저 수백만 줄로 돼있는 애플리케이션 코드에서 필요한 부분을 업데이트해야 한다. 여기부터 매우 힘든 고난의 연속이다. 서로 다른 기능을 책임지고 있는 팀들 간의 미팅과 같은 부분은 무시하더라도, 일단 이 덩어리진 코드를 로컬로 가져와서 내게 필요한 부분만을 변경하고, 빌드하고, 테스트하는 환경을 구축하는데 엄청난 시간이 소요된다.

우여곡절 끝에 코드를 업데이트 했다면, 이제 WAR로 패킹한다. 패킹이 완료된 .WAR 파일을 배포팀이나 운영팀에 전달한다. 거대한 WAR 파일을 전달받은 배포 및 운영팀은 이제 동작중인 WAS들에 신규로 업데이트된 파일을 전송한다. 물론 서비스가 잘못된 경우 기존 파일로 다시 복구해야 하므로 기존 .WAR 파일들은 시스템 어딘가에 알아볼 수 있게 보관한다.

수십 대의 서버에 FTP를 통해 파일을 업로드하고, 업데이트 시간이 되기를 기다린다. 업데이트를 하는 시간이 되면 먼저 처음 업데이트를 수행할 서버에서 WAS를 종료한다. 신규로 업로드된 .WAR 파일을 WAS가 참조하는 경로에 배치하고, WAS를 다시 시작한다. 두근두근 긴장의 연속이다. 별 문제 없이 업데이트가 완료됐다면, 다음 서버에서 업데이트를 진행한다.

그런 식으로 한 대씩 다 처리하고 나면 아침이 환하게 밝아온다. 그런데 갑자기 개발팀에서 전화가 온다. “기능이 하나 빠져서 다시 배포해야 해요!” 만약 해당 업데이트에 데이터베이스 스키마 업데이트가 추가돼야 한다면 어떨까. 이런 업데이트를 처리해야 하는 서비스가 10개 이상 되는 운영팀이라면 어떤 일이 발생할까.

5년 전에 개발된 코드를 운영하는 시스템이 있다. 업체와의 계약 만료로 인해, 그리고 해당 서비스는 그다지 많은 고객이 유입되고 있지 않으므로 5년 동안 별 문제 없이 그대로 동작해왔다. 하지만 이번에 전사적으로 클라우드 마이그레이션을 처리해야 한다. 이 시스템은 5년이 됐으므로 대상이 된다. 업데이트를 하려고 보니, 운영체제(OS)는 윈도우NT 4.0, WAS는 JBoss 3.x, 이 위에서 WAR 파일이 동작하고 있다.

5년 전 기준에도 그 이전의 시스템을 사용해 개발된 애플리케이션은 그 환경에서가 아니면 동작하지 않는다. 하지만 코드의 변경 없이는 시스템을 업그레이드할 수 없다. NT 4.0은 어떠한 클라우드 서비스 공급자도 제공하지 않는다. 클라우드로의 마이그레이션 계획은 무산되거나, 다시 거대한 마이그레이션 프로젝트가 시작된다.

한대의 서버에서 하나의 애플리케이션을 구동하던 시절에는 아마도 효율적이었을지도 모르겠다. 하지만 지금은 하나의 물리적 서버에 굉장히 많은 애플리케이션을 구동하는 클라우드의 시대다. 그런데 운영과 개발팀들은 한 번에 하나만의 애플리케이션을 구동할 수 있는 WAS에 거대한 애플리케이션을 그대로 패킹하고, 이 구성을 그대로 도커(Docker) 이미지화하는 작업을 하고 있다.

이것은 매우 비효율적이고, 도커 이미지를 사용하는 매우 잘못된 방법이라고 할 수 있다. WAS를 구동하기 위해 필요한 시스템 라이브러리가 많아지고, 그 자체로 거대해진다. 이미지의 크기가 크면 클수록 다음번 업데이트를 위한 빌드나 새로운 시스템에서의 컨테이너 기동 등에 다양한 비효율이 발생한다.

그렇다면 어떤 것이 옳은 방법일까? 특정 버전의 애플리케이션은 그 구동에 필요한 모든 라이브러리와 의존성을 포함하는 형태로 존재하되, 컨테이너 기반 환경에서 사용될 수 있을 만큼 충분히 가벼운 것이 좋을 것이다. 예전에는 시스템 호환성을 위해 컴파일을 수행할 때 필요한 라이브러리들을 shared로 추가했다면, 이제 해당 애플리케이션을 구동하기 위해 필요한 라이브러리들을 모두 static하게 추가하는 형태로 발전해가고 있는 것이다.

이것은 비단 바이너리뿐만 아니라 이것이 구동되는데 필요한 대부분의 것이 포함될수록 유리하다. 피보탈의 스프링팀은 스프링 프레임워크에 이러한 개념을 도입하고자 했는데, 바로 Fat JAR의 사용이다. ‘Make JAR not WAR’ 캠페인을 하고 있는 피보탈의 스프링 팀은, 스프링 부트라고 불리는 도구를 개발해 스프링 개발자들에게 제공하고 있다.

이 스프링 부트가 갖는 장점은 몇 가지가 있는데, 그중에서도 큰 특징 중 하나는 프로젝트 빌드에 필요하다면 톰캣(Tomcat), 언더토우(Undertow), 제티(Jetty)와 같은 WAS를 ‘임베드’하고 그 외에 필요한 스프링 의존성이 모두 함께 JAR로 패킹된다는 것이다. WAR와의 차이점은, 이 JAR 파일 하나만 있다면 JVM 머신이 설치된 어디에서나 동일하게 동작하는 애플리케이션을 가질 수 있다는 것이다.

이것은 가볍고, 따라서 JVM만 설치돼있는 컨테이너라면 손쉽게 추가돼 이미지의 빌드 속도, 컨테이너가 기동되는 속도 등을 가속할 수 있다. 또한 java -jar 커맨드만 있다면 구동할 수 있으므로, WAS에 대한 전문가가 아니더라도 누구나 동일하게 애플리케이션을 구동할 수 있다. 종전의 업데이트와 같은 과정에서 생각해 보면, WAS의 존재로 인해 발생하는 의존성 문제, 서버 하나에서 하나의 애플리케이션만을 구동할 수 있었던 문제들이 상당히 해결된다.

이것이 2010년대 후반에 시장을 선도하는 회사들이 사용하는 클라우드 기반 애플리케이션을 개발하고 빌드하고 배포하는 방법이다. 물론 이 한가지뿐만 아니라 매우 다양하고 많은 기술들이 필요하지만, 아마 가장 공감대가 높은 부분이 아닐까 싶다. 애플리케이션이 자주 업데이트되지 못하는 것은 비단 워터폴 개발방식뿐만 아니라, 그 애플리케이션이 만들어지고 배포되고 동작하는 방법이 매우 구식이기 때문인 부분이 더 크다.

피보탈의 스프링팀은 많은 개발자들이 이미 현업에서 사용하고 있지만 XML 설정 및 관리와 같은 복잡성으로 인해 문제가 됐던 부분을 개선한 스프링 부트 프로젝트를 수년전에 시작했다. 스프링 부트 사용의 장점은 아래와 같다.

▶ 단일 스프링 애플리케이션 제작
▶ 톰캣, 제티, 언더토우와 같은 WAS가 임베드돼 WAR로 애플리케이션을 배포할 필요가 없어짐. 즉, JAR로 빌드해 java -jar 커맨드로 간단히 실행 가능
▶ Maven 통한 설정 간소화를 위해 ‘starter’ POM 제공, 원하는 스프링 프레임워크의 도구를 쉽게 추가 및 제거 가능
▶ 가능한 경우 자동 설정을 사용
▶ 다양한 단계의 내·외부 설정 참조 및 애플리케이션 관련 다양한 메트릭스, 헬스 체크 등 제공
▶ XML 설정 필요 없음

스프링 클라우드에서 제공하는 Archaius 같은 클라우드 기반 애플리케이션 연동을 돕기 위한 도구들은 스프링 부트 프로젝트를 시작하는 것과 동일한 방법으로 사용이 가능하다. 스프링 부트 프로젝트들은 ‘스프링 이니셜라이저’라고 불리는 웹페이지(링크)에서 시작할 수 있다. 이 스프링 이니셜라이저는 프레임워크에 대한 일원화가 필요한 기업 및 조직의 내부적 사용을 위해 독립적으로 준비해 사용하는 것이 가능하다. 이 경우, 각 조직에서 공통적으로 필요한 모듈 등에 대해 커스텀화하고, 이를 사용하는 모든 조직에서 동일한 모듈의 사용과 업데이트를 일원화할 수 있기도 하다. 이를 위한 스프링 이니셜라이저 프로젝트는 해당 깃허브(링크)에서 찾을 수 있다.

스프링 이니셜라이저 웹사이트에서는 [그림1]과 같은 페이지를 확인할 수 있다.

▲ [그림1]

스프링 이니셜라이저의 화면은 매우 간단하게 구성됐는데, 각각 다음과 같은 기능을 한다.

▶ Maven, Gradle 및 스프링 부트의 버전을 선택할 수 있다.
▶ Artifact 그룹 및 이름을 지정한다.
▶ 스프링 부트 스타터로 불리는 ‘사전에 이미 구현된’ 도구들을 추가할 수 있다. 예를 들면 H2, JPA, Actuator, Zipkin, Zookeeper 등 이미 스프링 팀에서 구현한 스타터 패키지의 의존성이 자동 검색 및 추가된다.
▶ Generate Project를 클릭하면 위에서 지정한 내용을 바탕으로 기본 프로젝트 구조가 담긴 .zip 파일이 다운로드된다.

이 도구에서 지정을 원하는 더 많은 기능 또는 옵션을 보고 싶다면 하단에 있는 ‘Switch to the full version’ 링크를 클릭하면 된다. 세부 옵션에서는 자바의 버전, Groovy 또는 Kotlin 사용 여부, 그리고 다양한 스타터 패키지에 대한 체크박스를 제공한다. 당연한 말이지만, 새로운 프로젝트를 시작할 때 자바 1.8 이하 버전을 사용하는 것은 매우 강력하게 권고하지 않는다.

조금 더 시간을 내어 dependancies 부분을 살펴보는 것을 권고한다. 여기에는 거의 대부분의 스프링 프로젝트가 포함돼있으며, 이 프로젝트들을 별 어려움 없이 가져다 사용하는 것이 가능하다. AWS JDBC, Kafka stream 등 매우 다양한 도구를 확인할 수 있을 것이다.

스프링 부트를 사용해 MVC 애플리케이션을 만드는 것은 이전과 다르게 매우 손쉽다. 손쉬울 뿐만 아니라 버전 관리 및 DB 연동의 방법도 매우 간단하다. 스프링 부트를 통해 MVC 프로젝트를 수행해보고 싶은 이들은 구글에서 spring boot mvc를 검색하거나, 여기(링크)를 참조하면 된다.

자바와 스프링을 사용할 수 있는 이들이라면 스프링 부트의 간결함과 편리함에 금방 매료될 것이다. 스프링 부트는 원하는 애플리케이션을 프로덕션 수준의 다양한 도구들과 함께 즉시 사용 가능하도록 돕는다. 상기해야 할 것은, 우리는 지금 클라우드에 최적화된 서비스에 대해 이야기하고 있다는 것이다.

스프링 클라우드는 스프링 부트가 제공하는 손쉬운 방법을 통해 위에서 설명한 넷플릭스의 Archaius 같은 도구를 손쉽게 사용할 수 있도록 돕는다. 스프링 클라우드 Config server가 바로 그것이며, 이와 연동을 원하는 클라이언트들의 경우엔 Config client를 스프링 이니셜라이저의 의존성 부분에서 추가해 Config server와 바로 연동할 수 있다.

Maven 또는 Gradle 프로젝트를 빌드할 수 있는 환경을 갖추고 있다면 지금 바로 수행할 수 있다. 스프링 클라우드 Config server 는 여기(링크)를 살펴보면 된다. 링크에 소개된 동작은 크게 다음과 같은 단계로 구분된다. 링크에 소개된 내용이 부담스러운 이들은 아래 설명을 참고하면 된다.

▶ http://start.spring.io 에 접근
▶ Artifact Group과 Artifact 이름을 설정한다. Artifact 이름에는 config-server 정도가 적당하겠다.
▶ Dependencies에는 Config Server, Actuator 정도만 추가하자.
▶ Generate Project를 클릭하면 [artifact-name].zip 이름으로 프로젝트가 다운로드된다.
▶ 다운로드된 파일의 압축을 해제하고 이클립스 또는 STS, 인텔리J 등 원하는 IDE나 에디터를 사용해 프로젝트를 시작한다.

Maven을 사용한 경우 해당 디렉토리로 이동해 디렉토리 구조를 살펴보면 [그림2]와 같다.

▲ [그림2]

프로젝트의 설정에 필요한 의존성은 pom.xml 파일에 명시된다. 스프링 부트 애플리케이션의 설정은 src/resources/application.properties 또는 src/resources/application.yml 에서 지정할 수 있다. Maven 프로젝트를 빌드 할 수 있는 환경이 이미 준비돼있다면 다음과 같은 커맨드를 통해 별 문제 없이 프로젝트를 빌드할 수 있다.
 

$ mvn clean package


. ____ _ __ _ _
/ / ___'_ __ _ _(_)_ __ __ _
( ( )___ | '_ | '_| | '_ / _` |
/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |___, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v1.5.2.RELEASE)

2017-04-13 15:58:56.028 INFO 69208 --- [ main] c.example.ConfigServerApplicationTests : No active profile set, falling back to default profiles: default



[INFO] ----------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ----------------------------------------------------------------------
[INFO] Total time: 29.386 s
[INFO] Finished at: 2017-04-13T15:58:59+09:00
[INFO] Final Memory: 32M/169M
[INFO] ----------------------------------------------------------------------


위와 같은 메시지를 봤다면 아무런 문제없이 빌드가 완료된 것이다. 빌드가 완료된 스프링 부트 애플리케이션은 아래와 같은 방법으로 구동 가능하다.
 

$ java -jar target/config-server-0.0.1-SNAPSHOT.jar


2017-04-13 16:01:45.690 INFO 69393 --- [ main] o.s.c.support.DefaultLifecycleProcessor : Starting beans in phase 0
2017-04-13 16:01:45.772 INFO 69393 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http)
2017-04-13 16:01:45.776 INFO 69393 --- [ main] com.example.ConfigServerApplication : Started ConfigServerApplication in 2.85 seconds (JVM running for 3.197)


출력되는 로그 메시지를 보면 8080 포트에 http 서비스가 임베드된 톰캣을 통해 구동중임을 알 수 있다. 그럼 브라우저를 열고 http://localhost:8080 으로 접근해보도록 하자. 아마 Whitelabel Error 메시지를 확인할 수 있을 것이다. / 경로로 접근하면 No messages 에러가 발생하지만, /metrics 나 /env 같이 Actuator가 제공하는 엔드포인트로 접근하면 Full authentication is required to access this resource 라는 메세지가 나타나는 것을 확인할 수 있다. 이는 최신 스프링 부트에서는 Actuator가 제공하는 각종 애플리케이션 및 시스템 정보를 보호하기 위해 기본적으로 Security가 활성화돼있기 때문이다.

아직 아무것도 없는 애플리케이션이지만, 일단 아무 문제없이 빌드됐으며, 별도 WAS 설정 없이 java -jar 커맨드를 통해 빌드된 애플리케이션을 실행할 수 있다. Config server를 기동하기 전에, 먼저 java -jar로 시작했던 애플리케이션의 기본 Security를 제거해 Actuator의 엔드포인트를 활성화 하는 방법과, 8080으로 지정된 포트 설정을 변경하는 방법을 살펴보자.

스프링 부트 애플리케이션에서는 별도 설정이 없는 내용에 대해서는 기본으로 적용되는 설정이 있다. 이에 대한 내용은 Actuator가 활성화돼있는 경우에는 http://localhost:8080/configprops의 엔드포인트를 통해 확인할 수 있다. 기본 상태에서는 management.security.enabled의 값이 true로 적용돼있기 때문에 Actuator 엔드포인트에 대한 권한을 요구하지만, 이를 해제해보도록 하겠다.

이전에 빌드한 스프링 부트 애플리케이션이 지금 구동되고 있다면 Ctrl-c 이용해 중지하도록 하자. 그리고 아래 커맨드를 사용해 애플리케이션을 실행한다.
 

$ mvn spring-boot:run -Dmanagement.security.enabled=false


2017-04-13 16:31:07.604 INFO 71544 --- [ main] o.s.c.support.DefaultLifecycleProcessor : Starting beans in phase 0
2017-04-13 16:31:07.675 INFO 71544 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http)
2017-04-13 16:31:07.678 INFO 71544 --- [ main] com.example.ConfigServerApplication : Started ConfigServerApplication in 2.691 seconds (JVM running for 4.625)


위와 같이 메시지가 확인된다면 이제 이전에는 접근되지 않았던 http://localhost:8080/configprops 주소로 curl이나 브라우저를 통해 접근해보자. 그럼 [그림3]과 같은 JSON 응답을 확인할 수 있다.

▲ [그림3]

위 JSON 응답은 Actuator가 기본 제공하는 스프링 부트 애플리케이션 설정에 대한 정보를 나타내는 페이지다. 여러분은 http://localhost:8080/metrics 및 http://localhost:8080/env 엔드포인트 접근을 통해 애플리케이션 구동에 필요한 세부정보를 참조해 볼 수 있다. Actuator가 제공하는 정보에 대해서는 Spring Boot actuator를 검색해보거나 여기(링크)를 참조해 보면 된다.

몇 가지 엔드포인트에 대해 확인했다면, 다시 기동된 애플리케이션을 Ctrl-c 사용해 중지하고 아래 커맨드를 사용해 동일한 애플리케이션을 시작해보도록 하자. 아래 커맨드는 OSX나 리눅스에서 동작하므로, 윈도우를 사용하는 경우에는 SERVER_PORT에 대한 환경 변수를 set 같은 커맨드를 사용해 등록할 필요가 있겠다.
 

$ SERVER_PORT=8888 mvn spring-boot:run -Dmanagement.security.enabled=false


2017-04-13 16:48:40.667 INFO 72685 --- [ main] o.s.c.support.DefaultLifecycleProcessor : Starting beans in phase 0
2017-04-13 16:48:40.741 INFO 72685 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8888 (http)
2017-04-13 16:48:40.744 INFO 72685 --- [ main] com.example.ConfigServerApplication : Started ConfigServerApplication in 2.658 seconds (JVM running for 4.611)


로그를 살펴보면 8888 포트로 애플리케이션 기동이 완료된 것을 확인할 수 있다. 이는 아래 커맨드를 통해서도 동일한 효과를 볼 수 있다.
 

$ SERVER_PORT=8888 java -jar target/config-server-0.0.1-SNAPSHOT.jar


여기까지 설명에서 다음 몇 가지 내용에 주목할 필요가 있다. 첫째로 스프링 부트 애플리케이션은 스프링 이니셜라이저를 통해 매우 손쉽게 프로젝트를 생성하고, 빌드할 수 있는 기본 환경을 제공한다. 이것은 마치 비주얼스튜디오(Visual Studio)에서 MFC 애플리케이션의 기본 골격을 만들어주는 것과 매우 유사한 편의성을 제공한다고 이해하면 되겠다.

두 번째로, 스프링 부트 애플리케이션은 java -jar 통해 손쉽게 구동할 수 있다. 이는 별도 시스템 설정이나 WAS 같은 구조에 종속적이지 않음을 의미한다. 도커를 사랑하는 이들이라면 현재 도커를 통해 수행하고 있는 작업을 생각해보자. 도커에 WAS 프로세스가 구동될 수 있는 환경을 준비하고, 거기에 WAR로 빌드된 파일을 추가해 도커 이미지를 구성한다.

스프링 부트 애플리케이션에서는 이와 동일한 구성을 별도 컨테이너 설정이 없더라도 JAR로 빌드하면 WAS가 임베드돼 동작한다. JVM이 설치된 머신이라면 어디서든 동작 가능하다. 이것이 바로 컨테이너의 장점 아닌가. 아울러, JAR를 사용해 도커 이미지를 만드는 것은 더 작은 크기로, 더 효율적으로 만들 수 있다. JAR를 구동할 수 있는 적절한 버전의 JVM만 준비됐다면 빌드된 JAR를 실행할 모든 준비가 사실 끝난 것과 마찬가지기 때문이다. 따라서 WAS와 같이 무거운 애플리케이션을 거대한 도커 이미지에 빌드해 더 많은 메모리를 소비하는 구조로 만들 필요가 없다는 것이다.

세 번째로, 스프링 부트 애플리케이션은 시스템 환경 변수, application properties 등 다양한 방법을 통해 설정을 참조할 수 있다는 점이다. 뒤에 설명될 Config server를 사용하지 않더라도, 애플리케이션이 구동될 컨테이너나 시스템에 환경변수, 파일, 커맨드라인 파라미터 등 아주 다양한 방법을 통해 애플리케이션이 사용할 설정을 적용할 수 있다. 스프링 부트 애플리케이션의 외부 설정 참조의 순서는 여기(링크)를 참조하거나, 구글 등 검색엔진에서 “spring boot externalized configuration” 같은 검색어를 통해 참조 가능하다.

한번 빌드된 애플리케이션에 설정 변경이 필요한 경우, 새로운 빌드를 거치지 않고 환경 변수와 같은 방법을 사용해서 다른 설정으로 시작할 수 있다는 점은 매우 중요하다. 위 세 가지 내용들은 클라우드와 같이 리소스의 할당이 빠르고 자유로운 환경에서 더욱 더 유연해질 수 있다.

스프링 부트는 클라우드 기반에서 동작 가능한 최소 단위의 애플리케이션을 매우 빠르게, 그리고 항상 동일한 방법으로 개발할 수 있는 환경을 제공한다. 비단 작은 애플리케이션뿐만 아니라, 기존 MVC 구조의 거대한 애플리케이션 역시 개발 가능하다. 스프링 부트 사용의 장점은 먼저 다양한 데이터 저장소 및 클라우드 서비스들과 연동 가능한 도구들을 starter-tools로 기본 제공하고 있다는 점이다.

그 외에도 스프링 시큐리티, 스프링 배치, 스프링 데이터 등 스프링 프로젝트에 있는 다양한 도구들을 위에서 설명한 매우 편리한 방법으로 프로젝트에 추가하고, 의존성을 관리하고, 버전 변화에 따른 복잡성을 제거한 상태로 사용 가능하기 때문에, 기존 스프링 프레임워크를 직접 사용하던 방법보다 매우 효율적으로 애플리케이션을 준비할 수 있다. 실제로 스프링 부트를 사용해 카프카(Kafka)와 같은 스트림 도구와 연동 및 메세지를 주고받는 애플리케이션을 프로덕션 수준으로 만드는데 3일이 걸렸다는 대형 포털 서비스도 있다.

자바를 사용해 애플리케이션을 개발하는 경우, 스프링 부트는 반드시 살펴봐야 할 도구다. 그리고 마이크로서비스 또는 클라우드 기반 애플리케이션을 구현하고 있다면 스프링 부트와 함께 스프링 클라우드도 살펴보는 것이 좋다. 1990년대에 사용하던 방법 대신, 2010년도에 사용되는 기술과 그로 인한 장점을 경험할 수 있을 것이다.

다음번에는 스프링 부트의 장점을 바탕으로 스프링 클라우드를 사용해 마이크로서비스를 구현하는데 필수적인 요소 중 스프링 부트 Config server에 대해 살펴볼 것이다.

저작권자 © 아이티데일리 무단전재 및 재배포 금지