열심히 끝까지

[10분 테코톡] 스티치의 빌드와 배포 영상정리 본문

디바이스 융합 자바(Java)기반 풀스택 개발자 양성과정(과제)

[10분 테코톡] 스티치의 빌드와 배포 영상정리

노유림 2022. 6. 12. 01:10

빌드와 배포(동영상 시청)
영상 : https://www.youtube.com/watch?v=6SvUZqbU37E

1. 빌드란?
컴파일 그리고 빌드
 > 컴파일 : 작성한 소스코드를 바이너리 코드(2진 코드)로 변환하는 과정
                : 이진법 - 0, 1, 0, 1 < 컴퓨터가 이해할 수 있는 기계어
                : 즉, 컴퓨터가 이해할 수 있는 기계어로 바꿔주는 작업
                    = "컴파일"
                : 이런 일을 해주는 것 = "컴파일러"
 
 > 링크 : 여러 개로 분리된 소스코드들을 컴파일한 결과물들에서
              최종 실행 가능한 파일을 만들기 위해 필요한 부분들을 
              찾아서 연결해주는 작업
           
           : 링크는 컴파일이 이미 진행된 상태!
               - 컴파일이 진행된 상태의 작업물을 가지고 실행 가능한 파일을
                 만들어 주기 위해서 작업
           : ex ) 클래스 Car    |     List<Car> <- 일급 컬렉션 코드 Cars
                   각각 컴파일 진행
                   if A파일, B파일로 구분되어 있으면 각기 다른 파일이라 컴파일 진행
                   List<Car>에 Car라는 코드를 참고해야 하는데, 컴파일 된 0101만 있으면
                   무엇인지 모름
                    => 이런 경우에 링크를 통해서 연결해주는 작업 진행

 > 빌드 : 소스코드를 "실행 가능한 소프트웨어 산출물"로 만드는 일련의 과정
            : 컴파일과 같이 같은 소스코드를 작성하는데
              소스코드를 실행 가능한 소프트웨어로 만듦
            : 산출물 예시 - jar(Java Archive), war Web Appliation Archive)
            : 빌드에는 컴파일과 링크가 포함!     
            : ex) intelliJ - 망치모양버튼(빌드버튼) 버튼을 통해 빌드 진행
                    
2. 빌드 도구
 > 소스코드를 컴파일 : 테스트, 정적 분석 등을 실시하여 실행 가능한
                                애플리케이션으로 자동 생성하는 프로그램
 > 계속해서 늘어나는 라이브러리의 자동 추가 및 관리
 > 라이브러리의 버전 자동으로 동기화
 > 빌드를 할 때 앞서 이야기한 task들이 이루어져 있는데
    이것을 자동으로 도와주는 도구!
 > 빌드 도구가 등장했던 배경에서, 라이브러리 같은 것을 기존에는
    직접 jar파일 같은 것을 직접 추가해서 사용
      -> 빌드도구 덕분에 알아서 라이브러리를 추가, 연관 맺어주어
          편하게 사용 가능

 > Java의 빌드도구 : ANT, Maven, Gradle
   - ANT
     특징
      : XML 기반 빌드 스크립트 개발
      : 규칙 존재하지 않음
      : 절차적이다.(명확한 빌드 절차 정의 필요)
      : 생명주기를 갖지 않아 각각의 Target에 대한 의존관계와 작업을
        정의해주어야 함
     단점
      : 유연성이 높으나 프로젝트가 복잡해지는 경우 Build 과정의 이해가 어려움
      : XML, Remote Repository를 가져올 수 없음
      : 스크립트 재사용이 어려움
   
   - Maven
      특징
       : 프로젝트에 필요한 모든 종속성(Dependency)를 리스트 형태로
         Maven에게 알려주어 종속성을 관리
       : XML, Repository를 가져올 수 있음.
            : POM.xml 이라는 Maven 파일에 필요한 Jar, Class, Path를 선언만 하면
             직접 다운로드 할 필요가 없이 Repository에서 자동으로 필요한 라이브러리
             파일을 불러와 줌.             
            : Build.gradle 파일과 비슷함
      단점
       : 라이브러리가 서로 종속할 경우 XML이 복잡해짐
       : 계층적인 데이터를 표현하기에는 좋지만,
         플로우나 조건부 상황을 표현하기 어려움
       : 관리는 편리하나 맞춤화된 로직 실행이 어려움
       
   - Gradle
      특징
       : JVM 기반의 빌드 도구
       : Ant와 Maven의 단점을 보완
       : 오픈소스 기반의 Build 자동화 도구
       : Groovy 기반 DSL(도메인 통합 언어..?)로 작성
       : Build-by-convention을 바탕으로 함
           -> 스크립트 규모가 작고 읽기 쉬움
       : 설정 주입 방식(configuration injection)(인젝션한다)
       : 라이브러리 의존성을 코드 한 줄만 넣어줘도 관리
       : 라이브러리 버전이 바뀌어도 코드 한 줄만 수정해줘도 됨
           -> 사용자가 직접 라이브러리 버전을 관리할 필요 없음
       : 특정 컴퓨터나 디바이스에 버전이 종속될 일이 없기 때문
           -> Respository에 올려도 아무나 사용할 수 있다는 장점 존재
      Maven vs Gradle
       - 가장 중요한 성능은?
           : Gradle이 Maven보다 빌드에 소요되는 시간, 유연성, 종속성 관리 등
             다양한 측면에서 뛰어나다는 평가 존재
       - 얼마나 간편하게 설정할 수 있는지?
           : 라이브러리가 종속될 경우, 특정 조건을 표현할 경우에
             Maven이 이를 처리하기 복잡
             Gradle은 스크립트가 더 짧고 읽기 쉽게 되어있음
       - 라이브러리 의존성 관리?
           : Gradle이Maven보다 더 효율적이고 강력한 기능 제공
             Gradle 버전 충돌 또한 관리
   
