네이버의 Ngrinder는 대표적인 성능 부하 테스트 도구입니다.
개인적으로는 다른 테스트 도구들에 비해서 설치 과정이 조금 번거롭다는 단점에 비해 사용성과 UI/UX가 너무 직관적이라는 장점으로 인해서 오랫동안 애정하고 있는 제품인데요.
설치형을 지원하다보니 동적으로 Agent 수를 늘리고싶을때마다 설치된 이미지로 서버를 재생성하는 방식으로 늘리는게 참 불편했습니다.
이럴 경우 AWS를 통해서는 보통 2가지 방법으로 해결할 수 있는데,
- 오토스케일링 그룹
- Beanstalk
등 동적으로 동일한 서버 환경을 편하게 증설할 수 있습니다.
이번 시간에는 AWS Beanstalk을 이용하여 스케일링 가능한 Ngrinder 환경 구축하기를 진행해보겠습니다.
1. EC2에 Controller 설치하기
가장 먼저 Ngrinder의 Agent를 관리하고, 성능 테스트 전체를 관리하는 Controller를 EC2에 설치해보겠습니다.
Ngrinder의 release 페이지를 가보시면 현재 사용 가능한 버전들을 볼 수 있는데요.
현재 3.5.5가 최신이니, 3.5.5 버전을 사용하겠습니다.
당연한 얘기지만, AWS EC2에서 진행됩니다.
AWS EC2환경을 먼저 구축하고 해당 서버에서 SSH 접속후 진행해주세요.
아래처럼 war
파일을 우클릭하여 링크주소를 복사합니다.
복사한 링크 주소를 wget
으로 다운 받습니다.
wget https://github.com/naver/ngrinder/releases/download/ngrinder-3.5.5-20210430/ngrinder-controller-3.5.5.war
다운받은 war를 실행하기 편하도록 버전명을 제거한 이름으로 변경하겠습니다.
link
를 하셔도 무방합니다.
mv ngrinder-controller-3.5.5.war ngrinder-controller.war
해당 war를 세션 종료 방지 & 백그라운드 실행을 위해 nohup &
으로 실행하겠습니다.
nohup java -jar ngrinder-controller.war >/dev/null 2>&1 &
(만약 잘 실행이 안된다면 java -jar ngrinder-controller.war
만 수행해서 console로 로그를 확인해서 수정후 다시 nohup &
으로 실행하시면 됩니다.)
명령어 실행 후, Java 프로세스를 확인해봅니다.
ps -ef | grep java
아래와 같이 실행한 war
프로세스가 잘 보인다면 성공입니다.
ec2-user 2601 2528 21 15:06 pts/0 00:00:00 java -jar ngrinder-controller.war
ec2-user 2614 2528 0 15:06 pts/0 00:00:00 grep --color=auto java
실행이되면 8080
포트로 해당 웹 사이트를 접근할 수 있습니다.
초기 ID/PW는
admin/admin
입니다.
로그인까지 확인되시면 바로 Controller쪽 설정은 끝났습니다.
2. Security Group 생성
Ngrinder의 정상적인 연동을 위해선 Agent가 Controller에 접근이 가능해야만 하는데요.
그래서 둘 간의 통신을 위한 보안그룹을 별도로 생성합니다.
서로 다른 EC2간의 통신에 대한 내용은 기존 포스팅을 참고하시면 좋습니다.
NGRINDER_AGENT
- agent 전용 보안그룹에는 별도의 인바운드가 없어도 됩니다.
- agent의
ssh
접근을 위한 보안그룹인NGRINDER_AGENT
외에 별도로 관리하시길 추천드립니다.- ex)
EC2_SSH
등의 보안그룹을 별도로 만들어서 agent EC2에 2개의 보안그룹을 둘다 추가하셔도 좋습니다.
- ex)
이렇게 만들어진 agent 보안그룹을 controller 보안그룹의 인바운드로 추가하면 됩니다.
NGRINDER_CONTROLLER
80
포트는wget
을 통해 agent가 controller의 agent 설치 파일을 다운 받기 위해 추가합니다.
그리고 이렇게 만들어진 보안 그룹은 각 서버에 추가하겠습니다.
- Controller는 1에서 구축되었으니, 바로 추가하시면 됩니다.
- Agent는 아래에서 Beanstalk 환경 진행시 같이 추가합니다.
3. Beanstalk에 Agent 설치하기
자 이제 동적으로 서버를 스케일링 할 수 있는 Beanstalk에 Agent를 설치해볼텐데요.
3-1. Agent 설치 링크 가져오기
먼저 Agent 설치 파일 다운로드 링크를 받아와야 합니다.
Agent는 Controller 페이지에서 직접 제공합니다.
Controller에서 우측 상단 프로필을 클릭후 Agent Management
를 선택합니다.
그럼 아래와 같이 Download 링크가 나오는데 이를 우클릭하여 링크주소복사를 합니다.
이렇게 가져온 링크는 아래 Beanstalk config 파일에서 사용할 예정이니, 별도 텍스트 파일에 복사해놓으시면 됩니다.
3-2. Beanstalk 설정하기
AWS Beanstalk에 대해서 어느정도 사용해본적이 있다고 가정하고 진행합니다.
본인의 환경에 맞게 Beanstalk을 생성하시면 되는데, 하나만 기존과 다르게 진행해주시면 되는데요.
Agent의 보안그룹으로 2. Security Group 생성
에서 생성했던 NGRINDER_AGENT 보안그룹만 하나더 추가해주시면 됩니다.
(다른 보안그룹 없이 이것만 하라는 의미가 아니라, 이것도 함께 추가입니다.)
- 이 보안그룹이 추가되어야만 Controller가 Agent를 인식할 수 있습니다.
기본적인 Beanstalk 환경이 구성되었다면, 이제 Config 파일을 만들어보겠습니다.
3-3. Beanstalk config
모든 코드는 Github 에 있습니다.
Agent에 사용될 프로젝트는 다음과 같은 구조를 가집니다.
📦 ngrinder-in-action
├─ .ebextensions
│ ├─ 01-appstart.config
│ ├─ 02-system-tuning.config
│ └─ 03-timezone.config
├─ .gitignore
├─ .platform
│ └─ nginx
│ └─ nginx.conf
├─ Procfile
├─ deploy.sh
├─ README.md
각각의 파일은 다음과 같습니다.
.ebextensions/01-appstart.config
files:
"/sbin/appstart" :
mode: "000755"
owner: webapp
group: webapp
content: |
#!/usr/bin/env bash
COLLECTOR="collector ip"
AGENT_FILE_HOST="agent download link"
wget ${AGENT_FILE_HOST} -P /var/app/current
tar -xvf /var/app/current/ngrinder-agent-*.tar
killall java
/var/app/current/ngrinder-agent/run_agent.sh -ch ${COLLECTOR}
- agent 파일을 실행할
appstart
스크립트를 생성합니다. - collector ip는 private ip를 등록합니다.
AGENT_FILE_HOST
에는 3-1 에서 가져온 Agent 링크를 넣습니다.- Agent의 실행 자체는 크게 어렵지 않습니다.
- 다운 받은 agnet.tar 파일의 압축을 풀고 (
tar -xvf
) 이를run_agent.sh
로 실행만 하면 됩니다. -ch ${COLLECTOR}
는 Agent가 데이터를 보낼 Controller의 위치를 지정하는 옵션입니다.- 기본값은
localhost
라서 외부에 연결할 경우 이번처럼ch
옵션을 사용하면 됩니다.
- 다운 받은 agnet.tar 파일의 압축을 풀고 (
.ebextensions/02-system-tuning.config
files:
"/etc/security/limits.conf":
content: |
* soft nofile 65535
* hard nofile 65535
commands:
01:
command: "echo \"10240 65535\" > /proc/sys/net/ipv4/ip_local_port_range"
02:
command: "sysctl -w \"net.ipv4.tcp_timestamps=1\""
03:
command: "sysctl -w \"net.ipv4.tcp_tw_reuse=1\""
04:
command: "echo \"net.ipv4.tcp_max_tw_buckets=2000000\" >> /etc/sysctl.conf"
10:
command: "sysctl -p"
- agent가 최대한의 성능을 내기 위해 기본적인 OS 성능 튜닝 설정을 합니다.
- 각 설정에 대한 상세한 내용은 AWS Beanstalk을 이용한 성능 튜닝 시리즈 을 참고하시면 됩니다.
.ebextensions/03-timezone.config
commands:
01remove_local:
command: "rm -rf /etc/localtime"
02link_seoul_zone:
command: "ln -s /usr/share/zoneinfo/Asia/Seoul /etc/localtime"
- 성능 테스트시 시간 오차를 방지하기 위해 타임존을 KST로 변환합니다.
.platform/nginx/nginx.conf
user nginx;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
worker_processes auto;
worker_rlimit_nofile 65535;
events {
use epoll;
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
include conf.d/*.conf;
map $http_upgrade $connection_upgrade {
default "upgrade";
}
server {
listen 80 default_server;
# (1) health check
location / {
return 200 'ok';
}
access_log /var/log/nginx/access.log main;
client_header_timeout 60;
client_body_timeout 60;
keepalive_timeout 60;
gzip off;
gzip_comp_level 4;
# Include the Elastic Beanstalk generated locations
include conf.d/elasticbeanstalk/healthd.conf;
}
}
(1) location /
- Beanstalk의 Load Balancer Health Check 기본 주소가
/
입니다. - Ngrinder의 Agent가 Health Check 대상이 되기 보다는 Nginx에서 바로
/
로 200 응답을 주게 하여 Health Check를 통과하도록 구성합니다. - Agent는 별도로 API 응답을 할 용도가 아니기 때문에 이런 기본적인 헬스체크에 대해서는 Nginx에서 처리합니다.
이렇게 구성이 다되셨으면 실제로 배포를 진행해보겠습니다.
4. 배포하기
위 3-3. Beanstalk config
에서 설정한 내용 그대로 배포용 zip 파일을 만들면 되는데요.
매번 수동으로 쉘 명령어를 치기보다는 빠르게 스크립트를 만들어서 진행합니다.
deploy.sh
#!/usr/bin/env bash
DIR=deploy
if [ -d "$DIR" ]; then rm -Rf $DIR; fi
mkdir $DIR
cp -r .ebextensions ./deploy/
cp -r .platform ./deploy/
cp -r Procfile ./deploy/
cd deploy
zip -r agent.zip .
mv agent.zip ../
작성이 다 되시면 chmod +x ./deploy.sh
로 실행권한을 줍니다.
그리고 스크립트를 실행해보시면 아래와 같이 차례로 명령어가 수행되어 agent.zip
파일이 생성됩니다.
$ ./deploy.sh
adding: .ebextensions/ (stored 0%)
adding: .ebextensions/03-timezone.config (deflated 31%)
adding: .ebextensions/02-system-tuning.config (deflated 52%)
adding: .ebextensions/01-appstart.config (deflated 47%)
adding: Procfile (stored 0%)
adding: .platform/ (stored 0%)
adding: .platform/nginx/ (stored 0%)
adding: .platform/nginx/nginx.conf (deflated 54%)
이렇게 생성된 zip 파일을 수동으로 Beanstalk에 배포해봅니다.
여기서 파일 선택으로 해당 agent.zip
파일을 선택해서 배포를 합니다.
정상적으로 배포가 되시면 다음과 같이 Success 상태를 확인할 수 있습니다.
최종적으로 Controller의 Agent Management에서도 Agent가 표기 되면 성공입니다!
Github Action으로 설정이 변경될때마다 배포하는 방법도 추후 포스팅하겠습니다.