전제 조건

  • Docker가 설치 되어 있고 실행 중 이어야 한다.
  • 스프링 프로젝트를 jar파일로 내보내고 root/target/ 에 따로 빼두어야 한다.
  • Docker에 계정으로 로그인 되어 있어야 한다.

 

1.  루트 디렉토리에 Dockerfile 만들기

FROM {jdk 명} ex: openjdk:17-jdk 
COPY {jar 파일 경로명} ex: target/druginfo-0.0.1-SNAPSHOT.jar app.jar
ENTRYPOINT ["java","-jar","/app.jar"]

경로에 파일 있는지 확인

 

2.  Docker 파일 빌드, Docker hub에 업로드

docker build -t [이미지 이름] .
docker tag [이미지 이름] username/[이미지 이름]:latest
docker push username/[이미지 이름]:latest

Docker 허브에 잘 올라와 있는지 확인

상황

프로젝트 파일 실행시 grable이 전혀 빌드가 되지 않고 

java.io.StreamCorruptedException: invalid type code: 00
> invalid type code: 00

* Try:
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.
> Get more help at https://help.gradle.org.

다음 문구가 터미널에 출력 되는 상황

 

원인

주로 gradle의 버전이 맞지 않아서 발생한다고 한다.

해결법

settings -> Preferences -> Build, Execution, Deployment -> Build Tools -> Gradle

경로에서 설정된 Gradle의 JVM이 Spring 프로젝트를 만들었을 때 설정한 jdk와 동일하게 맞추어 주면 된다.

Group (패키지 이름)

    • 조직이 도메인을 가지고 있을 시 조직의 도메인을 거꾸로 적는다.
    • 특정 웹사이트 도메인이 없을 경우 Group은 회사나 조직의 이름과 프로젝트/팀 이름을 포함하는 것이 일반적
      • ex: com.[회사 또는 조직 이름].[프로젝트 또는 팀 이름]
    • Oracle표준 패키지 이름은 소문자 ASCII (a-z), 숫자 (0-9),  그리고 마침표 (.)로 이루어져야 한다.
      • 추가로 숫자를 시작으로 하는 것은 허용하지 않는다.

Artifact

  • 프로젝트 또는 애플리케이션의 이름
  • 소문자로 작성하며 공백이나 특수문자는 사용하지 않는다.
  • ex: 팀명 DrDrug → drdrug

Name

  • 프로젝트 명
  • Artifact와 비슷하게 작성

Description

  • 프로젝트에 대한 간략한 설명

Package name

  • Java 패키지의 이름으로, 일반적으로는 Group과 Artifact를 합친 이름을 사용

상황

안드로이드 어플에서 찍은 사진을 multipart-type요청으로 body에 담아 서버로 요청을 보냈을 때 발생

 

Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: org.springframework.web.multipart.MaxUploadSizeExceededException: Maximum upload size exceeded] with root cause

이유

사용자가 업로드하려고 시도한 파일의 크기가 서버에서 설정된 최대 업로드 가능 크기를 초과하였기 때문

SpringBoot에서 기본으로 설정된 최대 업로드 크기는 1048576 바이트(약 1MB) 만약 파일의 크기가 이 값을 초과한다면 FileSizeLimitExceededException 에러가 발생한다.

이 문제를 해결하기 위해서는 서버의 파일 업로드 제한을 증가시키거나, 사용자가 업로드하는 파일의 크기를 줄여야 한다.

 

해결

# application.properties 버전
spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=10MB

# application.yml 버전
spring:
  servlet:
    multipart:
      max-file-size: 10MB
      max-request-size: 10MB

Spring Boot에서는 application.properties 또는 application.yml 파일에서 명시하여 파일 업로드 크기를 조정하여 해결 할 수 있다.

상황

Restfull으로 개발된 SpringBoot 애플리케이션을 AWS EC2에 배포하였다.

어 그런데 일정 시간이 지나면 자동으로 연결이 끝어지면서 서버가 종료하게 된다.

학교 선배님에게 듣기로는 서버는 절대 죽어서는 안되고 계속 돌아가야 한다고 하여 방법을 찾게 되었다.

 

nohup, disown 명령어

// 공통 명령어
bashCopy code
nohup command-to-be-run &

// 포그라운드 프로세스 Spring jar파일 기준 방법
nohup java -jar ~.jar &
// 백그라운드 프로세스 기준 
disown

해당 nohup: ignoring input ~ 메시지가 뜨면 성공

nohup은 "no hangup"을 의미하며, 프로세스를 시작할 때 사용된다. 이는 터미널 세션 종료 시에 신호를 무시하도록 프로세스에 지시하는 것을 의미한다. & 기호는 명령어는 해당 프로세스를 백그라운드에서 실행하도록 한다.

disown 은 bash 셸의 내장 명령으로, 이미 실행 중인 백그라운드 프로세스에 대해 사용되며 현재 셸의 작업 목록에서 작업을 제거한다. disown이 실행되면, 해당 프로세스는 셸에서 분리되어 사용자가 로그아웃하더라도 계속 실행되게 된다.