3. 배포란?
    : 작성한 코드를 빌드하고, 빌드가 완성된 실행 가능한 파일(jar 또는 war)을
      사용자가 접근할 수 있는 환경에 배치하면 배포가 완료된 것
    : 어떤 블로그에 deploy라는 단어의 뜻의 유래가 
      군대에서 병사들을 일정한 위치에 배치하는 상황에서 발생된 단어
        -> 실행 가능한 파일 = 병사
        -> 사용자에게 제공해주기 위한 환경에 배치한다는 생각 
              => deploy는 그런 작업을 하는 일
    : 즉, jar 또는 war파일을 WAS(웹 애플리케이션 서버)에 올리는 것 = 배포

    : git(소스 형상 관리)에 올려둠 -> 코드가 제대로 동작하는지 테스트 코드 작성
         -> 이를 수행 및 검증하는 작업 -> 빌드가 잘 되면 배포 가능한 상태
       ==> 이 과정을 사용자가 직접 해주어야 함.
          => 그래서 나온 것이 빌드 자동화(CI/CD와 관련된 내용이 많기에 뒤에서 설명)
 
4. CI/CD에 대하여
CI(Continuous Integration : 지속적 통합)
   : 개발자를 위한 자동화 프로세스인 지속적 통합으로
     모든 개발이 끝난 이후에 코드 품질을 관리하는 고전적 방식의 단점을
     해소하기 위해 나타난 개념
   : 기존에는 개발이 끝난 이후에 코드 품질 관리 
         - 모든 코드를 다 작성 후 통합하면 에러 많이 발생
               ==> 그때가서 고치면 비용적 측면이 듦
               ==> 그래서 지속적인 통합, 주기적으로 계속 통합하며 발생하는 에러들을
                       확인 및 보수
   -CI 프로세스
      1. 코드 통합한다.
            - git에 자신이 개발한 코드 올려서 통합하는 과정
      2. 통합한 코드가 제대로 동작하는지 테스트 진행
      3. 제대로 빌드가 되는지 테스트
      4. 결과를 정리하고 버그가 존재한다면 적어둠
            - 발생하는 에러 확인 -> 수정 -> 다시 통합
  ~> 1~4의 과정을 계속해서 반복
            => 이 반복작업을 해결하기 위해 자동화 도구 탄생
   * Jenkins와  Travis
        - 둘 다 CI라는 자동화 기능 이외에 더 많은 기능 제공 
        - CI를 하기 위한 프로세스들을 자동화하도록 도와주는 툴

- CD(Continuous Deploy : 지속적 배포)
   : 소프트웨어가 항상 신뢰 가능한 수준에서 배포될 수 있도록 관리하자는 개념
         - 신뢰 가능한 수준이 어떤것인가?
                 : 테스트 다 통과, 빌드 잘 됨 - CI에서 본 것 같은 느낌?(CI 프로세스)
         - CI/CD가 불가결함
                 : CI가 선행됨에 따라 CD가 가능하다라는 느낌
                       -> 그래서 CI/CD 묶어서 통칭해서 부르는 것 같음
