빌드와 배포

빌드와 배포

작년 8월11일 기술발표[테크톡]때 진행한 내용을 바탕으로 재구성한 포스팅입니다.:):)

이번 테크톡에서 알아볼 주제는 "빌드와 배포"입니다.

일단 목차부터 말씀드리겠습니다.

  1. 빌드란?
    2.빌드도구

2.빌드도구(in Java)

2-1)Maven
2-2)Gradle
2-3)Maven vs Gradle
2-4)그래서 결론은...

3.배포란?
4.CI/CD에 대하여
5.무중단 배포


본론에 들어가기에 앞서 이번 발표 주제를 선정한 계기를 말씀드리겠습니다. 제가 지금까지 군복무중에 프로젝트를 진행하면서, 항상 머릿속에서 지워지지 않고 계속 저에게 있어 의문형으로 잔존해있던 질문들이 몇가지가 있는데요. 바로!!

jar? war? 이게 대체 뭐에 쓰는 거지?

로컬서버에서 작업을 하고 운영서버로 넘기려고 했더니 포털이 왜 굳이 2개씩 있지? 그냥 한개만 있으면 안되나?

.jsp 같은 경우에는 xftp로 그냥 운영서버에 덮어쓰기하면 반영이 되는데, 왜 .class 파일은 overwrite 해줘도 왜 바로 반영이 안되는 걸까?

왜 항상 WEB-INF라는 곳에 .java파일들이 있고, 왜 항상 Webapp이라는 곳에 정적자원(html,img)들이 있는 걸까?

만약 저와 같은 질문들을 한번쯤 해보셨고, 아직도 이에 대해 의문이 남아있으시다면, 이번 강의가 이런 질문들을 해소시켜주는 영양가 있는 강의가 될거라 생각됩니다!


1.빌드란?

빌드에 앞서 컴파일과 링크에 대해 말씀드리겠습니다. 1)컴파일: 작성한 소스코드를 바이너리 코드로 변환하는 과정 2)링크: 여러개로 분리된 소스코드들을 컴파일한 결과물들에서 최종실행가능한 파일을 만들기 위해 필요한 부분을 찾아서 연결해주는 일련의 작업 그리고 빌드라는, "소스코드를 실행 가능한 소프트웨어 산출물(jar라던가 war같은거)"을 만드는 일련의 과정"을 말합니다.

2.빌드도구

하지만 이런 빌드를 사람이 일일이 자동화 할 순 없어서 만들어 진 게 빌드도구(tool)입니다!

- 소스코드를 컴파일, 테스트, 정적분석 등을 실시하여 실행가능한 애플리케이션으로 자동 생성하는 프로그램
- 계속해서 늘어나는 라이브러리의 자동 추가 및 관리
- 라이브러리의 버전을 자동으로 동기화

2.빌드도구(in Java)

저희 부서에서는 Spring을 쓰기에 java 기반의 빌드도구들만 살펴보겠습니다. 다음과 같이 대표적인 세가지 툴이 있습니다.

"이중에서 주로 쓰는 'Maven'과 'Gradle'에 대해서만 중점적으로 다뤄보겠습니다."

2-1) Maven

"3세대 주류 빌드 도구인 메이븐은 다음과 같은 특징을 갖고 있습니다." 특징> -프로젝트에 필요한 모든 종속성을 리스트 형태로 maven에게 알려주어서 종속성을 관리함 -XML, Repository를 가져올 수 있다. (직접 다운로드 할 필요가 없고, 자동으로 라이브러리를 불러와줍니다. -> 라이브러리 자동관리!

단점> -라이브러리가 서로 종속하는 경우, XML이 복잡해진다. -계층적인 데이터를 표현하기에 좋지만, 플로우나 조건부 상황을 표현하기 어렵다. -편리하나 맞춤화된 로직 실행이 어렵다,

"Maven에 대한 이해를 위해 잠시 pom.xml을 보여드리겠습니다."

pom.xml은 간단히 말하면 maven에 대한 명세서(Description)입니다. POM(Project Object ModeL)을 설정하는 부분으로 프로젝트 내 빌드 옵션을 설정하는 부분입니다. 이걸 다른 프로젝트에 <복사-붙여넣기>하면 되기 때문에 범용성이 좋고, 협업할 때 버전을 통일하기에 좋습니다. 위 그림을 보면, 많이 복잡한데, 중요한 부분은 바로 <Dependencies>입니다. 해당 요소에는 해당 프로젝트가 의존하는 라이브러리 정보들이 담겨 있습니다.

다음으로 실제로 tibero(DB)와 연결할 때에 추가해야 하는 pom.xml의 코드에 대해 알아보겠습니다.
아래는 <dependencies> 태그 안에 들어갈 내용입니다.


`       <!-- mysql -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.13</version>
    </dependency>
    
    <!-- mybatis -->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.4.6</version>
    </dependency>

    <!-- mybatis-spring -->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis-spring</artifactId>
        <version>1.3.2</version>
    </dependency>

    <!-- spring-jdbc -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>${org.springframework-version}</version>
    </dependency>

    <!-- spring-test -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-test</artifactId>
        <version>${org.springframework-version}</version>
        <scope>test</scope>
    </dependency>`


각 라이브러리의 최신 버전을 확인하는 방법은 mvnrepository.com/ 로 이동해서 라이브러리의 그룹아이디나 아티팩트아이디를 검색해서 찾으면 된다!

2-2)Gradle

