1.war업데이트 스케쥴러 추가.
2.수동 실행, 로그 확인을 위한 뷰페이지 추가
master
Kurt92 5 months ago
parent 16553744c9
commit 69effe43c9

@ -12,7 +12,13 @@ jdk는 17버전</br>
기존 돌고있는 서비스의 영향을 주지 않기 위해 서버 시스템 환경변수는 그대로 둔다</br>
아래 명령어처럼 다운로드한 jdk 경로를 명시적으로 하여 실행하도록 한다.
& "C:\Program Files\Eclipse Adoptium\jdk-17.0.15.6-hotspot\bin\java.exe" -jar "C:\Users\Administrator\Desktop\clean-parking-worker-0.0.1-SNAPSHOT.jar" --spring.profiles.active
& "C:\Program Files\Eclipse Adoptium\jdk-17.0.15.6-hotspot\bin\java.exe" -jar "C:\Users\Administrator\Desktop\clean-parking-worker-0.0.1-SNAPSHOT.jar" --spring.profiles.active=local
<br>
<br>
start "" "C:\Program Files\Eclipse Adoptium\jdk-17.0.15.6-hotspot\bin\java.exe" -jar "C:\Users\Administrator\Desktop\clean-parking-worker-0.0.1-SNAPSHOT.jar" --spring.profiles.active=local >> "C:\logs\worker.log" 2>&1
- 자바 경로 , 배포할 jar파일 경로, 실행시 적용시킬 프로파일 순서이다.
- 해당 실행은 스크립트를 통해 만들 예정이며, 이후 스크립트 더블클릭으로 재실행 할수 있도록 한다.
- start를 붙이면 백그라운드로 실행 가능하다 (윈도우)
- 대신 로그를 볼려면 실행로그파일을 따로 지정해줘야 된다.

@ -0,0 +1,34 @@
package com.manual.controller;
import com.worker.scheduler.smg.schedule.SinmungoInOutScheduler;
import com.worker.scheduler.update.schedule.WarSyncScheduler;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.IOException;
@RestController
@RequiredArgsConstructor
public class RunController {
private final WarSyncScheduler warSyncScheduler;
private final SinmungoInOutScheduler sinmungoInOutScheduler;
@PostMapping("/menual/update-war")
public ResponseEntity<?> updateWar() throws IOException {
warSyncScheduler.checkAndDeploy();
return ResponseEntity.ok("Success");
}
@PostMapping("/menual/sinmungo-polling")
public ResponseEntity<?> sinmungoPolling() throws IOException {
sinmungoInOutScheduler.sinmungoAnswerSendScheduler();
return ResponseEntity.ok("Success");
}
}

@ -0,0 +1,16 @@
package com.manual.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class ViewController {
@GetMapping("/")
public String home() {
return "home";
}
}

