SpringBoot 애플리케이션 부하테스트

jy.YOON·2022년 7월 6일

SpringBoot와 scouter 연동 Dockerfile 생성

centos 도커 이미지 생성
docker run -it --name cent centos
호스트확인
hostname
wget 설치
yum -y install wget

CentOS 8 지원 종료로 인한 'AppStream 문제 발생시 '

'appstream cannot prepare internal mirrorlist no urls in mirrorlist'

원인 파악

EOS CentOS 8

CentOS 8 은 December 31, 2021 부로 EOS 되었습니다.
지속적인 사용을 위해서는 CentOS 8 Stream 으로 배포판 변경을 해야지 지속적인 지원을 받을 수 있습니다.

Error dnf

Error: Failed to download metadata for repo 'appstream': Cannot prepare internal mirrorlist: No URLs in mirrorlist
메시지가 나오면서 dnf 가 수행이 안되는 것을 확인 할 수 있습니다.

[root@chhan-c8 ~]# dnf repolist
CentOS Linux 8 - AppStream                                                                                      87  B/s |  38  B     00:00    
Error: Failed to download metadata for repo 'appstream': Cannot prepare internal mirrorlist: No URLs in mirrorlist

해결 방안

이는 CentOS 8 EOS 로 인해 CentOS 8 Mirror site 가 vault 로 전환되어 Mirror site 를 못 찾아 발생되는 문제입니다.
(https://www.centos.org/centos-linux-eol/)

아래 명령어를 통해 기존에 Mirror site 를 Vault 로 전환하여 dnf 사용을 할 수 있습니다.

[root@chhan-c8 ~]# sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-Linux-*
[root@chhan-c8 ~]# sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-Linux-*

아래와 같이 정상적으로 repolist 를 받아오는 것을 확인 할 수 있습니다.

[root@chhan-c8 ~]# dnf repolist
repo id                                           repo name
appstream                                         CentOS Linux 8 - AppStream
baseos                                            CentOS Linux 8 - BaseOS
extras                                            CentOS Linux 8 - Extras
[root@chhan-c8 ~]# cat /etc/yum.repos.d/CentOS-Linux-BaseOS.repo 
...
[baseos]
name=CentOS Linux $releasever - BaseOS
#mirrorlist=http://#mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=BaseOS&infra=$infra
baseurl=http://vault.centos.org/$contentdir/$releasever/BaseOS/$basearch/os/                                << vault site 로 변경

위와 같이 당장은 해결이 가능하지만 해당 Repo 는 더이상 Package 의 유지보수가 없으므로 보안에 취약합니다.
근본적인 해결을 위해서는 다른 배포판(ex. rocky linux 등) 이나 CentOS 8 Stream, RHEL 8 로 전환이 필요합니다.

CentOS 8 Stream 전환

해당 문서와 혼선을 방지하기 위해 외부 사이트를 링크합니다.

도커 이미지 안에서 스카우터 설치

docker image ls
#도커 이미지 접속
docker exec -it 이미지이름 bash 
wget으로 scouter 설치
wget https://github.com/scouter-project/scouter/releases/download/v2.17.1/scouter-all-2.17.1.tar.gz
gzip 풀기
gzip -d scouter-all-2.17.1.tar.gz
tar 풀기
tar xvf scouter-all-2.17.1.tar
scouter 의 scouter.conf 변경
cd scouter
cd agent.java
cd conf
vi scouter.conf 

아래 목록 3개만 #을 제거하자

현재까지 도커이미지에서 구성한 환경을 다시 이미지화 시킨다.
exit
docker commit 도커이미지이름 새로묶을이미지이름
현재까지 만들어져있는 도커이미지 확인
docker image ls

git.maven을 통해서 배포소스 빌드
git clone 깃주소
maven 다운
yum install maven
app이란 이름으로 git Maven build
mvn install -DfinalName=app

위처럼 원하는 maven 빌드 이름을 지정하고 싶다면 아래 구문 추가

 <build>
        <finalName>{finalName}</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <id>repackage</id>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

자세한 내용은 공식문서를 참고하자

https://docs.spring.io/spring-boot/docs/current/maven-plugin/reference/htmlsingle/

Maven 빌드시 트러블슈팅

maven 빌드시 오류발생

Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources) on project standard: The plugin org.apache.maven.plugins:maven-resources-plugin:3.2.0 requires Maven version 3.1.0 -> [Help 1]

메이븐을 설치하고 보니 JDK 버전이 11에서 8로 다운그레이드가 자동으로 된 상태가 발생했다.

Maven 버전이 3.0이면 애플리케이션을 빌드할 때 Maven 버전이 낮다는 이유로 빌드가 되지 않는다. 그래서 Maven 버전 높은걸 직접 수동으로 설치해주고 설정도 잡아줘야한다.

이전의 낮은Maven 버전과 JDK1.8버전은 삭제
sudo yum remove -y maven && sudo yum remove -y /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.302.b08-0.amzn2.0.1.x86_64/jre/bin/java

Maven 3.6 버전 설치

wget https://downloads.apache.org/maven/maven-3/3.6.3/binaries/apache-maven-3.6.3-bin.tar.gz

tar xvf apache-maven-3.6.3-bin.tar.gz

압축푼 폴더를 /usr/local/maven경로로 이동 /usr/local/maven 경로를 만들지 않아도 알아서 폴더를 생성함

