streetprogrammer

리눅스 배포시 스프링 스케줄러 중복실행 이슈 해결 본문

SERVER

리눅스 배포시 스프링 스케줄러 중복실행 이슈 해결

차완호미 2024. 5. 31. 14:15

이슈 : 리눅스 환경에서 war파일을 webapps아래에 놓고 tomcat 실행 -> 웹프로젝트내에 스케줄이 2번씩 실행됨 

 

문제점 : appBase아래에 있는 모든 웹프로젝트를 실행하는데 이때 /ROOT폴더의 웹프로젝트와 war파일이 압축해제되면서 생성된 웹프로젝트 내의 스케줄러가 동시에 돌아가면서 중복실행이됨 

 

해결방안  :

1.appBase에 하나의 프로젝트만 존재해야됨 ROOT 폴더 

2.appBase에는 웹프로젝트가 존재하지않고 <context path="/" >를 활용한 다른 경로의 웹프로젝트 수동배포

3. appBase에 하나의 웹프로젝트 존재하고 자동배포되지않게 server.xml 설정 그리고 <context path="/">로 해당 웹프로젝트 수동배포 진행  (수동으로 웹프로젝트를 배포하면서 해당 디렉터리에 변경이 발생하면 Tomcat이 이를 감지하고 자동으로 다시 배포하게 됩니다. 그렇기 때문에 autoDeploy도 false로 놔야함)

server.xml 설정
< Host name="localhost"  appBase="webapps"   unpackWARs="true" autoDeploy="false" deployOnStartup="false"  >  

 

이를 해결하기 위해 server.xml 관련 내용을 찾아봐서 해당 내용을 정리함 

 

< Host > 설정

* unpackWARs=""  옵션  (기본값 true)

 appBase에서 설정한 경로에 있는 war파일을 풀어 웹 디렉토리로 만듬

 

* autoDeploy="" 옵션  (기본값 true)

appBase에서 설정한 경로에있는 모든 웹 디렉토리가 변경됨에 따라 재배포시킴

추가로 war파일명이 바껴도 영향을 줌

 

* deployOnStartup="" 옵션  (기본값 true)

tomcat 실행시 배포여부를 설정함 true 일경우 appBase아래 모든 웹프로젝트를 배포, false일경우 배포하지않음

 

< Context>  설정

*  docBase =""  옵션

해당 경로에있는 웹 디렉토리나 WAR파일을 수동으로 배포시킴, WAR파일인 경우 ROOT폴더를 생성함

 

*  path ="" 옵션

서버가 수동 배포되었을때 해당 프로젝트에 접근하는 경로는 지정해줌 이때 "", "/" 로 설정할경우 ROOT폴더 역할을함 

해당경로에 war파일로 존재하는경우 ROOT폴더 역할을 할수없어 appBase안에 ROOT폴더가 생성됨 

 

( 추측 )  이슈 발생 시나리오  unpackWARs="true" autoDeploy="true" 인경우 

1. appBase안에있던 .war파일이 unpackWARs옵션에 의해 풀리게됨 

2. <Context>  옵션으로 수동배포 진행 path ="/" 조건이지만 docBase에 웹프로젝트가 아닌 war파일로 존재하기때문에 ROOT폴더 생성됨

3.  appBase안에있던 모든 웹프로젝트가 실행됨 -> 스케줄 중복실행 원인

 

 

<톰캣 실행시 전체 순서 정리>

  1. unpackWARs="true"에 의한 WAR 파일 풀기
    • 톰캣이 시작될 때, appBase 디렉터리 내에 있는 모든 WAR 파일이 풀려서 해당 웹 애플리케이션이 배포됩니다.
  2. appBase 디렉터리 내에 있는 웹 애플리케이션 시작
    • 톰캣이 시작될 때, appBase 디렉터리 내에 있는 모든 웹 애플리케이션이 시작됩니다. 이는 WAR 파일이 풀려서 배포된 애플리케이션이 포함될 수 있으며, unpackWARs="true" 옵션을 통해 풀리지 않은 디렉터리 구조의 애플리케이션도 포함됩니다.
  3. <Context> 에 의한 수동배포 진행
    • 수동으로 배포된 웹 애플리케이션은 톰캣 시작시에 자동으로 시작되지 않으므로, 이 단계에서 해당 수동 배포된 애플리케이션이 배포되고 시작됩니다.
  4. 루트 컨텍스트 설정에 의한 ROOT 애플리케이션 재정의:
    • 설정 파일에 <Context> 요소를 사용하여 루트 컨텍스트를 재정의한 경우, 이전에 자동으로 배포된 ROOT 애플리케이션을 덮어씁니다. 새로운 <Context> 설정에 따라 배포됩니다. 이때, 톰캣이 시작될 때 설정 파일에 정의된 컨텍스트가 자동으로 배포된 애플리케이션보다 우선시됩니다.

 

* 추가정보

일반적으로 context 요소의 path가 "" 또는 /로 설정되고 docBase 위치에 WAR 파일이 있으면, 해당 WAR 파일이 ROOT 애플리케이션으로 배포됩니다. 이때 appBase 디렉토리에 ROOT라는 이름의 폴더가 생성됩니다. -> "unpackWARs" 옵션 단계에서 실행됨

 

중복된 <Context> 설정: 예를 들어, A.war 파일이 appBase 디렉터리에 존재하고, conf/server.xml 파일이 동일한 docBase를 가리키는 경우. tomcat 시작시 자동배포와 docBase의 수동 배포가 중복되어 스케줄이 2개실행됨 

 

deployOnStartup="false" 옵션 : 톰캣 실행시 deploy = false함 기본값은 true . => false인경우 자동배포 안하게되고 <context> 로 인해 수동배포만 진행함.

 

 

 

결론 : 현재 프로젝트 상황기준 appBase아래에 웹프로젝트 하나만 ROOT컨텍스트로 실행하고자 하기때문에

 

1. ROOT폴더가 만들어지면안됨 -> server.xml < Context path="/" docBase="webprojectName_ver2 " reloadable="true" > 사용하고 해당 위치의 프로젝트가 war가 아닌 폴더형태여야함 

 

2. appBase에 있는 프로젝트는 톰캣 실행시 자동배포되며 , <docBase="webprojectName_ver2 ">에 의해  수동배포가 됨 그래서 중복이생길수있으니 자동배포되지 않게 설정해야함

< Host name="localhost"  appBase="webapps"   unpackWARs="true" autoDeploy="false" deployOnStartup="false" >  

 

Comments