[TIL/0627] 직렬화와 역직렬화; 도커; gradle

fpg1·2023년 6월 27일

TIL

목록 보기
3/12

CS지식

직렬화와 역직렬화

https://medium.com/@hatim.zahid/serialization-and-deserialization-how-data-travels-in-a-computer-network-13f61dc225c4

직렬화란?

  • 직렬화란 (데이터) 객체를 바이트 스트림으로 변환하는 프로세스이다
  • 즉 프로그래밍 언어의 객체를 언어에 관계없이 컴퓨터 하드웨어에서 이해할 수 있는 1과 0으로 변환한다

바이트 스트림이란?

  • 의미 있는 최소 독립 정보 단위가 바이트인 데이터스트림을 바이트 스트림이라고 한다
  • 데이터는 바이트 단위로 연속적으로 전송된다

역직렬화란?

  • 바이트 스트림을 프로그래밍 언어의 특정 객체로 변환하는 프로세스이다

알고리즘

(이론)구간 합

합 배열

  • S[i] = A[0] + A[1] + A[2] + ... + A[i-1] + A[i] // A[0]부터 A[i]까지의 합

  • 구간 배열에서는 합 배열을 이용하여 시간복잡도를 줄인다
    - 합 배열을 미리 구해놓으면 일정 범위의 합을 구하는 시간 복잡도가 O(N)에서 O(1)로 감소

합 배열을 만드는 공식

  • S[i] = S[i-1] + A[i]

구간 합을 구하는 공식

  • S[i] - S[i-1] // i에서 j까지의 구간합

(문제) 구간 합 구하기 - 11659

  1. 문제 분석하기
  • 문제에서 수의 개수와, 합을 구해야 하는 횟수는 최대 100,000(십만번)이다.
  • 만약 십만번의 합을 매번 십만번 구간의 합을 계산하여 처리한다면 0.5초 안에 해결 할 수 없다

    놓친 부분: 시간복잡도의 제약 속에서 나의 풀이안이 가능할지 미리 생각해보고 구현하지 않았다


느낀점

공부방법

공식문서마다 다르겠지만, 입문자를 위한 페이지가 별도로 없는 공식문서라면 입문서나 또는 잘 정리된 블로그, 강의를 보고 공식문서를 보는 것이 좋겠다.
왜냐하면 공식문서에서는 초심지가 신경쓰지 않아도 될 내용까지 포함되어 해당 기술의 핵심을 파악하기 어려울 수 있다


도커

Dockerfile

https://www.daleseo.com/dockerfile/
Dockerfile이란?

  • Docker 이미지가 어떤 단계를 거쳐 빌드되야 하는지를 담고 있는 텍스트 파일이다
  • Docker는 Dockerfile에 나열된 명령문을 차례대로 수행하여 이미지를 생성한다

FORMAT

  • 각 명령문은 명령어로 시작하고, 여러 개의 인자가 따라올 수 있다
  • 인자와 명령어의 구분이 쉽도록 명령어는 대문자로 써주는 것이 관례이다
# 주석(comment)
명령어(INSTRUCTION) 인자(arguments)

FROM

  • 하나의 Docker 이미지는 base 이미지부터 시작해서 기존 이미지 위에 새로운 이미지를 중첩해서 여러 단계의 이미지 층(layer)을 쌓아가며 만들어진다
  • FROM 명령문은 이러한 base 이미지를 지정해주기 위해 사용되며, 보통 Dockerfile 내에서 최상단에 위치한다