- CI/CD 정리
   : 지속적으로 통합하면서 테스트와 빌드를 진행하고 이를 통과한 코드에 대해서
    신뢰할 수 있고 바로 배포할 수 있다는 개념
   : 신뢰할 수 있는 코드 제작 -> 신뢰할 수 있는 코드를 언제든 지속적으로 배포

4. 무중단 배포
   : 기존에 동작하고 있는 서버(배포가 완료된)가 존재
     그 상태에서 새롭게 업데이트한 코드를 배포한다면?
        -> 충돌이 발생!!!
        -> 기존의 서비스 중인 서버를 잠시 내리고 코드를 배포한 후
             다시 서버를 동작시켜야 함
   ex ) 8080 포트를 서버에 띄움 
         -> 새롭게 배포할 내용이 있다면 포트 충돌을 막기 위해서 서버를 다운
         -> 8080 포트에 새롭게 배포할 서버를 띄움

         => 서버가 다시 뜨는데 30초의 시간이 걸린다고 한다면 그 시간만큼
              다운 타임(유저에게 서비스가 불가능한 시간)이 발생
                  - 다운타임이 발생 시, 유저가 서비스를 쓸 수 없는 상태
                    해당 주소를 입력해도 페이지를 볼 수 없는 상태
               : 개발자의 경우 유저에게 최대한 가장 신뢰성 있고 성능이 좋은 환경을 
                 제공해야 하는데 이런 문제 발생시 문제가 될 수 있음
               : 자신이 제공하는 애플리케이션 서비스에서 다운타임이 문제가 되지 않는다면
                 무중단 배포를 고려해보지 않아도 됨
               : 하지만 지속적인 서비스가 필요한 환경에서는 
                 "무중단 배포" 고려할 수 밖에 없음
   - 무중단 배포 필요 조건
        : 두 대 이상의 서버를 서비스해야 한다
        : 다운 타임이 발생하지 않으려면 실제 서비스 중인 서버와
          새롭게 배포한 서버가 동시에 존재해야 함
        : 비용을 줄이려면 배포할 때만 새롭게 서버를 띄우고
          배포가 완료된 후에 기존 서버는 죽이면 됨
    
   -무중단 배포의 종류  
      : 롤링 배포카나리 배포블루/그린배포

      - 롤링 배포(Rolling 배포)
         : 서버 1과 2가 로드 밸런서에 몰려있는 상태
         : 로드 밸런서 - 서버로부터 들어오는 요청을 
                                 최대한 잘 분배하는 일을 담당하는 역할
           1. 서버 1을 로드 밸런서에서 뺌
           2. 서버 1에 배포
           3. 서버 1을 다시 로드 밸런서에 넣음
           4. 서버 2를 로드 밸런서에서 뺌 
           5. 서버 2에 배포
           6. 서버 2를 다시 로드 밸런서에 넣음
            - 모든 서버 배포 완료!

         : 단점
            - 배포할 서버가 너무 많다면 n대 단위로 배포하기도 하는데 
              배포가 모두 끝나기 전까지는 누구는 이전 서비스를 받고 
              누구는 신규서비스를 받을 수 있다는 문제가 존재
            - 1대에 배포하는 것보다 최소 2배 이상 느림 

      - 카나리 배포(Canary 배포)
         : 광부들이 광산에 유독가스가 나오는 것을 알아내기 위해서
           가스에 민감한 카나리아를 광산 안에서 키웠다고 해서 유래된 배포
         : 소수의 유저(혹은 사내)만 사용하는 환경(Canary 환경)에 신규 버전을
           배포하고 문제가 없다고 판단됐을 때 다른 모든 서버에 배포

      - 블루/그린 배포(Blue / Green 배포)
         : 실제로 서비스 중인 환경(Blue)과 새롭게 배포할 환경(Green)을 
           세트로 준비해서 배포하는 방식

         : 장점
            - 새롭게 배포할 환경에만 배포하면 되기 때문에 배포 속도가 매우 빠름
            - 언제나 Green 환경이 떠있기 때문에 만약 잘못된 버전으로
               배포를 했을 경우에 신속하게 롤백이 가능
         : 단점
            - Green 환경이 항상 떠있어야 하기 때문에 비용이 두 배로 듬