따라서 위 명령어는 ~.jar를 실행하고, 이 프로세스를 백그라운드에서 계속 실행하도록 하며, 터미널이나 쉘이 닫혀도 종료되지 않도록 한다.

요약: 프로그램을 터미널 세션 종료 시에 신호를 무시하도록 설정 후 백그라운드로 실행시켜 사용자가 로그아웃을 하거나 네트워크 연결이 끊어져도 중단되지 않게 해준다.

 

특이사항

  • nohup 명령어로 실행되는 프로세스는 자동으로 재시작 되지 않는다.
    • 서버가 중지되거나 재부팅 된다면 수동으로 다시 실행시켜 주어야 한다.
  • nohup java -jar ~.jar > output.log 2>&1 & 명령어를 통해
    • nohup.out 파일에 출력을 저장하지 않고 다른 파일에 저장하는 것이 가능하다.

 

'Development > Spring' 카테고리의 다른 글

스프링 프로젝트 명명규칙  (0) 2023.08.05
multipart.MaxUploadSizeExceededException 해결  (0) 2023.07.30
Tomcat, Jetty, Undertow  (0) 2023.07.16
Spring vs SpringBoot  (0) 2023.07.16
DTO, POLO 데이터 객체  (0) 2023.07.01

Tomcat

Apache Software Foundation에서 개발한 오픈 소스 웹 서버 및 서블릿 컨테이너.
Java Servlet, JavaServer Pages (JSP), Java EL 등을 지원하며, 웹 애플리케이션을 위한 컨테이너 역할 수행한다.

 

장점:

  1. 오랜 기간 동안 사용되어 왔고, 안정성이 검증되어 있다.
  2. 방대한 커뮤니티 지원과 풍부한 문서화.
  3. Spring과 같은 인기 있는 Java 프레임워크와 잘 호환된다.
  4. Java 웹 애플리케이션 표준인 Servlet과 JSP를 잘 준수한다.

단점:

  1. 경량화에 비중을 둔 웹 서버에 비해 상대적으로 무거울 수 있다.
  2. 비동기 처리와 같은 몇몇 고급 기능 지원이 제한적일 수 있다.

 

Jetty

Eclipse Foundation에서 개발한 오픈 소스 웹 서버 및 서블릿 컨테이너.
작은 크기, 빠른 시작 시간, 모듈식 플러그인 아키텍처 등이 특징.

 

장점:

  1. 경량화되어 있어 메모리 사용량이 적고 시작 시간이 빠르다.
  2. 모듈식 아키텍처로 필요한 기능만 선택적으로 사용할 수 있다.
  3. 임베디드 웹 서버로서 사용하기 적합하다.

단점:

  1. Tomcat과 비교할 때 상대적으로 작은 커뮤니티 지원.
  2. 문서화가 Tomcat만큼 풍부하지 않을 수 있다.

 

Undertow

JBoss에서 개발한 경량화된 오픈 소스 웹 서버.
Servlet 3.1, WebSocket, HTTP/2 등 최신 Java 웹 표준을 지원하며, 높은 성능과 비동기 처리를 지원.

 

장점:

  1. 빠른 시작 시간과 높은 성능.
  2. 비동기 처리를 지원하여 고성능이 요구되는 애플리케이션에 적합하다.
  3. 최신 Java 웹 표준을 지원한다.

단점:

  1. 상대적으로 새로운 웹 서버로 커뮤니티 지원이 더 적을 수 있다.
  2. Tomcat과 Jetty에 비해 일부 애플리케이션에서의 호환성 문제가 있을 수 있다.

소개

  • Spring: 자바 플랫폼을 위한 오픈 소스 프레임워크로, 2003년에 Rod Johnson 의해 처음 발표되었다. 
  • SpringBoot: Spring Framework 위에서 구축된 독립적인(stand-alone), 생산 수준의 Spring 기반 애플리케이션을 쉽게 만들 있도록 돕는 도구

공통점

  • Java로 개발된 애플리케이션을 만들기 위한 프레임워크

라이브러리: 개발자가 코드의 흐름을 제어하며 필요한 시점에서 호출하여 사용한다.
프레임워크: 개발자가 아닌 프레임워크가 애플리케이션의 흐름을 제어하며, 애플리케이션의 전반적인 구조를 제공하며 개발자는 정해진 구조 위에서 기능을 추가하게 된다. 