WORKDIR

  • WORKDIR 명령문은 쉘의 cd 명령문처럼 컨테이너 상에서 작업 디렉토리로 전환을 위해서 사용된다
  • WORKDIR 명령문으로 해당 디렉터리로 전환하면, 그 이후의 모든 RUN, CMD, `ENTRYPOINT', 'COPY', 'ADD' 명령문은 해당 디렉터리를 기준으로 실행된다
WORKDIR <이동할 경로>

RUN

RUN ["<커맨드>", "<파라미터1>", "<파라미터2>"]
RUN <전체 커맨드>
  • RUN 명령문은 이미지 빌드 과정에서 필요한 커맨드를 실행하기 위해서 사용한다

ENTRYPOINT

ENTRYPOINT ["<커맨드>", "<파라미터1>", "<파라미터2>"]
ENTRYPOINT <전체커맨드>
  • ENTRYPOINT 명령문은 이미지를 컨테이너로 띄울 때 항상 실행되어야 하는 커맨드를 지정할 때 사용한다
  • 컨테이너가 뜰 때 ENTRYPOINT 명령문으로 지정된 커맨드가 실행되고, 이 커맨드로 실행된 프로세스가 죽을 때, 컨테이너도 따라서 종료된다

CMD

CMD ["<커맨드>", "<파라미터1>", "<파라미터2>"]
CMD <전체커맨드>
  • CMD 명령문은 해당 이미지를 컨테이너로 띄울 때 디폴트로 실행할 커맨드나,ENTRYPOINT 명령문으로 지정된 커맨드에 디폴트로 넘길 파라미터를 지정할 때 사용한다
  • CMD 명렴문은 이미지를 container로 띄울 때 딱 한 번 실행 기회를 가지게 되며, 이 기회마저도 docker run 커맨드에 인자를 넘길 경우 상실하게 된다

EXPOSE

  • EXPOSE 명령문은 네트워크 상에서 컨테이너로 들어오는 트래픽을 리스닝 하는 포트와 프로토콜을 지정하기 위해 사용한다
  • 주의할 점은 EXPOSE 명령문으로 지정된 포트는 해당 컨테이너의 내부에서만 유효하며, 호스트 컴퓨터에서는 이 포트를 바로 접근할 수 없다
  • 호스트 컴퓨터로부터 해당 포트로의 접근을 허용하려면 docker run 커맨드에 -p 옵션을 통해 호스트 컴퓨터의 특정 포트를 포워딩 시켜줘야한다.

COPY

  • COPY 명령문은 호스트 컴퓨터에 있는 디렉터리나 파일을 Docker 이미지의 파일 시스템으로 복사하기 위해 사용된다.
  • 절대 경로와 상대 경로 모두를 지원하며, 상대 경로를 사용할 때는 이전에 등장했던 WORKDIR 명령문으로 작업 디렉터리를 어디로 전환해놨는지 확인해야한다

ADD

  • ADD 명령문은 일반 파일 뿐만 아니라 압축 파일이나 네트워크 상의 파일도 사용할 수 있다
  • 이렇게 특수한 파일을 다루는게 아니라면 COPY 명령문을 사용하는걸 권장한다

ENV

ENV <> <>
ENV <>=<>
  • ENV 명령문은 환경 변수를 설정하기 위해 사용한다
  • ENV 명령문으로 설정된 환경변수는 이미지 빌드시에도 사용가능하며, 해당 컨테이너에서 돌아가는 애플리케이션도 접근할 수 있다

ARG

ARG <이름>
ARG <이름>=<기본값>
  • ARG 명령문은 docker build 커맨드로 이미지를 빌드 시, --build-arg 옵션을 통해 넘길 수 있는 인자를 정의하기 위해 사용한다

예를들어 port 인자를 선언해주면

ARG port

다음과 같이 docker build 커맨드에 --build-arg 옵션에 port 값을 넘길 수 있습니다

$ docker build --build-arg port=8000 .

인자의 디폴트 값을 지정해주면, --build-arg 옵션으로 해당 인자가 넘어오지 않았을 때 사용된다

ARG port=8000

설정된 인자 값은 다음과 같이 ${인자명| 형태로 읽어 사용가능하다

CMD start.sh -h 127.0.0.1 -p ${port}

ENV와 달리 ARG로 설정한 값은 이미지가 빌드되는 동안에만 유효하니 주의하여야한다

.dockerignore파일

  • Docker 이미지를 빌드할 때 제외시키고 싶은 파일이 있다면 .dockerignore 파일에 추가하면 된다
  • 제외시 RUN, CMD, COPY와 같은 명령문에서 해당 파일을 사용할 수 없다

빌드

Gradle

https://www.youtube.com/watch?v=V4knLFDG-ZM
Gradle이란?

  • 빌드 자동화 도구

빌드 자동화 도구란?
빌드

  • 소스코드를 실행 가능한 파일로 변환하는 것

빌드 도구

  • 코드를 빌드 및 라이브러리 관리, 테스팅, 배포를 수행해준다

빌드 도구를 사용하지 않았을 때의 문제점
1. 반복적인 작업을 수작업으로 수행해야 한다
2. 라이브러리를 직업 다운로드 및 버전 업데이트를 해야한다
3. 프로젝트의 의존성을 파악하기 어렵다

Gradle의 특징
스크립트 언어

  • 동적으로 실행 가능하고
  • 스크립트 로직을 직접 작성할 수 있으며
  • gradle이 지원하는 플러그인을 호출 할 수 있다

Groovy 기반의 DSL

  • 자바와 유사한 문법구조를 가지며, java와 호환된다
  • JVM에서 실행되는 스크립트 언어이다

Plugin이란?

  • 특정 작업을 위해 모아놓은 task들의 묶음

의존성이란?

  • 프로젝트에서 사용하는 라이브러리나 패키지를 의존성이라 한다

Dependencies Configuration

  • 특정 시점에 불필요한 특정 라이브러리를 추가한다면 리소스 낭비이므로 라이브러리를 추가하는 시점을 설정할 수 있다
  • implementation: 런타임 + 컴파일 시점 모두에서 사용
  • compileOnly: 컴파일때만
  • runtimeOnly: 런타임때만
  • testImplementation: 테스트할때만

repositories

  • 라이브러리(모듈)이 저장된 위치를 정의한다
  • 라이브러리의 저장소를 명시해주면 gradle이 해당 저장소에서 필요한 라이브러리를 가져온다

성능
Build Cache

  • 빌드 결과물을 캐싱하여 재사용한다
  • 라이브러리 의존성을 캐시로 저장한 후 라이브러리 재사용

점진적 빌드

  • 마지막 빌드 호출 이후 변경된 부분만 빌드
  • 변경되지 않은 부분은 캐시 결과를 검색해 재사용
    - 태스크의 입력/ 출력이 변경되지 않은 경우 up-to-date를 표시하고 태스크를 실행하지 않는다

데몬 프로세스

  • 다음 빌드 작업을 위해 백그라운드에서 대기하는 프로세스이다
  • 초기 빌드 이후 빌드 실행 시 초기화 작업을 거치지 않아 적은 시간 소요
  • 초기 빌드 결과물을 데몬 프로세스에 저장하고 그 이후의 빌드에서는 데몬 프로세스에서 결과물을 가져와 재사용한다

멀티프로젝트(멀티모듈)이란?

  • 공통되는 도메인을 사용하는 프로젝트를 하나의 프로젝트로 묶어서 관리하는 것이다
  • Gradle은 각 프로젝트가 공통으로 사용하는 클래스를 모듈로 만들어 독립적인 각 프로젝트에서 사용할 수 있도록 한다

Gradle
https://youtu.be/zeDh2mMd_fc

  • src -> 자바 소스파일
  • .gradle -> gradle 버전 및 설정 파일
  • settings.gradle -> 프로젝트 정보 설정
    - 멀티 프로젝트 빌드시에 여러 프로젝트 정의 가능, 하위프로젝트들이 어떻게 구성되었는지 기록
  • build.gradle -> 프로젝트 빌드 정보 및 구성에 대한 표현
  • gradlew, gradlew.bat -> 작동될 gradle 명령 파일들
    - gradle이 설치되어있지 않아도

CI (Continuous Integeration)

  • 지속적 통합이라 하며, 코드 변경사항 마다 빌드, 테스트까지 자동으로 진행하고 결과물을 보고 받고 리포지토리에 자동 통합되는 프로세스
  • 변경 사항이 클래스, 기능 더 나아가 전체 어플리케이션에서의 테스트를 수월하게 진행
  • 신규코드와 기존코드의 충돌을 빠르게 수정 가능

CD (Continuous Deployment)

  • 개발자들이 코드에 변경사항을 줄 경우, 파이프 라인을 통해 이동하여 프로덕션 단계까지 자동으로 배포되는 프로세스

CI/CD

Github actions

https://youtu.be/iLqGzEkusIw

github actions란

  • 특정한 이벤트가 발생했을 때 원하는 일을 자동으로 수행하도록 한다

events

  • 어떤 일이 일어났을 때(트리거)를 지정하는 역할

workflows

  • 특정한 이벤트가 발생했을 때 어떤 일을 수행하고 싶은지 명세할 수 있는 곳

jobs

  • workflows에는 하나 또는 다수의 job이 있을 수 있다.
  • 병렬적으로 혹은 순차적으로 실행될 수 있다
  • job 안에는 step으로 쉘 스크립트를 실행할 수 있다

actions

  • 재사용할 수 있는 오픈된 actions가 정의되어 있다

runner

  • job을 실행하는 machine
  • 각각의 job은 개별적이고 독립적인 machine에서

예제

  • *.yml 형식으로 만든다
  • name: workflow 이름을 지정
  • on: 어떤 이벤트가 발생했을 때 본 workflow가 실행되는지 지정
  • jobs:
    check-bats-version: job의 이름
    runs-on: 어떤 vm(runner)을 사용할 지 지정
    steps: 어떤 순서로 무슨 작업을 실행하는지 지정

도커

도커 컴포즈

그림과 실습으로 배우는 도커&쿠버네티스
도커 컴포즈란?

  • 도커 컴포즈는 도커 설정을 기재한 설정 파일을 이용해 한 번에 여러 개의 컨테이너를 생성, 실행, 폐기하는 기능을 제공한다
  • 다시말해 하나의 텍스트파일(정의파일:compose file, YAML포맷)에 명령어를 기재해 명령어 한번에 시스템 전체를 실행하고 종료와 폐기까지 한번에 하도록 도와주는 도구
  • 정의 파일에는 컨테이너나 볼륨을 어떠한 설정으로 만들지에 대한 항목이 기재돼있다

커맨드

  • up: 정의 파일에 기재된 내용대로 이미지를 내려받고 컨테이너를 생성 및 실행한다. 네트워크나 볼륨에 대한 정의도 기재할 수 있다
  • down: 컨테이너와 네트워크를 정지 및 삭제한다. 볼륨과 이미지는 삭제하지 않는다

도커 컴포즈와 Dockerfile의 차이점

  • 도커 컴포즈는 컨테이너와 주변환경(네트워크 및 볼륨)까지 만든다.
  • Dockerfile은 이미지를 만들기 위한 것이다

UP커맨드: 컨테이너와 주변환경생성

  • 컴포즈 파일 내용에 따라 컨테이너와 볼륨, 네트워크를 생성하고 실행한다
  • 컴포즈 파일의 경로는 -f 옵션을 사용해 지정한다
    docker-compose -f 정의_파일_경로 up 옵션

정의파일

  • 정의파일 이름은 docker-compose.yml이 기본설정이름이다
  • 정의파일은 한 폴더에 하나만 있을 수 있다
  • 파일 명령어는 똑같이 도커엔진에 전달되며, 만들어진 컨테이너도 동일하게 도커 엔진 위에서 동작한다
  • 컨테이너 생성에 필요한 이미지 파일이나 HTML 파일 모두 컴포즈 폴더에 함께 둔다

서비스와 컨테이너

  • 도커 컴포즈에서 컨테이너가 모인 것을 서비스라 한다
  • 도커컴포즈와 쿠버네티스에서는 컨테이너의 집합체를 서비스라고 부른다
    - 이는 리눅스에서 동작하는 소프트웨어를 서비스라고 부르기 때문에 정착된 용어인듯하다

컴포즈 파일 작성하는 방법

  • 작성요령은 주항목 -> 이름추가 -> 설정과 같은 순서로 작성한다
  • 주항목에는 services, networks, volumes 등이 있으며, 주 항목 아래에 정의 내용이 기재되므로 services:와 같이 뒤에 콜론(:)을 붙인다
  • 주항목 아래에는 한 단 들여써서 이름을 기재한다
    - 한 단의 공백의 개수는 몇 개여도 상관없지만 탭은 사용할 수 없다. 또한 한번 정한 한 단의 크기를 그 뒤에도 계속 유지해야한다.
  • 이름을 기재한 다음에는 각 컨테이너의 설정을 기재한다. 설정할 내용이 여러 개 라면 줄을 바꿔 하이픈(-)을 앞에 적고 들여쓰기를 맞춘다

컴포즈 파일 작성요령 정리

  • 주석은 #, 문자열은 작음따옴표 혹은 큰따옴표로 감싼다
  • 첫 줄에 도커 컴포즈 버전을 기재한다

컴포즈 파일의 항목
주항목

자주 나오는 정의내용

  • depends_on 은 다른 서비스에 대한 의존관계를 나타낸다.
    - 컨테이너를 생성하는 순서나 연동 여부를 정의한다.
    depends on: -namgeuk은 namgeuk 컨테이너를 생성한 다음 penguin 컨테이너를 만든다

restart의 설정값

그 외의 정의 항목

예시

도커의 detach/attach(백그라운드/포그라운드)

https://asecurity.dev/entry/Docker-detachattach%EB%B0%B1%EA%B7%B8%EB%9D%BC%EC%9A%B4%EB%93%9C%ED%8F%AC%EA%B7%B8%EB%9D%BC%EC%9A%B4%EB%93%9C-%EC%8B%A4%ED%96%89
포그라운드 실행

  • 현재 실행하는 터미널(콘솔)에 컨테이너의 동작 상태를 출력하는 모드이다
  • 터미널과 프로세스가 부모, 자식으로 연결되어 터미널이 끊어질 경우 컨테이너가 종료된다
  • Docker Compose, docker run 명령이 모두 기본적으로 포그라운드로 실행된다

백그라운드 실행

  • 터미널에 관계없이 지속적으로 실행할 수 있도록 구성할 때 유용하다
  • 현재 동작상태를 확인하는 용도로 log옵션을 이용할 수 있다
  • run은 컨테이너를 생성할 때 사용하는 명령이고, start는 이미 존재하는 컨테이너를 실행할 때 사용하는 명령인데 docker start시 자동으로 백그라운드 모드로 동작한다
profile
backend

0개의 댓글