티스토리 뷰

 서버가  비정상  상태일 경우 팀즈로 알람을 받아서 조치 하도록 운영을 하고 있는데,  매시간 서버 재기동 하는게 불편해서 비정상 상태일 경우 서버를 재시작 하도록 자동화 하려고 함. 

jsch 를 라이브러리 사용 - ssh 연결해줌 최신버전 0.1.55 버전이 이상하지만 고고

  implementation 'com.jcraft:jsch:0.1.55'

 

ssh 설정 -  프로퍼티는 알아서 지정  연결할 host port username pw 넣어주면됨

@Configuration
public class SshCommandConfig {

  @Value("${ssh.tunnel.host}")
  private String sshHost;

  @Value("${ssh.tunnel.port}")
  private int sshPort;

  @Value("${ssh.tunnel.username}")
  private String sshUser;

  @Value("${ssh.tunnel.password}")
  private String sshPassword;

  // SSH 연결 메서드
  @Bean
  public Session sshSession() throws Exception {
    JSch jsch = new JSch();
    Session session = jsch.getSession(sshUser, sshHost, sshPort);
    session.setPassword(sshPassword);
    session.setConfig("StrictHostKeyChecking", "no"); 
    session.connect();
    return session;
  }

  // 리눅스 명령어 실행 메서드
  public String executeCommand(Session session, String command) throws Exception {
    ChannelExec channelExec = (ChannelExec) session.openChannel("exec");
    InputStream in = channelExec.getInputStream();
    channelExec.setCommand(command);
    channelExec.connect();

    StringBuilder outputBuffer = new StringBuilder();
    int readByte = in.read();
    while (readByte != -1) {
      outputBuffer.append((char) readByte);
      readByte = in.read();
    }
    channelExec.disconnect();
    return outputBuffer.toString();
  }

 

ssh 로 세션 연결해서 경로 이동해서 서버 재시작 하는 로직  - restart 보다는 stop 엔 start 로 함

@Slf4j
@AllArgsConstructor
@Component
public class WebhookFailAlertStepConfig {

  private final TeamsWebhookApiUtil teamsWebhookApiUtil;

  Gson gson = new Gson();

  private final SshCommandConfig sshCommandConfig;

  public Tasklet webhookFailAlertBatchTaslket() {
    return (contribution, chunkContext) -> {
      RestTemplate restTemplate = new RestTemplate();
      String healthCheckUrl = "";
      HttpEntity<String> requestEntity = new HttpEntity<>("", new HttpHeaders());
      
      try {
        ResponseEntity<String> response = restTemplate.postForEntity(healthCheckUrl, requestEntity, String.class);
        String responseBody = response.getBody();
        if(!responseBody.equals("success")){
          sendWebhookError(responseBody);
        }
      } catch (Exception e) {
        sendWebhookError(e.toString());
      }
      return RepeatStatus.FINISHED;
    };
  }

  private void sendWebhookError(String responseBody){
      /*
      * 알람 로직 
      */

      /**
       *  서버 재시작 로직 실행
       */
      try{
        Session session = sshCommandConfig.sshSession();

        String changeDirectory = "/어쩌구";

        String stopCommand = "stop 어쩌구";
        sshCommandConfig.executeCommand(session, changeDirectory + stopCommand);

        // 15초간 기다림
        Thread.sleep(15000);

        String startCommand = "start 어쩌구"
        sshCommandConfig.executeCommand(session, changeDirectory + startCommand);
      } catch(Exception e){
        log.error("서버 재시작 로직 중 에러 발생... {} " , e);
      }
    }
  }

테스트완료 잘됨. 

하지만 실제로 왜 서버가 비정상 상태가 되는지 확인이 우선


Heap dump 확인 해본 결과 쓰레드 문제로 예상됨. 

Spring boot thread 설정을 변경하여 모니터링 해보자

server:
  port: 
  tomcat:
    threads:
      max: 200 # 생성할 수 있는 thread의 총 개수
      min-spare: 50 # 항상 활성화 되어있는(idle) thread의 개수
    max-connections: 8192 # 수립가능한 connection의 총 개수
    connection-timeout: 20000 # timeout 판단 기준 시간, 20초

'Backend > Spring & Spring Boot' 카테고리의 다른 글

JVM 설정 변경  (0) 2024.10.25
Spring batch 처리  (0) 2023.12.11
Spring Boot API 테스트 코드 구현  (0) 2023.07.04
Spring Boot 테스트 개념 정리  (0) 2023.07.04