차이점

    • 설정과 구성
      • Spring Framework: Spring 애플리케이션을 설정하고 구성하는 데에 XML 기반 또는 주석 시반 설정으로 복잡한 부분이 있어 많은 시간이 소요된다.
      • Spring Boot: opinionated defaults 기법을 통해 기본 설정을 제공받아 설정을 자동화하여 개발자가 별도의 설정을 하지 않아도 바로 애플리케이션을 실행할 수 있게 해준다. 상대적으로 적은 시간이 소요된다.
    • 서버 설정
      • Spring Framework: 별도의 내장 서버를 포함하지 않기 때문에 개발자가 별도로 웹 서버를 설치하고 구성해야 한다.
      • Spring Boot: 내장 Tomcat, Jetty, Undertow 등의 서버를 제공하므로 웹 서버를 따로 설치하거나 구성할 필요가 없다.
    • 의존성 관리
      • Spring Framework: 개발자가 필요한 모든 라이브러리의 의존성을 수동으로 관리해야 한다.
      • Spring Boot: 스타터(starter)종속성을 제공하여, 프레임워크 자체에서 관련된 의존성 그룹을 자동으로 가지고 와서 설치해준다.
    • 프로젝트 배포
      • Spring Framework: WAR 파일로 패키지화하여 별도의 서버에 배포하여야 한다.
      • Spring Boot: JAR 파일로 패키지화하여 자체 내장 서버를 통해 쉽게 실행하고 배포할 수 있다. 
      • ( https://suhanlim.tistory.com/192 )배포 및 WAR, JAR 파일 설명 글
    • 개발 및 시장 출시 시간
      • Spring Framework: 설정, 의존성 관리 등으로 인해 개발 및 배포 시간이 상대적으로 길 수 있다.
      • Spring Boot: 자동 설정, 내장 서버, 스타터 종속성 등으로 인해 빠르게 애플리케이션을 개발하고 배포 할 수 있다.
    • SpringBoot에서 추가된 기능
      • Actuator: Spring Boot Actuator 애플리케이션의 상태를 모니터링하고 관리하는 기능을 제공한다. HTTP 엔드포인트나 JMX 통해 애플리케이션의 다양한 정보(: 메트릭, 헬스 체크, 환경 설정 ) 확인할 있다.
      • ( https://suhanlim.tistory.com/193 )사용 방법 정리 글
      • YAML: YAML형식의 설정 파일을 지원한다.

언제 사용해야 하는가?

  • Spring Framework: 복잡한 애플리케이션에 대해 많은 제어가 필요하거나 특정 설정을 최적화하려는 경우나, 학습 목적으로 Spring 내부 동작을 이해하려는 경우에 사용하는게 적합하다.
  • Spring Boot: 빠른 프로토타이핑이나 마이크로서비스 아키텍처와 같이 빠른 개발과 배포가 중요한 상황에서 적합하다. 설정의 복잡성을 최소화하고 빠르게 실행 가능한 애플리케이션을 만들 때 사용하면 좋다.

POJO (Plain Old Java Object)

POJO는 단순히 데이터를 나타내는 클래스이며 특정한 인터페이스를 구현하거나, 특정한 클래스를 상속받지 않는 단순한 클래스를 의미한다. 주로 필드, 메소드, 생성자 등을 포함할 수 있으며, 비즈니스 로직 처리 보다는 데이터를 저장하고 전달하는데 사용된다.
@Data
public class Medication {
    private String entpName;
    private String itemName;
    private String efcyQesitm;
    private String useMethodQesitm;
    private String atpnWarnQesitm;
    private String atpnQesitm;
    private String intrcQesitm;
    private String seQesitm;
    private String depositMethodQesitm;
    private String itemImage;
}

DTO (Data Transfer Object)

데이터 전송 객체(Data Transfer Object, DTO)는 계층간 데이터 교환을 위한 자바 Beans 이다.
DTO도 POJO의 한 형태로, 시스템 간 또는 계층 간의 데이터 전송을 위해 사용된다. 보통 DTO는 각 필드에 대한 getter/setter 메소드를 포함한다. DTO는 보통 계층 간의 데이터 전송을 목적으로 사용되며, 각 필드를 캡슐화하여 사용하는 POJO와 다소 차이가 있다.
여기서 계층이란 Controller, Service, DAO 등을 의미한다.
class Item {
    @JsonProperty("entpName")
    private String entpName;
    @JsonProperty("itemName")
    private String itemName;
    @JsonProperty("efcyQesitm")
    private String efcyQesitm;
    @JsonProperty("useMethodQesitm")
    private String useMethodQesitm;
    @JsonProperty("atpnWarnQesitm")
    private String atpnWarnQesitm;
    @JsonProperty("atpnQesitm")
    private String atpnQesitm;
    @JsonProperty("intrcQesitm")
    private String intrcQesitm;
    @JsonProperty("seQesitm")
    private String seQesitm;
    @JsonProperty("epositMethodQesitm")
    private String depositMethodQesitm;
    @JsonProperty("itemImage")
    private String itemImage;

    // getter and setter methods
    // ...
}
class Header {
    @JsonProperty("resultCode")
    private String resultCode;
    @JsonProperty("resultMsg")
    private String resultMsg;

    // getter and setter methods
    // ...
}
class Body {
    @JsonProperty("items")
    private List<Item> items;

}

public class ResponseDTO {
    @JsonProperty("header")
    private Header header;
    @JsonProperty("body")
    private Body body;

    // getter and setter methods
    // ...
}

 

+ DAO (Data Access Object)

데이터베이스에 접근하는 코드를 캡슐화하기 위한 설계 패턴

+ Recent posts