2020. 6. 19. 22:08ㆍTIL/웹
우연히 빌드와 배포에 관련된 발표를 하는 영상을 보았는데, 내용이 참 좋았다.
평소에 궁금하기도 하고 자주 헷갈리는 부분이었기 때문에 간단하게나마
따로 정리해보게 되었다. 하지만 빌드와 배포 과정을 정리한 것은 아니고 개념위주이다...
자세한 과정은 프로젝트 내용을 정리할때 포함시켜야겠다.
(썸네일이 jenkins 와 gcp인 이유는 빌드와 배포라는 주제에 적합한 이미지인 것 같아서이다...)
1. 빌드란?
사실 Maven이라는 빌드툴에 대해 정리하면서 컴파일과 빌드에 대해서는 정리한 적이 있다.
하지만 maven글에 어중간하게 껴있는 느낌이어서 이곳에 다시 간단하게나마 정리해두려고 한다.
컴파일 : 작성한 소스 코드를 바이너리 코드로 변환하는 과정
즉, 소스코드를 컴퓨터가 이해할 수 있는 기계어로 변환해주는 것을 의미하며, 이런 이을 해주는 것을 컴파일러라고 부른다.
빌드: 소스 코드를 실행 가능한 소프트웨어 산출물로 만드는 일련의 과정
산출물로는 jar, war파일 등이 있다.
링크: 여러 개로 분리된 소스 코드들을 컴파일한 결과물들에서 최종 실행 가능한 파일을 만들기 위해 필요한 부분을 찾아서 연결해주는 작업을 의미한다. 직접 만들었던 자바 웹 애플리케이션 중 Lotto로 예를 들어 보자. Lotto라는 클래스가 있고 List <Lotto>를 멤버 변수로 갖는 LottoRepository클래스가 있다. 이 서로 다른 두 소스코드는 각각 컴파일이 될 텐데, 이때 LottoRepository클래스는 Lotto클래스를 참조해야 한다. 이때 바이너리 코드만으로는 참조할 클래스를 이해하지 못하므로, 연결해주는 작업이 필요한데 이것이 바로 링크라는 개념이다. 결론적으로 링크는 이미 컴파일된 파일을 가지고 실행 가능한 파일을 위해 서로 필요한 부분들을 연결해 주는 작업이다.
위의 세 개념을 보았을 때 빌드가 실행 가능한 소프트웨어 산출물을 내는 일련의 과정이므로 컴파일과 링크를 포함한 과정임을 짐작해 볼 수 있다.
2. 빌드도구
빌드도구는 말 그대로 빌드를 도와주는 프로그램이다.
소스코드를 컴파일, 테스트, 정적 분석 등을 거쳐 실행 가능한 애플리케이션으로 자동 생성해주는 역할을 한다.
또한, 계속해서 늘어나는 라이브러리의 자동 추가 및 관리를 해주고 해당 라이브러리의 버전을 자동으로 동기화해준다.
설명해 주시는 분께서 '자동'이라는 key point를 잡아 주셔서 쉽게 이해할 수 있었다.
대표적인 빌드 도구로는 개발을 한다면 한 번쯤 들어봤을 ANT, Maven, Gradle이 있다.
각각의 특징은 다음과 같다.
ANT
- XML 기반 빌드 스크립트를 개발
- 규칙이 없다.
- 절차적이다. (명확한 빌드 절차 정의가 필요하다.)
- 생명주기를 갖지 않아 각각의 Target에 대한 의존관계와 작업을 정의해 주어야 한다.
Maven
- 프로젝트에 필요한 모든 종속성(Dependency)을 리스트 형태로 Maven에게 알려주어 종속성을 관리한다.
- XML, Repository를 가져올 수 있다.
- Pom.xml이라는 Maven 파일에, 필요한 Jar, Class Path를 선언만 하면 직접 다운로드할 필요 없이 Repository에서 자동으로 필요한 라이브러리 파일을 불러와준다.
- 라이브러리가 서로 종속할 경우 XML이 복잡해진다.
- 계층적인 데이터를 표현하기에는 좋지만, 플로우나 조건부 상황을 표현하기 어렵다.
- 편리하나 맞춤화된 로직 실행이 어렵다.
Gradle
- JVM 기반의 빌드 도구
- Ant와 Maven의 단점을 보완한 빌드 도구이다.
- 오픈소스 기반의 빌드 자동화 도구이다.
- Groovy 기반 DSL로 작성한다.
- Build-by-convention을 바탕으로 한다. -> 스크립트 규모가 작고 읽기 쉽다.
- 설정 주입 방식
나는 CRUD게시판 만들기 연습을 하면서 Maven도 써보고 Gradle도 써보았지만 개인적으로는 Maven이 더 손에 잘 감겼다. 하지만, 기능 자체가 적고 복잡하지 않아서 Maven의 단점을 잘 느끼지 못했기 때문인 것 같다. 더 큰 규모의 프로젝트를 하며 Gradle의 장점을 몸소 느껴보고 싶다는 생각도 들었다.
3. 배포란?
작성한 코드를 빌드하고, 빌드가 완성된 실행 가능한 파일을 사용자가 접근할 수 있는 환경에 배치하면 배포가 완료되었다고 볼 수 있다. 이때 실행 가능한 파일은 아까 예로 들었던 jar파일이나 war파일 등이다. 해당 영상에서는 deploy의 어원과 함께 설명해 주어서 너무 좋았다. deploy는 군대에서 병사들을 일정한 위치에 배치하는 상황에서 발생된 단어라고 한다. 파일을 병사라고 생각한다면 사용자들이 접근할 수 있는 환경에 파일들을 배치하는 것이 배포라고 할 수 있는 것이다.
간단하게 생각하면 결국 jar파일 또는 war파일을 WAS에 올리는 것이 배포인 것이다.
배포의 과정을 좀 더 상세하게 보면 git(소스 형상 관리)에 프로덕션 코드를 올려두고, 코드가 제대로 동작하는지 테스트 코드를 작성하고, 이를 수행 및 검증하는 작업까지를 포함한다. 이 부분에서 생각해보자면, 변경사항이 있을 때마다 깃에 올리고, 테스트하고, 빌드하고, 수행 및 검증하고... 배포란 참 복잡해 보인다. 이러한 과정들을 위해 존재하는 것이 빌드 자동화 또는 배포 자동화 등이다.
4. CI/CD ?
먼저, CI는 Continuous Integration 즉, 지속적 통합이라는 뜻이다.
이것은 모든 개발이 끝난 이후에 코드 품질을 관리하는 고전적 방식의 단점을 해소하기 위해 나타난 자동화 프로세스 개념이라고 한다.
CI의 프로세스를 살펴보면 아래와 같다.
1. 코드를 통합한다. -> 깃에 코드를 통합한다.
2. 통합한 코드가 제대로 동작하는지 테스트한다.
3. 제대로 빌드가 되는지 테스트한다.
4. 결과를 정리하고 버그가 존재한다면 기록한다.
이러한 CI과정들을 변경사항들이 있을 때마다 직접 계속해야 한다면 여간 귀찮은 일이 아닐 것이다. 이러한 문제를 해결해주기 위해 많은 자동화 도구들이 나왔는데, 대표적으로 Jenkins가 있다. 스프링 부트 프로젝트를 진행하며 Jenkins를 사용해 보았는데 CI 기능 이외에도 많은 기능을 제공해주는 것 같다.
CD는 Continuous Deploy 즉, 지속적 배포를 의미한다.
이것은 소프트웨어가 항상 신뢰 가능한 수준에서 배포될 수 있도록 관리하자는 개념이라고 한다. 여기서 신뢰 가능한 수준이라면 테스트도 모두 통과하고, 빌드도 잘 되는 등의 상태를 의미한다.
5. 무중단 배포
기존에 동작하고 있는 서버가 존재한다고 해보자. 이것은 배포가 완료된 상태인 것이다. 만약 이 상태에서 새롭게 업데이트한 코드를 배포한다면 기존의 서버를 중지하지 않았기 때문에 충돌이 발생한다. 이렇나 충돌을 막기 위해서는 배포되어있던 서버를 중지하고 코드를 업데이트한 후 재배포 과정을 거쳐야 한다. 만약, 구글이 이러한 과정으로 배포가 이루어진다면 서버가 중단되었다가 다시 실행되는 term동안 전 세계인이 구글 서버를 사용하지 못하게 되는 것이다. 하지만 구글 서버가 죽어있는 상태를 본 사람이 있을까? (가끔 있다고는 하지만... 그 원인은 이러한 방식으로 재배포하기 때문이 아니다!)
이러한 이유로 지속적인 서비스가 필요한 환경에서는 무중단 배포를 고려할 수밖에 없다.
원리는 생각보다 간단했다...
두 대 이상의 서버를 서비스하는 것이다.
이미 서비스 중인 서버와 새롭게 배포한 서버가 동시에 존재하면 되는 것이다. 이렇게 하면 새로 업데이트된 서버를 올리면 기존의 서버를 죽이고 코드를 업데이트할 필요가 없어지는 것이다.
무중단 배포 방식으로는 Rolling배포, Canary배포, Blue/Green 배포가 있다고 한다. (자세한 내용은 다음에 따로 정리해야겠다...)
개인적으로 CI/CD개념과 무중단 배포는 어렴풋하게만 알고 있었는데 해당 영상을 보며 많은 것을 새로 이해할 수 있어서 좋았다. 간단한 게시판을 만들어 젠킨스를 사용하여 배포해보고 있는데 막히는 부분이 많아서 잠시 미뤄둔 상태이다... 이 강의를 보고 나니 그 작업을 꼭 제대로 끝 맞춰 보고 싶다는 생각이 들었다.
'TIL > 웹' 카테고리의 다른 글
[웹] REST (0) | 2020.05.18 |
---|---|
[웹] MVC 패턴 (0) | 2020.05.18 |
[빌드툴] Maven (0) | 2020.05.13 |
[서버] 웹서버와 WAS (3) | 2020.05.07 |
[서버] 서버개발의 의미 (3) | 2020.04.27 |