@ -4,7 +4,7 @@ import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
@SpringBootApplication
@SpringBootApplication(scanBasePackages = {"com.worker", "com.manual"})
@EnableScheduling
public class CleanParkingWorkerApplication {

@ -33,7 +33,7 @@ public class SinmungoInOutScheduler {
// esb에이전트 xml파일 읽기
/** esb에이전트 xml파일 읽기 */
@Scheduled(fixedRate = 10 * 60 * 1000) // 10분
public void sinmungoInOutScheduler() throws IOException {
try{

@ -22,34 +22,29 @@ public class WarSyncScheduler {
private final int SFTP_PORT = 1922;
private final String SFTP_USER = "cc-war";
private final String SFTP_PASS = "xit5811807!";
// private final String REMOTE_CC_WAR_PATH = "D:\\prod-cc\\deploy\\clean-parking-boot.war";
private final String REMOTE_CC_WAR_PATH = "/deploy/clean-parking-boot.war";
// 동적 드라이브 감지
private Path resolveBasePath() {
if (!isWindows) return Paths.get("/opt/prod-cc");
// 경로 설정
private final Path LOCAL_WAR_PATH = isWindows
? Paths.get("D://prod-cc/deploy/clean-parking-boot.war")
: Paths.get("/opt/prod-cc/deploy/clean-parking-boot.war");
private final Path LOCAL_TMP_PATH = isWindows
? Paths.get("D://prod-cc/tmp/clean-parking-boot.war")
: Paths.get("/opt/prod-cc/tmp/clean-parking-boot.war");
private final Path LoCAL_BACKUP_PATH = isWindows
? Paths.get("D://prod-cc/backup/clean-parking-boot.war")
: Paths.get("/opt/prod-cc/backup/clean-parking-boot.war");
private final Path META_FILE_PATH = isWindows
? Paths.get("D://prod-cc/meta/clean-parking.war.meta")
: Paths.get("/opt/prod-cc/meta/clean-parking.war.meta");
String[] drives = {"C:", "D:", "E:"};
for (String drive : drives) {
Path base = Paths.get(drive, "prod-cc");
if (Files.exists(base)) return base;
}
throw new RuntimeException("[배포] prod-cc 디렉터리를 찾을 수 없습니다.");
}
private final Path PID_FILE_PATH = isWindows
? Paths.get("D://prod-cc/deploy/clean-parking.pid")
: Paths.get("/opt/prod-cc/deploy/clean-parking.pid");
private final Path BASE_PATH = resolveBasePath();
private final File LOG_FILE = isWindows
? new File("D://prod-cc/logs/clean-parking.log")
: new File("/opt/prod-cc/logs/clean-parking.log");
// 경로 정의
private final Path LOCAL_WAR_PATH = BASE_PATH.resolve("deploy/clean-parking-boot.war");
private final Path LOCAL_TMP_PATH = BASE_PATH.resolve("tmp/clean-parking-boot.war");
private final Path LOCAL_BACKUP_PATH = BASE_PATH.resolve("backup/clean-parking-boot.war");
private final Path META_FILE_PATH = BASE_PATH.resolve("meta/clean-parking.war.meta");
private final Path PID_FILE_PATH = BASE_PATH.resolve("deploy/clean-parking.pid");
private final File LOG_FILE = BASE_PATH.resolve("logs/clean-parking.log").toFile();
@Scheduled(fixedRate = 5 * 60 * 1000) // 5분
// @Scheduled(cron = "0 0 2 * * *") // 매일 새벽 2시
@ -71,6 +66,7 @@ public class WarSyncScheduler {
sftp = (ChannelSftp) session.openChannel("sftp");
sftp.connect();
log.info("[배포] SFTP 업테이트 서버 연결 성공");
// 리모트 파일 속성
SftpATTRS attrs = sftp.lstat(REMOTE_CC_WAR_PATH);
@ -79,6 +75,7 @@ public class WarSyncScheduler {
// 메타파일 비교
boolean isUpdated = isWarUpdated(remoteSize, remoteMtime);
log.info("[배포] 변경감지");
if (!isUpdated) {
log.info("[배포] 변경 없음. 스킵");
@ -93,6 +90,7 @@ public class WarSyncScheduler {
// 실행 중이면 종료
killPreviousWar();
log.info("[배포] 프로세스 kill");
// 교체
Files.move(LOCAL_TMP_PATH, LOCAL_WAR_PATH, StandardCopyOption.REPLACE_EXISTING);

File diff suppressed because it is too large Load Diff

@ -0,0 +1,66 @@
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>스케쥴러 제어</title>
</head>
<body>
<h1>📅 CleanParking 스케쥴러 수동 실행</h1>
<label for="task">실행할 스케쥴러 선택:</label>
<select id="task">
<option value="warSync">Get War File from Update Server</option>
<option value="sinmungoPolling">Sinmungo Xml DB Polling</option>
<!-- 필요한 스케쥴러 추가 -->
</select>
<button id="runSchedulerBtn">스케줄러 실행</button>
<hr>
<a href="/manual/logs">🪵 로그 보기</a>
</body>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"/>
<!--<script type="text/javascript" src="/lib/jquery.js"></script>-->
<script>
const fn = {
init: () => {
},
onEventListener: () => {
$('#runSchedulerBtn').on('click', function () {
const taskName = $('#task').val();
$.ajax({
url: '/manual/run',
method: 'POST',
data: { task: taskName },
success: function (res) {
alert('실행 완료: ' + res);
},
error: function (xhr, status, err) {
alert('실패: ' + err);
}
});
});
}
}
$(document).ready(function(){
fn.onEventListener();
});
</script>
</html>
Loading…
Cancel
Save