-
jar 파일 실행 원리백엔드 2023. 2. 3. 11:05
- java -jar로 커맨드 실행
- MANIFEST.MF(개발영역단과 스프링부트 연결해주는 영역)의 main class인 jarLauncher가 실행
- jarLauncher가 MANIFEST.MF start class인 JarAnalysisApplication 호출
⇒ 이것의 핵심은 우리가 개발한 main 메소드를 스프링 프레임워크가 대신 호출해준다는 것
여기서 더 알 수 있는 것은 프레임워크와 라이브러리의 차이점
프레임워크 = 우리가 짠 코드를 호출, 흐름 통제권을 가짐
라이브러리 = 우리가 호출
jar ⇒ 스프링부트에 개발한 소스코드를 실행하는 모든 것을 가지고 있음
스프링 부트 jar 구성 요소
(BOOT-INF, org/springframework/boot/loader, META-INF)
- BOOT-INF
- classes : jvm이 읽을 수 있도록 컴파일된 클래스 파일
- lib : 코드 실행 필요한 디펜던시 라이브러리들
- classpath.idx : lib에 있는 외부 라이브러리들을 찾을 수 있도록 클래스패스 명시
- layers.idx : 도커에서 jar 이미지 만들 때 쓰는 정보
- 도커 ⇒ 빌드된 jar 파일을 도커 컨테이너로 복사 후 실행, 컨테이너 기반 오픈소스 가상화 플랫폼
- 가상화 방식
- OS 가상화 : 사용법 간단, 무겁고, 느리며 운영환경에서 사용할 수 없음
- 도커 : 프로세스를 격리하는 방식, 가볍고, 빠름, 성능적 손실이 거의 없음
- 도커 이미지
- 컨테이너 실행에 필요한 파일과 설정 값 등을 포함하고 있는 것
- 컨테이너 = 이미지를 실행한 상태
- 같은 이미지에서 여러 개 컨테이너를 생성할 수도 있고, 컨테이너 상태가 바뀌거나 삭제되도 이미지를 통해 다시 컨테이너를 실행할 수 있음
- 이미지를 만들어서 저장해두면 다른 서버에서도 이미지를 받아서 컨테이너를 실행 시켜 동일한 환경을 만들어 줄 수 있음 ⇒ 도커 허브에 등록하여 관리
- 컨테이너를 실행하기 위해 필요한 정보를 가지고 있기 때문에 용량이 보통 수백 메가바이트 정도
- 처음 이미지 다운 받을 때는 괜찮지만, 기존 이미지에 파일 하나를 추가하고 다시 받으려면 비효율적 이기 때문에 레이어 사용
- 이미지는 여러 개의 레이어로 구성, 파일이 추가되거나 수정되면 새로운 레이어 생성
- 형태 : [Registry URL]/[사용자 ID]/[이미지명]:[tag]
- Registry URL ⇒ 도커 허브(기본)
- 사용자 ID 지정하지 않으면 기본값(Library)
- ubuntu = library/ubuntu = [docker.io/library/ubuntu](<http://docker.io/library/ubuntu>)
// tag 명령어 이용하여 기존 이미지에 추가로 이름을 지을 수 있음 docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG] // subicura라는 ID 사용, 이미지 이름을 sinatra-app으로 변경 docker tag app subicura/sinatra-app:1 // docker의 push 명령어로 도커 허브에 이미지 업로드 docker push subicura/sinatra-app:1
- 도커 이미지 만들려면 도커파일 작성 ⇒ 도커 빌드
- 이미지는 url 방식으로 관리하며 태그를 붙일 수 있음
// 도커파일 작성 # Start with a base image containing Java runtime FROM java:8 # Add Author info LABEL maintainer="hdh8659@naver.com" # Add a volume to /tmp VOLUME /tmp # Make port 8080 available to the world outside this container EXPOSE 8080 # The application's jar file ARG JAR_FILE=build/libs/realtime-client-0.0.1-SNAPSHOT.jar # Add the application's jar to the container ADD ${JAR_FILE} realtime-client-0.0.1-SNAPSHOT.jar # Run the jar file ENTRYPOINT ["java","-jar","/realtime-client-0.0.1-SNAPSHOT.jar"]
- 이미지를 컨테이너로 실행
docker run -p 5000:8080 to-do-springboot #
- 내부적으로 애플리케이션이 8080을 사용하고 있으나 5000도커
- 스프링부트 경우 임베디드 된 WAS를 통한 단독 실행이 가능하기 때문에 빌드된 jar 파일 복사만으로 도커 이미지를 구성할 수 있어 편리
- 반드시 도커 파일은 jar파일을 가져오는 것, 도커 빌드 전 반드시 스프링부트 애플리케이션의 빌드가 선행되어야 한다는 점
- 도커로 애플리케이션 배포 시 문제점 : 디버깅과 디버깅 과정에서 수정된 코드 즉시 반영이 되지 안되는 점 ⇒ 스프링 부트에서 Dev Tools로 방법 제공, 도커 환경이 아닌 경우에 Dev Tools는 변경된 애플리케이션의 내용을 즉시 반영하고, 서비스를 자동 재시작해주는 역할, 도커 환경에서도 동일하게 동작하지만 추가 설정이 필요
// application.yml 파일에 아래 코드를 추가한 후 도커로 배포 spring: devtools: remote: secret: mysecret
- 가상화 방식
- 도커 ⇒ 빌드된 jar 파일을 도커 컨테이너로 복사 후 실행, 컨테이너 기반 오픈소스 가상화 플랫폼
- spring-boot-loader
- jar 파일 실행 - spring-boot-loader가 작성한 소스 코드 호출 - spring-loader는 gradle이 빌드할 때 디폴트로 넣어줌
- 기본 java에도 jar 실행해주는 클래스가 있는데 굳이 spring-boot-loader를 통해 실행하는 이유 ⇒ 자바는 jar안의 jar를 로드하는 방식을 제공하지 않음. 따라서 스프링부트는 spring-boot-loader 라는 자신만의 방식으로 nested.jar 까지 로드하는 방법 제공
- META-INF : 스프링부트와 자신이 개발한 소스 코드 연결해주는 영역
- MANIFEST.MF : jar 실행되면 먼저 Main-Class 인 JarLauncher가 호출
- JarLauncher에서 자신이 개발한 statrt-class를 호출하기 위해 필요한 경로 설정 파일
- jar 실행 - Main Class인 jarLauncher 호출
- jarLauncher 에서 우리가 개발한 start-Class 호출하기 위해 필요한 경로 설정 파일
'백엔드' 카테고리의 다른 글
Java Study[2022-11-01] - 스프링부트 프로젝트(JPA 보충 내용) (0) 2022.11.01 Java Study[2022-10-31] - 스프링부트 프로젝트(JPA CRUD) (0) 2022.10.31 Java Study[2022-09-19] - 객체지향프로그래밍(set 인터페이스, override 후 equalse(), hashCode() 재정의) (0) 2022.09.19 Java Study[2022-09-18] - 객체지향프로그래밍(set 인터페이스, Iterator() 학습) (0) 2022.09.18 Java Study[2022-09-17] - 객체지향프로그래밍(Stack과 Queue 구현하기) (0) 2022.09.18