콘텐츠로 이동

2025 08 18

2025-08-18

Play vs Spring 배포 프로세스 비교 (thin Jar, fat Jar)

  • Play Framework
    • sbt dist로 배포할 파일 빌드하면 전통적인 방식의 배포판 구조 사용
    • bin/: 실행 스크립트 포함

      1. 스크립트는 실행환경 보고 (ex. OS, java 위치)
      2. 스크립트 내부에서 lib/ 하위 JAR 파일 경로 : 으로 이어붙여 매우 긴 classpath로 만듦

        declare -r script_conf_file="${app_home}/../conf/application.ini"
        declare -r app_classpath="$lib_dir/../conf/:$lib_dir/til-api.til-api-1.0-SNAPSHOT-sans-externalized.jar
        :$lib_dir/org.scala-lang.scala-library-2.13.10.jar:$lib_dir/com.typesafe.play.twirl-api_2.13-1.5.1.jar
        :$lib_dir/com.typesafe.play.play-server_2.13-2.8.8.jar:$lib_dir/com.typesafe.play.play-logback_2.13-2.8.8.jar
        :$lib_dir/com.typesafe.play.play-akka-http-server_2.13-2.8.8.jar:$lib_dir/com.typesafe.play.filters-helpers_2.13-2.8.8.jar:...
        

      3. 최종적으로 java -cp [엄청나게 긴 클래스패스] play.core.server.ProdServerStart 형태로 명령어 만들어 실행

        • lib/: 어플리케이션 코드 JAR와 모든 의존성 라이브러리 JAR들이 각각 파일로 들어있음
        • conf/: 설정 파일(application.conf, routes)
  • SpringBoot
    • gradle bootJar로 빌드하면 실행 가능한 *.jar 파일 생성
    • 생성된 *.jar에는 어플리케이션 코드 + 의존성 라이브러리 jar 들이 BOOT-INF/lib 폴더 안에 그대로 포함됨
    • java -jar til.jar와 같이 실행
      • JVM은 jar 파일 내 MANIFEST.MF를 읽어 Main-Class 찾음
      • Spring Boot Jar의 Main-Class는 사용자의 코드가 아닌, Spring Boot가 제공하는 JarLauncher
      • jar 파일 내부에 포함된 라이브러리 읽을 수 있도록 특수 클래스 로더 설정
    • 모든 준비 끝나면 로더가 사용자의 main 메서드 호출해 앱 실행

rabbitMQ close jvm hang

  • 원인
    • 서로 다른 스레드에서 channel.close(), connection.close() 동시에 호출되면 문제 생길 수 있음
    • 따라서 단일로 닫히도록 하자