▶️배경
현재 CloudPlatform Service를 만들고있는데, 주요 서버는 두개가 있다.
- User Data Control Server (Spring Boot)
- System Operation Management Server (Go Lang)
Client -> UDCS (Proxy Server) -> SOMS 형식으로 통신하게된다.
UDCS 서버에서는 로그인 및 회원가입과 같은 인증 및 인가, 그리고 로깅을 담당한다.
즉 Client가 아래 처럼 request와 accessToekn이 포함된 헤더가 있다면 이 정보를 이용하여 SOMS 서버에 똑같이 요청을한다(Proxy 역할)
{
"dest": "/vm/create",
"method": "POST",
"data": "{ blah blah }"
}
이런 형식으로 SOMS에 요청하게 되고, 아래와 같은 로그를 남긴다. 요청하기전에 ENROLL ,응답이오면 END 로그를 생성하게된다.
private void logEnroll(RequestDto requestDto, String transactionId,String remoteAddr) {
log.info("Type = {}, Dest = {}, Method = {}, Data = {}, Time = {}, IP = {}, Transaction_Id = {}",
TransactionType.ENROLL,
requestDto.getDest(),
requestDto.getMethod(),
requestDto.getData(),
LocalDateTime.now(),
remoteAddr,
transactionId);
}
private void logEnd(String targetTransactionId,String transactionId) {
log.info("Type = {}, Target_Transaction_Id = {}, Time = {}, Transaction_Id = {}",
TransactionType.END,
targetTransactionId,
LocalDateTime.now(),
transactionId);
}
▶️상황
만약 SOMS와 통신중 비정상적으로 스프링 서버(UDCS)가 종료되었을 때는 어떻게해야할까?
예를들어, 클라이언트가 vm create 를 요청하였으며 SOMS에 해당 요청까지 전달되었는데 스프링 서버가 비정상적으로 종료되었다면 응답과 상관없이 END 로그가 찍히지 않을 것이다.
정상 FLOW : ENROLL → SOMS Forwarding → 응답 → END
Failed Case
- ENROLL → SOMS Forwarding → 작업 정상 수행 → 스프링 서버 비정상적인 종료 → (NOT END LOG)
- ENROLL → SOMS Forwarding → 작업 비정상 수행 → 스프링 서버 비정상적인 종료 → (NOT END LOG)
- ENROLL → SOMS Forwarding → 스프링 서버 비정상적인 종료 → (NOT END LOG)
- ENROLL → 스프링 서버 비정상적인 종료 → (NOT END LOG, NOT forwarding SOMS)
따라서 이 경우의 Integrity Check가 필요하다.
▶️해결방법
현재 환경
ELK 를 통해 로그정보를 확인하고있으며 서버 내에 file로도 저장하고있다.
스프링이 재시작될 때 Integrity Check
@PostConstruct
public void integrityCheck(){
1. 최신 로그를 찾는다.
2. 뒤에서부터 END가 나오지않았는데 ENROLL 만 있는 경우를 탐색한다.
3. 해당 ENROLL LOG를 보고 작업을 재수행한다.
}
애플리케이션 시작 시 최근 로그를 조회하고, ENROLL만 있는 로그를 찾는다. 해당 ENROLL 로그를 기반으로 작업을 다시 수행하고, 작업의 상태에 따라 로그를 기록한다. 이를 통해 스프링 서버가 비정상적으로 종료되었을 때의 Integrity Check를 수행할 수 있다. 시스템의 안정성과 일관성을 유지할 수 있게된다.