"요즘 트랜드 도구이자 4세대 주류 빌드 도구인 메이븐은 다음과 같은 특징을 갖고 있습니다." 특징>

  • JVM 기반의 빌드도구
  • 오픈소스 기반의 Builde 자동화 도구
  • Ant와 Maven의 단점을 보완
  • Build-by-convention을 바탕으로 한다. --> 스크립트 규모가 작고 읽기 쉽다.
  • Groovy 기반의 DSL로 작성
  • 설정주입방식(Configuration-Injection)

"Gradle에 대한 이해를 위해 잠시 build.gradle을 보여드리겠습니다."

build.gradle은 쉽게 말해서 gradle에 대한 명세서입니다. pom.xml과 한가지 다른 점은 파일 자체가 프로젝트 오브젝트(객체)로, 프로젝트 인터페이스를 구현하는 구현체이자, 프로젝트 딴에서 필요한 작업을 수행하기 위해 모든 메서드와 프로퍼티를 모아놓은 슈퍼객체라 볼 수 있습니다.

pom.xml은 간단히 말하면 maven에 대한 명세서(Description)입니다. POM(Project Object ModeL)을 설정하는 부분으로 프로젝트 내 빌드 옵션을 설정하는 부분입니다. 이걸 다른 프로젝트에 <복사-붙여넣기>하면 되기 때문에 범용성이 좋고, 협업할 때 버전을 통일하기에 좋습니다. 위 그림을 보면, 많이 복잡한데, 중요한 부분은 바로 <Dependencies>입니다. 해당 요소에는 해당 프로젝트가 의존하는 라이브러리 정보들이 담겨 있습니다.

"이 파일의 구조는 마치 DB에서 원소들이 모여 집합을 이루듯이, 메서드들이 모여 파일이라는 집합을 이루는 형태를 갖고 있습니다."

2-3)Maven vs Gradle

"이번에는 이 두가지 빌드관리 툴을 비교해보겠습니다."

Q1) 성능은? A1) Gradle이 Maven보다 빌드시간, 유연성, 종속성 관리 측면에서 뛰어나다.

Q2) 얼마나 간편하게 설정할 수 있는지? (설정의 용이함) A2) 라이브러리가 종속될 경우, 특정 조건을 표현할 경우에 Maven이 이를 처리하기 복잡하다고 한다. 반면, Gradle은 스크립트가 더 짧고 읽기 쉽게 되어 있다.

Q3) 라이브러리의 의존성 관리 측면에서는? A3) Gradle이 Maven보다 더 효율적이고 강력한 기능을 제공하고 있다. 또한 Gradle은 버전 충돌 또한 관리해준다.

2-4)그래서 결론은...

Gradle을 씁시다!

"자바 웹 애플리케이션을 개발할 때, Gradle이라는 tool을 우선적으로 쓰되, 예외적인 환경에서 그 환경에 맞게 Ant나 Maven을 쓰시면 좋을 것 같습니다." "현재 저희가 관리하는 서버도 maven으로 관리되고 있는데요, 추후에 환경과 여건이 받쳐 준다면, Gradle을 사용하여 개발을 진행하게 된다면 좋을 것 같습니다."

3)배포란?

-(추상적) 작선한 코드를 빌드했으면, 이제 빌드가 완성된 실행 가능한 파일을 사용자가 접근할 수 있는 환경에 배치하는 행위(사용자 환경에 배치가 완료됬으면 배포가 완료됐다고 부를 수 있다.)

-(구체적) 빌드를 하고 생성된 jar 또는 war 파일을 WAS(Jeus나 Tomcat)에 올리는 것이 배포다.

#### 3-2)배포의 과정
"배포의 과정에는 크게 세단계가 있는데..."

-git(소스 형상 관리)에 올려두고 -코드가 제대로 동작하는지, 테스트 코드를 작성하고, -이를 수행하는 작업까지!

그러나! 문제는 이 일련의 과정들을 사람들이 해야한다는 게 문제입니다. ->소스 한번 수정할 때마다 git에 올리고, Test돌리고, 빌드하고,
이런 일련의 과정들이 반복되니까 굉장히 번거롭다는 게 문제입니다.
-
-> 그런데 우리 개발자들한테 있어서 자동화는 숙명이잖습니까?
-
-> 따라서 이런 이슈의 해결책으로 등장한 배포 자동화 툴들이 있는데,
이 부분은 뒤에 나오는 CI/CD와 관련이 있기 때문에 뒤에서 설명하도록 하겠습니다.