sudo mv apache-maven-3.6.3 /usr/local/maven

Maven 환경변수 잡아주기

sudo vi /etc/profile.d/maven.sh
export M2_HOME=/usr/local/maven
export MAVEN_HOME=$M2_HOME/bin
export PATH=$MAVEN_HOME:$PATH

환경설정 적용하기

source /etc/profile.d/maven.sh

Maven 버전확인

mvn -v

Maven 버전확인 시 등장하는 트러블 슈팅

The JAVA_HOME environment variable is not defined correctly This environment variable is needed to run this program NB: JAVA_HOME should point to a JDK not a JRE

원인

리눅스에 Maven을 설치한 후에, JAVA_HOME 환경변수를 설정해줘야 Maven이 JDK 위치를 찾아서 실행할 수 있습니다.

Maven의 목표는 우리가 실행하려는 프로젝트의 소스 코드에 맞는 적합한 Java 컴파일러를 실행시키는 것이기 때문입니다.

내부적으로(Apache Maven v3.5.4)

$JAVA_HOME/bin/java 을 찾도록 설정되어 있습니다.

그런데 만약, JDK가 아닌 JRE를 가리키도록 설정되어 있어도 초기 단계에서는 에러가 안납니다.

왜냐면 JDK와 JRE 둘 다 bin 폴더와 javac 파일을 가지고 있기 때문입니다.

JRE의 메인 기능은 Java code를 실행시키는 것(run)이지만,

JDK는 실행과 컴파일, 디버그(run, compile, debug) 등 여러 다른 중요한 것들을 합니다.

하여간 우리는 JAVA_HOME 을 JRE가 아닌, JDK를 가리키도록 해야합니다.

자바 컴파일 경로 확인
which javac
자바 환경 변수 버전 확인
echo $JAVA_HOME
자바 환경 변수 설정
vi /etc/profile

classpath는 라이브러리 경로를 가리키는데 . 을 입력하면 자바가 지정한 경로를 인식한다

JAVA_HOME=/usr/lib/jvm/java/java-11-openjdk-11.0.13.0.8-4.el8_5.x86_64
PATH=$PATH:$JAVA_HOME/bin
CLASSPATH="."
export JVA_HOME PATH CLASSPATH
모든걸 적용하고 Maven 버전을 확인하면 JDK11버전과 Maven 3.6.3 버전이 정상적으로 적용된것을 확인 할 수 있다.

다시 메이븐을 통해서 애플리케이션을 빌드해보자
mvn install -DfinalName=app

아까와 달리 성공적으로 빌드된것을 확인할 수 있다.

Docker file 만들기

스프링 파일의 경로와 같은 동일선상 위치(동일레벨)에서 도커파일을 생성해준다.

vi DockerFile
#sb_scouter:v1 이미지로부터
FROM sb_scouter:v1
#UTF-8 설정
ENV LC_ALL=C.UTF-8
#포트는 8080
EXPOSE 8080
#Maven 빌드로 만들어진 스프링 jar파일을 도커의 app.jar로 생성해준다.
ADD ./StandardSpringBoot/target/*.jar  app.jar
#스카우터 서버 경로로 가서 스카우터 서버를 실행 그리고 스카우터 agent와 conf정보를 물려서 스프링 jar 실행
CMD ["sh", "-c", "cd scouter/server/ && ./startup.sh && /usr/bin/java -javaagent:/scouter/agent.java/scouter.agent.jar -Dscouter.config=/scouter/agent.java/conf/scouter.conf
-jar /app.jar"]
도커 이미지화
#./ 현재위치에 잇는 도커파일로 새로운 도커이미지(sb_scouter:v2)로 만든다.
docker build -t sb_scouter:v2 ./
도커 이미지 확인
docker image ls

도커 이미지 실행

docker run -d -it --name test -p [ip주소]:[외부포트번호]:[docker 내부포트번호] dockerimage:version

 #--name 생성될컨테이너이름 -p 가용포트 -p 가용포트(스카우터포트:6100) 도커이미지
 docker run -d --name sb_sc2 -p 8080:8080 -p 6100:6100 sb_scouter:v2
혹시 도커이미지가 잘못빌드됬으면 삭제
docker rmi -f 도커이미지이름
이미지로 실행중인 컨테이너도 삭제
docker ps -a
docker stop 컨테이너ID
docker rm 컨테이너ID
도커로그확인
docker logs -f sb_sc2

관리pc에서 스카우터 툴을 실행해서 애플리케이션 감시하기

이제 http를 요청하면 Scouter에 request를 감시하는것을 확인할 수가 있다,.

k6를 이용한 부하테스트

https://k6.io/docs/getting-started/installation/

호스트에서 k6다운
docker pull grafana/k6

https://k6.io/docs/getting-started/running-k6/

vi k6.js
k6.js에 아래구문 적용
import http from 'k6/http';
import { sleep } from 'k6';

export default function () {
  http.get('https://본인호스트아이피:포트번호);
  sleep(1);
}

테스트구문

5000명 유저가 10초동안 request를 날린다
$ docker run --rm -i grafana/k6 run --vus 5000 --duration 10s - <k6.js

부하를 걸어준뒤 APM에서 확인할 수 았다.

엄청나게 무언가가 올라오는구만!!

profile
5 Seconds rule

0개의 댓글