2 Commits

Author SHA1 Message Date
Rinjae 8a884e53e3 ci - readiness probe port 39120 으로 정정
eapim-admin CI / build (push) Has been cancelled
- DEPLOY_HTTP_PORT 30120 → 39120 (실서버 tomcat 포트)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-16 16:30:13 +09:00
Rinjae 7de00ecad2 ci - readiness probe 안정화
eapim-admin CI / build (push) Has been cancelled
- probe URL 변경: login.do(POST) → loginForm.do(GET)
- timeout 180s → 300s (200MB war 첫 explode 시간 확보)
- 실패 시 catalina 로그 300줄 + systemd status + 포트 출력

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-16 16:22:07 +09:00
5 changed files with 21 additions and 69 deletions
+15 -7
View File
@@ -17,7 +17,7 @@ jobs:
CATALINA_BASE: /prod/eapim/adminportal CATALINA_BASE: /prod/eapim/adminportal
CATALINA_HOME: /prod/eapim/apache-tomcat-9.0.116 CATALINA_HOME: /prod/eapim/apache-tomcat-9.0.116
CATALINA_PID: /prod/eapim/adminportal/temp/catalina.pid CATALINA_PID: /prod/eapim/adminportal/temp/catalina.pid
DEPLOY_HTTP_PORT: "30120" DEPLOY_HTTP_PORT: "39120"
defaults: defaults:
run: run:
working-directory: eapim-admin working-directory: eapim-admin
@@ -89,7 +89,7 @@ jobs:
cp eapim-admin/build/libs/eapim-admin.war "$DEPLOY_DIR/monitoring.war" cp eapim-admin/build/libs/eapim-admin.war "$DEPLOY_DIR/monitoring.war"
ls -la "$DEPLOY_DIR" ls -la "$DEPLOY_DIR"
- name: Start tomcat and readiness probe (timeout 180s) - name: Start tomcat and readiness probe (timeout 300s)
working-directory: ${{ github.workspace }} working-directory: ${{ github.workspace }}
run: | run: |
LOG="$CATALINA_BASE/logs/catalina.$(date +%Y-%m-%d).log" LOG="$CATALINA_BASE/logs/catalina.$(date +%Y-%m-%d).log"
@@ -99,14 +99,17 @@ jobs:
# systemd 가 Tomcat 을 새 cgroup 으로 띄움 — runner step 종료와 무관하게 살아남음 # systemd 가 Tomcat 을 새 cgroup 으로 띄움 — runner step 종료와 무관하게 살아남음
systemctl --user start eapim-admin systemctl --user start eapim-admin
DEADLINE=$(($(date +%s) + 180)) # /loginForm.do 는 GET 매핑(MainController#loginForm) → tomcat·webapp 양쪽 살아있으면 200
# /login.do 는 POST 처리 — GET 으로 probe 시 405/잘못된 응답 가능성 있어 회피
PROBE_URL="http://localhost:$DEPLOY_HTTP_PORT/monitoring/loginForm.do"
DEADLINE=$(($(date +%s) + 300))
STATUS=000 STATUS=000
while [ $(date +%s) -lt $DEADLINE ]; do while [ $(date +%s) -lt $DEADLINE ]; do
STATUS=$(curl -sS -o /dev/null -w '%{http_code}' --max-time 3 \ STATUS=$(curl -sS -o /dev/null -w '%{http_code}' --max-time 3 \
"http://localhost:$DEPLOY_HTTP_PORT/monitoring/login.do" 2>/dev/null || echo "000") "$PROBE_URL" 2>/dev/null || echo "000")
case "$STATUS" in case "$STATUS" in
200|302|401) 200|302|401)
echo "Readiness OK (/monitoring/login.do HTTP $STATUS)" echo "Readiness OK ($PROBE_URL HTTP $STATUS)"
break break
;; ;;
esac esac
@@ -122,8 +125,13 @@ jobs:
case "$STATUS" in case "$STATUS" in
200|302|401) ;; 200|302|401) ;;
*) *)
echo "::error::Readiness probe failed within 180s (last HTTP status: $STATUS)" echo "::error::Readiness probe failed within 300s (last HTTP status: $STATUS)"
[ -f "$LOG" ] && tail -c +$((BEFORE+1)) "$LOG" | tail -100 echo "--- last 300 lines of catalina log ---"
[ -f "$LOG" ] && tail -c +$((BEFORE+1)) "$LOG" | tail -300
echo "--- systemd unit status ---"
systemctl --user status eapim-admin --no-pager || true
echo "--- listening ports ---"
ss -tlnp 2>/dev/null | grep -E ":$DEPLOY_HTTP_PORT\b" || echo "(port $DEPLOY_HTTP_PORT 미점유)"
exit 1 exit 1
;; ;;
esac esac
@@ -39,10 +39,11 @@ public interface ApiStatusRepository extends BaseRepository<ApiStatus, String> {
+ " FROM (" + " FROM ("
+ " SELECT A.EAISVCNAME" + " SELECT A.EAISVCNAME"
+ " , NVL(B.STATUS_CODE, 'N') AS STATUS_CODE" + " , NVL(B.STATUS_CODE, 'N') AS STATUS_CODE"
+ " , NVL(( SELECT MAX('Y') FROM EMSAPP.DJB_APISTATUS_INCIDENT_API X" //TODO: 게시판 임시로 생성하여 사용. 유차장이 완료하면 변경할것
+ " WHERE EXISTS (SELECT 1 FROM EMSAPP.DJB_APISTATUS_INCIDENT Y WHERE X.INCIDENT_ID = Y.INCIDENT_ID " + " , NVL(( SELECT 'Y' FROM PTL_NOTICE_API X "
+ " AND SYSTIMESTAMP BETWEEN STARTED_AT AND END_AT) " + " WHERE EXISTS (SELECT 1 FROM EMSAPP.PTL_NOTICE Y WHERE X.NOTICE_ID = Y.ID)"
+ " AND A.EAISVCNAME = X.API_ID),'N') AS CTRL_YN " //+ " AND TO_CHAR(SYSDATE, 'YYYYMMDDHH24MI') BETWEEN START_TIME AND END_TIME) "
+ " AND A.EAISVCNAME = X.API_NAME),'N') AS CTRL_YN "
+ " , (SELECT CASE WHEN TOTAL = 0 THEN 'X'" + " , (SELECT CASE WHEN TOTAL = 0 THEN 'X'"
+ " WHEN (TOTAL - SUCCESS) * 100 / TOTAL > :errorRate THEN 'Y'" + " WHEN (TOTAL - SUCCESS) * 100 / TOTAL > :errorRate THEN 'Y'"
+ " ELSE 'N' END" + " ELSE 'N' END"
@@ -1,9 +1,6 @@
package com.eactive.eai.rms.ext.djb.job; package com.eactive.eai.rms.ext.djb.job;
import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.Set;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.quartz.DisallowConcurrentExecution; import org.quartz.DisallowConcurrentExecution;
@@ -71,24 +68,10 @@ public class ApiStatusMonitorJob implements Job {
@Override @Override
public void execute(JobExecutionContext context) throws JobExecutionException { public void execute(JobExecutionContext context) throws JobExecutionException {
JobDataMap jobDataMap = context.getJobDetail().getJobDataMap();
// execute.instances 가 지정된 경우 해당 인스턴스에서만 실행
String allowedInstances = jobDataMap.getString("execute.instances");
if (StringUtils.isNotEmpty(allowedInstances)) {
Set<String> instanceSet = Arrays.stream(allowedInstances.split(","))
.map(s -> s.trim().toLowerCase())
.collect(Collectors.toSet());
String currentInstance = StringUtils.defaultString(System.getProperty("inst.Name")).trim().toLowerCase();
if (!instanceSet.contains(currentInstance)) {
log.debug("Job 실행 인스턴스 제한 - 현재: {}, 허용: {}", currentInstance, allowedInstances);
return;
}
}
log.info("*** START ApiStatusUpdateJob run({})", CommonUtil.getToday("yyyy-MM-dd HH:mm")); log.info("*** START ApiStatusUpdateJob run({})", CommonUtil.getToday("yyyy-MM-dd HH:mm"));
// Job 파라미터 로깅 // Job 파라미터 로깅
JobDataMap jobDataMap = context.getJobDetail().getJobDataMap();
logJobParameters(jobDataMap); logJobParameters(jobDataMap);
HashMap<String, String> param = this.checkParameters(jobDataMap); HashMap<String, String> param = this.checkParameters(jobDataMap);
@@ -1,12 +1,8 @@
package com.eactive.eai.rms.ext.djb.job; package com.eactive.eai.rms.ext.djb.job;
import java.util.Arrays;
import java.util.Date; import java.util.Date;
import java.util.Set;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
import org.quartz.DisallowConcurrentExecution; import org.quartz.DisallowConcurrentExecution;
import org.quartz.Job; import org.quartz.Job;
import org.quartz.JobDataMap; import org.quartz.JobDataMap;
@@ -52,21 +48,6 @@ public class InflowTokenMonitorJob implements Job {
@Override @Override
public void execute(JobExecutionContext context) throws JobExecutionException { public void execute(JobExecutionContext context) throws JobExecutionException {
JobDataMap jobDataMap = context.getJobDetail().getJobDataMap();
// execute.instances 가 지정된 경우 해당 인스턴스에서만 실행
String allowedInstances = jobDataMap.getString("execute.instances");
if (StringUtils.isNotEmpty(allowedInstances)) {
Set<String> instanceSet = Arrays.stream(allowedInstances.split(","))
.map(s -> s.trim().toLowerCase())
.collect(Collectors.toSet());
String currentInstance = StringUtils.defaultString(System.getProperty("inst.Name")).trim().toLowerCase();
if (!instanceSet.contains(currentInstance)) {
log.debug("Job 실행 인스턴스 제한 - 현재: {}, 허용: {}", currentInstance, allowedInstances);
return;
}
}
log.info("*** START InflowTokenFailMonitorJob run({})", CommonUtil.getToday("yyyy-MM-dd HH:mm")); log.info("*** START InflowTokenFailMonitorJob run({})", CommonUtil.getToday("yyyy-MM-dd HH:mm"));
long execMinute = 1; //default 배치 실행주기(분) long execMinute = 1; //default 배치 실행주기(분)
@@ -5,20 +5,14 @@ import com.eactive.eai.rms.common.datasource.DataSourceTypeManager;
import com.eactive.eai.rms.common.util.CommonUtil; import com.eactive.eai.rms.common.util.CommonUtil;
import com.eactive.eai.rms.onl.apim.portalInquiry.PortalInquiryClosingService; import com.eactive.eai.rms.onl.apim.portalInquiry.PortalInquiryClosingService;
import com.eactive.eai.rms.onl.common.util.DateUtil; import com.eactive.eai.rms.onl.common.util.DateUtil;
import org.apache.commons.lang3.StringUtils;
import org.quartz.DisallowConcurrentExecution; import org.quartz.DisallowConcurrentExecution;
import org.quartz.Job; import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext; import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException; import org.quartz.JobExecutionException;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import java.util.Arrays;
import java.util.Set;
import java.util.stream.Collectors;
/** /**
* 매일 00:05 실행 - RESPONDED 상태 문의글 자동 종료 배치 * 매일 00:05 실행 - RESPONDED 상태 문의글 자동 종료 배치
* *
@@ -50,21 +44,6 @@ public class PortalInquiryClosingJob implements Job {
@Override @Override
public void execute(JobExecutionContext context) throws JobExecutionException { public void execute(JobExecutionContext context) throws JobExecutionException {
JobDataMap jobDataMap = context.getJobDetail().getJobDataMap();
// execute.instances 가 지정된 경우 해당 인스턴스에서만 실행
String allowedInstances = jobDataMap.getString("execute.instances");
if (StringUtils.isNotEmpty(allowedInstances)) {
Set<String> instanceSet = Arrays.stream(allowedInstances.split(","))
.map(s -> s.trim().toLowerCase())
.collect(Collectors.toSet());
String currentInstance = StringUtils.defaultString(System.getProperty("inst.Name")).trim().toLowerCase();
if (!instanceSet.contains(currentInstance)) {
log.debug("Job 실행 인스턴스 제한 - 현재: {}, 허용: {}", currentInstance, allowedInstances);
return;
}
}
log.info("*** START PortalInquiryCommentClosingService run({})", CommonUtil.getToday("yyyy-MM-dd HH:mm")); log.info("*** START PortalInquiryCommentClosingService run({})", CommonUtil.getToday("yyyy-MM-dd HH:mm"));
int closingDays = DEFAULT_CLOSING_DAYS; int closingDays = DEFAULT_CLOSING_DAYS;