본문 바로가기

개발일지/TIL

[230819] Jmeter SSE 테스트 데이터 전송 받지 못하는 문제

테스트 시 SSE 데이터 전송받지 못하는 문제

💬 Jmeter에서 SSE 테스트 스크립트가 정상적으로 데이터를 받지 못하는 문제가 발생했습니다. 테스트를 진행하기 위해 이 문제를 해결해야 했습니다.

 

✔ 원인 분석

💬 원인을 알아보기 위해 연결, 종료, 데이터를 전송받을 때 메시지를 출력해 봤습니다. 어느 지점에서 문제가 일어나는지 확인하기 위해서였습니다.
     ➡ 연결이 정상적으로 이루어지는 메시지 출력 ( O )
     ➡ 연결 완료되었을 때 전송되는 메시지 출력 ( O )
     ➡ 연결이 종료되었을 때 전송되는 메시지 출력 ( O )

💬 모든 메시지가 정상적으로 출력이 되는 것을 확인했습니다. 그런데 이걸 확인하는 과정에서 이상한 패턴이 확인할 수 있었습니다. 연결, 연결 메시지, 종료 이 과정에 4~5초 안에 이루어지고 반복이 된다는 것입니다. 재연결 사이에 1~2초 정도의 간격이 있다는 것입니다.

 

✔ 해결

💬 문제를 해결할 수 있는 방법은 두 가지였습니다. 첫 번째는 서버에서 계속 데이터를 전송을 해서 연결이 끊어지지 않도록 하는 것입니다. 두 번째는 Jmeter 스크립트에서 연결 시간을 지정해 주는 것이었습니다.

✅ 입찰 기능을 테스트하는 것이어서 테스트 연결을 위해 추가적인 데이터를 날리는 것은 정확한 성능 측정이 어렵다고 판단했습니다. 그래서 Jmeter 스크립트에서 연결 시간을 지정하는 것으로 해결했습니다.

EventSource eventSource = builder.readTimeout(30, TimeUnit.SECONDS).build()​

 

✔ 다른 문제

💬 문제를 해결 이후에 정상적으로 테스트가 되는 것처럼 보였습니다. 그런데 두 번째 테스트부터 서버에서 "연결 오류" 에러가 다시 보이면서 문제가 발생했습니다.

💬 SSE의 문제점 중 하나가 클라이언트가 언제 연결을 종료했는지 알 수 없다는 것입니다. 그것을 인지해서 서버에서 데이터 보낼 때 전송에 실패하면 SSE 연결을 삭제하게 만들어놨습니다. 그러고 나서 예외를 던지게 해 뒀습니다. 이 부분이 문제가 되고 있었습니다. 전송이 실패한 하나를 만나면 예외 처리를 위해 다른 SSE 연결에 대한 데이터 전송은 시도하지 않았던 것입니다. 

 

✔ 해결

✅ SSE 데이터 전송에서 실패시 예외를 던지는 것 대신 로그를 찍는 것으로 대신해 해결했습니다.

for(CustomSseEmitter sendEmitter : sendEmitters) {
    try {
        sendEmitter.sseEmitter()
            .send(SseEmitter.event()
                    .name(event.toString())
                    .data(data));
    } catch (IOException ex) {
        currentEmitters.remove(sendEmitter);
        
        // 추가 코드
        log.info(ex)
        
        /* 삭제 코드
        throw new RuntimeException("연결 오류");
        */
    }
}
 

 

✔ 결과