springboot + tomcat + svelte + mysql 배포

최경현·2024년 7월 5일

프로젝트를 진행하면서 간단한 쇼핑몰을 배포하였다.
배포는 카페24를 통해 간단하게 하였다.
카페24 에서는 tomcat JSP 호스팅을 사용하였다.
처음에는 postgreSQL을 사용하여 db관리를 하였는데, 카페24는 postgreSQL을 지원해주지 않아서 mySQL로 마이그레이션하였다.

svelte project 정적 build하는 방법은 알아서 찾아보길 바란다. 자료가 꽤 있다.

svelte로 만든 프론트엔드는 정적파일로 build한 후에 springboot project의 resource/static안에 배치하였다.

정적파일로 프론트엔드를 build한 후에 생기는 index.html이 핵심이다.

forward와 redirect의 차이

이걸 알기전에 forward와 redirect의 차이를 알아야한다.

Forward:
내부 요청 전달.
URL 변경 없음.
동일한 요청-응답 사이클.
클라이언트는 URL 변경을 인지하지 못함.

서버 내부에서 요청을 다른 쪽으로 전달해야하거나 요청 데이터를 유지해야할 때 사용한다.
ex) 폼데이터를 다음 페이지로 전달
즉, 내부 자원 간의 요청을 처리할 때 사용

Redirect:
클라이언트에게 새로운 요청 지시.
URL 변경.
두 개의 요청-응답 사이클.
클라이언트는 새로운 URL로 리다이렉트됨.

클라이언트가 새로운 URL을 요청하도록 해야할 때나 URL 변경이 필요할 때 사용한다.
ex) 로그인 후 사용자를 홈페이지로 리다이렉트
즉, 클라이언트에게 새로운 URL로 이동하도록 할 때 사용

스프링부트 프로젝트의 MvcConfig에서 ViewControllerRegistry를 사용하여 특정 경로로 들어오는 요청을 모두 index.html로 포워딩하도록 설정하였다.
이유는 SPA(Single Page Application)의 라우팅 문제를 해결하기 위해서이다.

이를 해결하기 위해 클라이언트 측 경로 요청을 index.html로 포워딩하여 SPA의 라우터가 올바르게 경로를 처리하도록 설정하였다.

spa란?

SPA는 하나의 HTML 페이지를 로드하고, JavaScript를 사용하여 페이지의 내용을 동적으로 업데이트하는 웹 애플리케이션

사용 이유는?

SPA는 클라이언트 측 라우팅을 사용하여 다양한 URL 경로를 처리. 그러나 서버는 이러한 경로를 인식하지 못하고 404 Not Found 오류를 반환할 수 있음.

 @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {

        String path = uploadDir;

        registry.addResourceHandler("/**")
                .addResourceLocations("classpath:/static/")
                .setCacheControl(CacheControl.maxAge(10, TimeUnit.MINUTES));

MvcConfig에 선언해주었는데, 스프링부트 애플리케이션에서 정적 리소스를 효율적으로 관리하고 제공하고, 애플리케이션에서 정적 리소스를 제공하는 방법을 세밀하게 제어하고, 클라이언트 측 성능을 최적화하기 위해 선언하였다.

http://yourdomain/index.html 요청 시 src/main/resources/static/index.html 파일을 반환.

spring:
  mvc:
    static-path-pattern: /static/**
  web:
    resources:
      static-locations: classpath:/static/

스프링 부트 애플리케이션에서 정적 리소스의 경로를 설정하고 관리하기 위해서 application.yml에 선언하였다.

예를 들어, src/main/resources/static/ 디렉토리에 index.html 파일이 있다고 가정해보자.
설정 적용 전: 기본 설정으로는 http://yourdomain/index.html로 접근할 수 있다.
설정 적용 후: 설정을 적용하면 http://yourdomain/static/index.html로 접근할 수 있다.

tomcat 배포

tomcat을 사용하기 위해 build.gradle에 선언

providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'

public class Main extends SpringBootServletInitializer {

    public static void main(String[] args) {
        SpringApplication.run(Main.class ,args);
    }

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(Main.class);
    }

tomcat 배포를 하기 위해서 SpringBootServletInitializer 확장.
이를 통해 Spring Boot 애플리케이션을 독립 실행형 애플리케이션으로 실행할 수도 있고, WAR 파일로 패키징하여 서블릿 컨테이너에서 실행할 수도 있다.

war와 bootWar의 차이

WAR: 전통적인 Java 웹 애플리케이션 아카이브로, 서블릿 컨테이너 또는 애플리케이션 서버에서 실행.
BootWar: Spring Boot의 특수한 WAR 파일로, 내장 서블릿 컨테이너를 포함하여 실행 가능하며, 외부 서블릿 컨테이너에서도 실행될 수 있다.

build.gredle에서

bootWar {
    archiveFileName = 'ROOT.war'
}

bootWar를 선언해주었다. 이름을 ROOT.war라고 선언하였는데, ROOT.war라고 이름을 설정하는 이유는 Tomcat이 이를 기본 웹 애플리케이션으로 인식하고, / 경로로 매핑하기 위함

예를 들어, myapp.war라는 이름의 WAR 파일은 기본적으로 /myapp 경로로 매핑
ROOT.war 파일을 webapps 디렉토리에 배치하면, Tomcat은 이 파일을 기본 웹 애플리케이션으로 인식하고 루트 경로(/)로 매핑.


.

참고로 나는 svelte프로젝트를 정적파일로 build하고 index.html 포워딩 문제때문에 400, 403error를 자주봤다.
위에 적은 방법들은 내가 배포를 진행하면서 겪었던 문제들을 해결하기 위해 했던 방법들이다.

아 참고로 메모리 부족 에러가 뜰 가능성이 농후하니 Catalina.sh에서

JAVA_OPTS="$JAVA_OPTS -Xms1024m -Xmx2048m -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=1024m"

를 추가해주는게 좋음

profile
ㅇㅇ

0개의 댓글