본문 바로가기
카테고리 없음

JMeter SSE 테스트

by NH_club 2023. 8. 19.

현재 며칠 째 이 기능을 테스트를 성공하지 못하고 있다.

현재 프로젝트에서 가장 핵심 기능인데 말이다. JMeter에 조금 익숙해 졌으니 금방 끝나겠지 라고 생각한지 벌써 3일 째가 되어간다. 삽질 과정을 블로그에 적을 생각도 못하고 계속 삽질을 하고 있다.

첫 째, 일단 Referce가 없다. 그나마 2개 정도 있는데 이 2개의 방법이 유사해서 1개로 봐도 무방하다. 그렇다고 이 1개의 자료가 잘 되는 것도 아니다. https://www.blazemeter.com/blog/jmeter-sse 이 자료에서 제공하는 두가지 방식 전부 잘 되지 않는다.. 지금부터라도 삽질 과정을 남겨야 할 것 같아 부랴부랴 왔다...

JSR223 Sampler Script에서 import가 되지 않는 문제
더보기

며칠간 기록도 안하고 해결하느라 자료를 남기지 못했다. 기억나는대로 텍스트로 적어야겠다.

현재 필요한 라이브러리는 다음과 같다.

import com.launchdarkly.eventsource.EventSource
import com.launchdarkly.eventsource.EventHandler
import com.launchdarkly.eventsource.MessageEvent
import java.net.URI
import java.io.StringReader
import java.util.concurrent.TimeUnit
import javax.json.Json
import javax.json.JsonObject
import javax.json.JsonReader
import javax.json.JsonValue

이 부분에서 찾지 못한다고 에러가 떴다. 지금이야 이렇게 알고 말하지 이 것을 알기 까지가 굉장히 고되었다.
일단 eventsource에 있는 EventHandler는 4.0 버전부터 사라졌다. 그 것을 알기 전 까진 계속 이상한 곳을 수정했다. 결국 문제점을 찾아 Eventsource의 버전을 3.0으로 낮춰 해결했다.
이 뿐만이 아니라 다른 라이브러리들을 갖고 오는 방법, 해당 라이브러리는 어떤 라이브러리를 의존하고 있는지, 의존하고 있는 라이브러리를 갖고 오는 방법.. 등등 굉장히 많은 시간을 소비했고 import 문제는 해결하였다.

서버에서 보내는 이벤트를 수신하지 못하는 문제
더보기

현재 직면한 문제이다.

import com.launchdarkly.eventsource.EventSource
import com.launchdarkly.eventsource.EventHandler
import com.launchdarkly.eventsource.MessageEvent
import java.net.URI
import java.io.StringReader
import java.util.concurrent.TimeUnit
import javax.json.Json
import javax.json.JsonObject
import javax.json.JsonReader
import javax.json.JsonValue

class SimpleEventHandler implements EventHandler {
    List<String> respList = []

    void onOpen() {
        log.info("The connection has been opened")
    }

    void onClosed() {
        log.info("The connection has been closed")
    }
    
    void onMessage(String Event, MessageEvent messageEvent){
        String receivedData = messageEvent.getData();
	    log.info("Received event type: $Event with data: $receivedData")
        if (receivedData.startsWith("connect user:") || receivedData.startsWith("connect idea:")) {
            respList.add(receivedData)
        } else if (Event.equals("BID_PRICE_UPDATE")) {
            respList.add(receivedData)
        }
    }

    void onComment(String comment) {
        log.info(comment)
    }

    void onError(Throwable t) {
        log.info("Error $t")
    }
}

EventHandler eH = new SimpleEventHandler()
String responseList = ""

String[] parameters = Parameters.split(",")
String uri = parameters[0]  
long reconnectionTimeMs = parameters[1].toLong()
long sleepDuration = parameters[2].toLong()

EventSource.Builder builder = new EventSource.Builder(eH, URI.create(uri))
EventSource eventSource = builder.build()
eventSource.setReconnectTimeMillis(reconnectionTimeMs)
try {
    eventSource.start()
    TimeUnit.SECONDS.sleep(sleepDuration)
    log.info("1")
} catch(Exception e) {
    log.error("Exception while starting EventSource or sleeping", e)
    eventSource.close()
    log.info("2")
} finally {
    eventSource.close()
    log.info("3")
}

log.info("Processing received data...")
for (String respRecord : eH.respList) {
    log.info("Processing record: $respRecord")
    try {
        JsonReader jsonReader = Json.createReader(new StringReader(respRecord))
        JsonObject jsonObject = jsonReader.readObject()
        JsonValue bidPrice = jsonObject.getValue("bidPrice") 
        responseList = responseList + "Updated Bid Price: ${bidPrice}\n"
    } catch(Exception ex) {
        log.error("Error processing record: $respRecord", ex)
    }
}
SampleResult.setResponseData(responseList, "UTF-8")

여기에서 마지막 respList를 받아오지 못하고 있다. JMeter 로그에는 1과 3, Processing received data... 만 찍힐 뿐 아래의 Processing record: $respRecord를 찍지 못하고 있다. 이는 respList가 비어있다는 결론이 나왔다. 그럼 왜 비어있을까? 코드에선 처음에 init message를 보내주는데 왜 비어있을까 심지어 init message가 빨라서 못 받았을 까봐 1초의 딜레이를 주고 보내는데도 받아오지 못한다... 왜........ 왜왜왜ㅐㅗㅇ왜오애ㅙ애왜일까ㅏㅏㅏㅏㅏㅏㅏㅏㅏ

도저히 앞으로 나아가 지지 않아서 분담했다.

한명의 팀원은 JMeter로 나는 Gatling으로...


팀원 한 분이 JMeter로 SSE 테스트 해결함.


문제점 첫 번째 SimpleEventHandler에서 일단 log 기능이 되지 않았음.
System.out.println() 으로 잘 찍히는 것 확인.


문제점 두 번째 내부적으로 서버에서 일정시간 동안 지속적으로 업데이트를 해주지 않으면 연결을 끊어버림.

위의 스크립트는 처음 initMassage를 보낸 여부와 상관 없이 지속적으로 업데이트를 보내줬어야 했음.
eventSource 생성 시 readTimeout을 주어 지속적으로 업데이트 하지 않아도 가능하도록 설정하여 해결.

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