일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- 프리코스
- 객체지향설계
- git
- 클린코드
- 객체지향
- 우테코
- 플레이 스토어 20명
- 기능명세서
- 구글 비공개 테스트 20명
- 운영체제 #CS지식
- 구글 플레이 비공개 테스트
- 플레이스토어 비공개 테스트
- 커밋 메시지
- 설계
- 구글 플레이 스토어 배포 방법
GYUD-TECH
[뉴젯] nGrinder 테스트 환경 구축 본문
뉴젯 프로젝트에서 동시에 발송되는 뉴스레터로 인해 메일 수신 처리가 오래 걸리는 문제를 발견하였다. 캐싱과 같은 기법을 도입하여 이를
개선하고자 하였는데, 도입 이전에 성능을 측정하여 현재 상태를 진단하고, 정확한 성능 측정 개선 정도를 파악하하고자 하였다.
성능 측정을 위해 nGrinder를 설정하며 겪었던 문제점과 Docker를 활용해 테스트 환경을 구축한 경험에 대해 자세히 소개할 예정이다.
nGrinder 소개
부하 테스트의 대표적인 도구인 JMeter와 비교하여 nGrinder가 가벼운 리소스를 사용하기 때문에 nGrinder를 활용한 부하 테스트 방식을 선택하였다.
nGrinder를 사용할 때 controller와 agent의 개념이 나오는데 이 구조를 이해하면 테스트 환경 구축도 이해하기 쉬워 간단하게 소개한다.
참고 자료: https://github.com/naver/ngrinder/wiki/Architecture
nGrinder 구성
nGrinder는 크게 controller와 agent로 구성된다.
controller
부하 테스트를 실행하기 위해서는 개발자가 발생 시키고 싶은 부하를 설정하고 모니터링하는 화면이 필요하다.
이를 위해 nGrinder는 controller에서 성능 측정을 위한 웹 인터페이스를 제공하여 개발자가 부하 script를 구성하고 모니터링 할 수 있게끔 도와준다. controller는 웹 인터페이스를 제공하기 때문에 기본적으로 8080 포트를 통해 접속할 수 있다.
agent
controller에서 작성한 Script에 따라 부하를 발생시키는 역할이 필요하다.
controller에서 부하를 발생 시킬 수도 있겠지만, 단일 머신에서 많은 부하를 발생 시키면 controller의 성능이 제한되는 문제가 발생한다. 부하를 발생시키는 agent라는 개념을 만들고, 여러 대의 agent를 구성할 수 있도록 하여 많은 부하를 발생시킬 수 있도록 도와준다.
이렇게 부하를 분산함으로써 여러 지역/ 네트워크에서 실행하는 것도 가능하도록 하여 실제 배포 환경과 비슷한 구성을 할 수 있도록 하는 효과도 있다.
정리
구조를 이해하면 테스트 환경 구축을 위해 어떤 과정을 거쳐야 하는지 쉽게 이해할 수 있다.
- nGrinder 설치
- controller 실행
- controller에서 부하를 발생 시킬 Script 작성
- agent를 필요한 만큼 생성 후 실행
- controller에서 부하 테스트 및 모니터링
이 과정을 따라가며 컨테이너 환경에서 부하 테스트 환경을 구축한 내용을 하나씩 소개하겠다.
테스트 환경 구축
로컬 환경에서 nGrinder 부하 테스트 환경 구축
처음에는 가장 쉬운 방식으로 로컬 환경에서 nGrinder를 사용하고자 하였다. 결론부터 말하면 이 방식 말고 Docker를 활용한 컨테이너 환경에서 nGrinder를 실행 시키는 것을 권장한다.
1. nGrinder 설치
가장 먼저 아래 Github 페이지에서 nGrinder war 파일을 다운받는다.
https://github.com/naver/ngrinder/releases
Releases · naver/ngrinder
enterprise level performance testing solution. Contribute to naver/ngrinder development by creating an account on GitHub.
github.com
나는 최신 버전인 가장 최신 버전인 3.5.9-p1을 설치해줬다. (버전이 변경되더라도 가장 최신 파일을 다운하면 된다.)
2. controller 실행
이후 아래 명령어를 입력해 war 파일을 실행해준다.
기본적으로 8080 포트에서 실행되기 때문에 target 서버를 8080 포트에서 실행하기 위해 9000번 포트로 변경하여 실행하였다.
java -Djava.io.tmpdir=[다운 한 nGrinder 파일 위치]/lib -jar ngrinder-controller-3.5.9.war --server.port=9000
만약 로컬 PC에 11 버전 이후 자바가 설치되어 있면, nGrinder가 지원되지 않기 때문에 버전을 낮춰야 한다.
자바 17버전을 사용하고 있던 나는 사전에 검색을 통해 자바 버전에 대한 주의를 보았지만, 오류가 발생할 수 있다는 가벼운 주의만 줘서 그냥 진행했지만 진짜 실행이 되지 않아서 한참 고생했다.
자바 11 버전을 새로 다운받는 일이 번거롭기 때문에 Docker를 활용해 컨테이너 환경을 구성하여 테스트를 실행하기로 하였다.
컨테이너 환경에서 nGrinder 부하 테스트 환경 구축
1. nGrinder 설치
Docker로 구축할 때는 일일이 파일을 다운받지 않고 Dockerfile 내에서 nGrinder war 파일을 다운받도록 설정하였다.
FROM openjdk:11-slim
# WAR 파일 다운로드 URL 설정
ARG WAR_FILE_TARGET_URL=https://github.com/naver/ngrinder/releases/download/ngrinder-3.5.9-p1-20240613/ngrinder-controller-3.5.9-p1.war
# curl 설치
RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*
# 네트워크에서 WAR 파일 다운로드
RUN curl -fL -o /app.war ${WAR_FILE_TARGET_URL}
ENTRYPOINT ["java", "-jar", "/app.war"]
나중에 docker agent 도 실행해줘야 하기 때문에 docker-compose 파일도 추가로 작성하였다.
services:
controller:
container_name: controller
build:
context: ./ngrinder-controller
dockerfile: Dockerfile
networks:
- ngrinder
environment:
- SERVER_MODE=controller
ports:
- "9000:8080" # 웹 접속 포트 (nGrinder 컨트롤러의 대시보드 및 설정 페이지 접속)
- "12000-12009:12000-12009" # 에이전트와 컨트롤러 간 통신 포트 범위 (테스트 실행 시 사용)
- "16001:16001" # 컨트롤러와 에이전트 간 내부 제어 통신 포트
컨테이너의 8080 포트에서 실행되는 controller를 로컬에서 9000번 포트를 통해 접속 할 수 있도록 Docker compose 파일을 작성하였다.
2. docker 컨테이너 실행
docker compose up controller 명령어를 활용해 docker 컨테이너를 실행시켜준 후, 9000 번 포트에 접속하면 로그인 화면을 볼 수 있다.
ID와 Password 모두 admin으로 입력하면 controller 대시보드에 접속할 수 있다.
3. Script 작성
controller 대시보드 상단 탭에서 Script - Create a Script를 클릭해 테스트 Script를 작성해 준다
Script 이름을 설정하고, URL에 내가 테스트할 서버의 url을 입력하면 된다.
localhost에서 실행하는 경우에는 localhost는 입력되지 않아 127.0.0.1를 입력하였다.
(뒤에 주소 설정과 관련해서 한참을 헤맨 내용을 소개할 예정이다)
4. agent 생성 및 실행
docker agent 생성을 위해 controller 대시보드에서 Download Agent를 통해 agent를 다운받아준다.
나는 이 파일을 agent.tar로 이름을 변경하고 압축 해제를 한 후에 아래와 같이 Dockerfile을 작성해 별도의 컨테이너에서 agent를 실행하도록 하였다.
FROM openjdk:11-slim
RUN apt-get update && apt-get install -y tar && rm -rf /var/lib/apt/lists/*
# tar 파일 복사 및 압축 해제
COPY ./agent.tar /home/
RUN tar -xf /home/agent.tar -C /home/ && rm /home/agent.tar
CMD pkill -f "ngrinder-agent" || true && /home/ngrinder-agent/run_agent.sh
agent에 대한 설정과 둘 사이 네트워크 통신을 위한 네트워크 설정도 docker compose에 작성해주면 된다.
agent:
build:
context: ./ngrinder-agent
dockerfile: Dockerfile
networks:
- ngrinder
networks:
ngrinder:
driver: bridge
docker 실행 시에는 agent는 반드시 controller에 연결되어야 하기 때문에 controller를 먼저 실행하고 agent를 실행해야 한다는 것에 주의하자.
부하 테스트 진행
이제 테스트를 위해 target 서버를 실행하고 controller의 Script 에서 Validate 버튼을 눌러 api를 검증하였지만, 서버를 찾을 수 없다는 에러가 발생했다.
이유가 무엇인지 한참을 고민하다가 docker 컨테이너 환경을 사용하고 있다는 것이 떠올랐다.
agent는 도커 컨테이너 환경에 존재하기 때문에 위 이미지와 같이 localhost:8080 포트로 요청을 보내게 되면, agent의 컨테이너에 8080 포트로 http 요청을 보내기 때문에 404 에러가 발생한다.
따라서 IP 주소를 host의 IP 주소로 변경하여 localhost에서 실행되는 테스트 서버에 요청을 보내도록 설정하였다.
private static final String BASE_URL = "http://host.docker.internal:8080"
@Test
public void test() {
HTTPResponse response = request.GET(BASE_URL + "/newsletter", params)
if (response.statusCode == 301 || response.statusCode == 302) {
grinder.logger.warn("Warning. The response may not be correct. The response code was {}.", response.statusCode)
} else {
assertThat(response.statusCode, is(200))
}
}
그 결과, 드디어 Test를 성공했다...!!
마지막으로 Performance Test 탭에서 성능 테스트를 진행할 Process 와 Trhead 개수, Script, 실행 규칙을 입력하고 테스트를 진행하면 된다.
나는 총 10개의 프로세스에서 각각 100개의 쓰레드로 총 1,000개의 요청을 보내도록 하였고, Run Count 1로 규칙을 설정하여 각각의 쓰레드가 한번만 테스트를 수행하도록 설정하였다.
Save and Start를 누르면 controller가 실행 중인 agent에 Script를 배포하고, 모니터링을 시작하며 agent는 설정한 값대로 script를 실행하며 부하를 발생시킨다.
느낀점
메일 서버를 배포하지 않고 local에서 테스트를 수행했기 때문에 IP 주소를 localhost로 설정해줘야 하는 부분에서 많이 헤맸다. Docker 환경에서의 nGrinder 테스트 진행과 관련된 아티클이 거의 없었기 때문에 Java 버전이나 docker 컨테이너 실행 순서, IP 설정 문제를 해결하는데 많은 시간이 걸렸던 것 같다.
하지만 직접 test 환경을 구축하며 nGrinder의 구조에 대해서 학습하고, docker에 대해서도 더욱 깊이 이해할 수 있었던 유익한 삽질 경험이라고 생각한다🥲
참고 자료
nGrinder 공식 문서: https://github.com/naver/ngrinder
nGrinder 공식 Github 아키텍처 소개: https://github.com/naver/ngrinder/wiki/Architecture
nGrinder 모니터링 시 값들의 의미 참고자료: https://0soo.tistory.com/223
'프로젝트' 카테고리의 다른 글
[뉴젯] Redis 도입과 분산 락을 활용한 동시성 문제 해결 (0) | 2025.02.01 |
---|---|
[뉴젯] 도커를 활용한 CI 구축 (0) | 2025.01.15 |
[뉴젯] 유저 지표에서 시작된 쿼리 성능 최적화 (1) | 2025.01.06 |
[뉴젯] 메일 수신 처리 속도 및 AWS Throttling 지표 개선 (1) | 2025.01.03 |
[해피에이징] 수평적 권한 상승 문제 (0) | 2024.01.11 |