## 4) CI/CD에 대하여 - CI

CI(Continuous Integration): 지속적 통합 -개발자를 위한 자동화 프로세스인 지속적 통합으로, (모든 개발이 끝난 직후에 코드 품질을 관리하는) 고전적 방식의 단점을 해소하기 위해 등장한 개념 "옛날과 달리 이제 개발 도중에 품질관리가 가능합니다. 만약 20년 전으로 돌아가서 저랑 A간부님이랑 프로젝트를 진행한다고 해보겠습니다.그러면 중간에 잠재적인 에러가 있음에도 개발이 끝나고 나서 한꺼번에 통합을 하니까, 에러가 반드시 발생할 수 밖에 없겠죠? 서로 클래스가 중복된다던가, 라이브러리 충돌이 발생한다던가, 타입이 중복된다던가, 이와 같은 문제가 굉장히 많이 발생할 수 밖에 없습니다. 그래서 옛날에는 코드를 다 짜고 나서 마지막에 한꺼번에 수정을 하려고 했었기에, 오히려 비용이 더 많이 늘게 되었었던 것 같습니다.

CI 방식 및 과정

1.코드를 통합한다. 2.통합한 코드가 제대로 동작하는지, 테스트한다. 3.제대로 빌드가 되는지도 테스트한다. 4.결과를 정리하고, 버그가 존재한다면 적어둔다. "(이러한 일련의 과정을) 매번 해야 하나? 너무 귀찮은데,,, 라고 생각하실수도 있습니다."

#### 4-2) CI 도구
![](https://static.blex.me/images/content/2023/7/3/20237321_ywTMoE4aFhqDEW2Q3hJv.png)

"프로세스를 자동화 하도록 도와주는 툴이다, 이 정도로만 이해해주시면 되겠습니다."

#### 4-3) CD
CD(Continuous Deploy):지속적 배포
-소프트웨어가 항상 신뢰가능한 수준, 즉 테스트도 잘 되고 빌드도 잘 되는 수준에서 배포될 수 있도록 관리하자는 개념

"but! 실무에서 '이게 CI이고 저게 CD야!' 라고 엄격히 구분하지는 않습니다. 오히려 그냥 하나로 보죠. 공식문서를 보면, '지속적으로 통합하면서 테스트와 빌드를 진행하고, 이를 통과한 코드에 대해서, 신뢰할 수 있고, 바로 배포할 수 있다.' 라고 나와있기에, 'CI'가 선행됨에 따라서 반드시 'CD'가 이루어지게 됩니다. 따라서, '지속적 통합'과 '지속적 배포'를 구분짓는 다는게, 사실상 의미가 없습니다."

##정리를 한번 해보면,, -지속적으로 통합하면서 테스트와 빌드를 진행하고, 이를 통과한 코드에 대해서 신뢰할 수 있고, 바로 배포할 수 있다.

정리를 한번 해보면,
"test,build 잘 통과하고,
통과한 코드에 대해서, 즉 신뢰할 수 있는 코드에 대해서
바로 배포할 수 있다"라고만 알고 넘어가시면 될 것 같습니다.

5)무중단 배포

마지막으로 '무중단 배포'에 대해서 짧게 정리하고 마무리 하겠습니다. 말 그대로 서비스를 잘 실행하고 있다가, 이클립스 우측 하단에 보시면, 버튼바 중간에 빨간버튼, 중지버튼이 있습니다. 이 중지버튼을 누르지 않고, 새로운 코드를 배포하는 걸 말한다고 볼 수 있습니다.

5-1)실무에서의 무중단배포

"좀 더 실무적으로 말씀을 드리자면,
만약 웹서비스를 이용중인데 중간에 새로운 코드가 배포되었다고 가정해보겠습니다.
이떄, 이 웹 애플리케이션이 중단배포로 돌아간다면, 중간에 세션이 끊겨서 다시 로그인을 하는 상황이 벌어졌을 겁니다."
하지만 이 웹 애플리케이션이 무중단배포로 돌아간다면, 중간에 로딩시간이 걸려 잠깐 멈출수는 있겠지만, 세션이 날아가는 일은 벌어지지 않습니다.

"이번에는 다른 상황을 가정해보겠습니다.
기존에 동작하고 있는 서버(배포가 완료된)가 존재해 있고, 그 상태에서 새롭게 업데이트한 코드를 배포한다면 어떻게 될까요?"

--> 바로 충돌이 발생하게 될 겁니다!
--> 조치(무중단배포)를 취해주지 않았다면, 기존에 서비스중인 서버를 잠시 내리고 코드를 뿌려준 후 다시 서버를 동작시켜야 합니다.

아까 위에서 말한 방법에 대한 프로세스를 보시면 아래와 같이 진행이 될 겁니다. 1>8080포트에 서버를 띄운다. 2>새롭게 배포할 내용이 있다면 포트 충돌을 막기 위해서 서버를 다운시킨다. 3>8080포트에 새롭게 배포할 서버를 띄운다. => 서버가 다시 뜨는데 30초의 시간ㅇ이 걸린다고 하면, 그 시간 만크 '다운타임'이 발생했다고 볼 수 있다.

5-2)무중단 배포를 위한 필요조건

-두대 이상의 서버를 서비스해야한다. -다운타임이 발생하지 않으려면 실제 서비스중인 서버와 새롭게 배포한 서버가 동시에 존재해야 한다. -비용을 줄이려면 배포할 때만 새롭게 서버를 띄우고 배포가 완료된 후에 기존 서버는 죽이면 된다. -"이번에는 두가지 배포방식에 대해서 소개해드리겠습니다."

5-3) Rolling 배포

-롤링배포는 서버를 한대씩 구버전에서 새버전으로 교체해가는 전략이다. -서비스중인 서버 한대를 제외시키고, 그 자리에 새 버전의 서버를 추가한다. -이렇게 구버전에서 새버전으로 트래픽을 점진적으로 전환한다. -이와 같은 방식은 서비스의 제약이 있을 경우, 유용하나 배포중인 인스턴스의 수가 감소하므로 서버 처리 용량을 미리 고려해야 한다.

5-4) Blue/Green 배포

-블루/그린 배포는 구버전에서 새버전으로 일제히 전환하는 전략이다. -구 버전의 서버와 새 버전의 서버들을 동시에 나란히 구성하고, 배포시점이 되면 트래픽을 일제히 전환시킨다. 하나의 버전만 프로덕션 되므로 버전관리 문제를 방지할 수 있고, 또한 빠른 롤백이 가능하다. 또 다른 장점으로 운영환경에 영향을 주지 않고, 실제 서비스 환경으로 새 버전 테스트가 가능하다. -예를 들어, 구버전과 새버전을 모두 구성하고 포트를 다르게 주거나 내부 트랙피일 경우 새 버전으로 접근하도록 설정하여 테스트를 진행해 볼 수 있다. 단, 시스템 자원이 두배로 필요하고, 전체 플랫폼에 대한 테스트가 진행되어야 한다.

쉽게 말해서!

"실제로 서비스 중인 환경(Blue)과
새롭게 배포할 환경(Green)을 세트로 준비해서 배포하는 방식을 말한다."

위 그림을 보며, 설명드리겠습니다.
제일 처음에는 LoadBalancer가 서비스 중인 상태에 연결되어 있죠.
얘는 그린인데 그린은 새로 배포한 상태입니다. 이 그린은 원래 로드밸런서에 물려 있지 않았어요.

그러니까 항상 블루인 서버에서 배포를 하고 있다가 새롭게 배포한 그린 서버에다가 로드밸런서의 방향만 바꿔주는 거죠. 그럼 저희는 짧은 시간동안 서버를 가리키는 것만 바로 그린으로 넘겨주더라도 모든 배포가 끝난 상태가 되니까 "가장 속도가 빠르고 효율적이다."라는 장점이 있고, 반대로 단점으로는 "두 개의 서버가 띄워져 있어야 하기에 비용도 두배로 든다" 입니다.

지금까지 <빌드와 배포>에 관한 발표였습니다.

참고 및 출처:
https://www.youtube.com/watch?v=0Emq5FypiMM

https://www.youtube.com/watch?v=6SvUZqbU37E

https://www.google.com/search?q=%EC%A0%95%EC%A0%81%EC%9E%90%EC%9B%90+%EB%AC%B4%EC%A4%91%EB%8B%A8%EB%B0%B0%ED%8F%AC&source=lnms&tbm=isch&sa=X&ved=2ahUKEwjpksHQj7f5AhWiw4sBHRxTCgIQ_AUoAXoECAEQAw&biw=1920&bih=973&dpr=1

https://www.google.com/search?q=%EB%A1%9C%EC%BB%AC%EC%84%9C%EB%B2%84+WAS&oq=%EB%A1%9C%EC%BB%AC%EC%84%9C%EB%B2%84+WAS&aqs=chrome.0.69i59.638j0j1&sourceid=chrome&ie=UTF-8

https://onlywis.tistory.com/10

https://wangmin.tistory.com/50

https://coding-hyeok.tistory.com/47

이 글이 도움이 되었나요?

신고하기
0분 전
작성된 댓글이 없습니다. 첫 댓글을 달아보세요!
    댓글을 작성하려면 로그인이 필요합니다.