Introduction
SpringBoot를 활용한 Wep Application server 를 만든 후, 내가 만든 서버의 안전성 및 가용성을 확인하기 위해 부하 툴과 모니터링 툴을 활용해 알아보려고 합니다. 성능측정에 필요한 개념부터 직접 성능을 테스트 하고 어떤 점들을 개선했는지 적어보도록 하겠습니다.
Index
- 성능측정 할 때 알아야할 용어들
- 성능측정 전 알아야 할 JVM 개념 정리
성능측정 할 때 알아야할 용어 정리
사용자
-
서비스를 사용하는 사용자의 수 (부하를 주는 유저 수)
-
Acitve user:
어떤 요청을 보내고, 결과가 나오기를 기다리는 사용자
성능 테스트 시 virtual User 와 거의 동일하다.
-
Concurrent User
서비스에 접속한 사용자
서비스에 부하를 가할 가능성이 매우 높은 서비스 접속중인 유저
응답시간

-
응답시간은 요청시간과 응답시간으로 분리 가능하고 그 사이에는 Think time이 존재한다.
Think time이란 한 요청을 하고 다른 요청을하기까지 걸리는 시간을 의미한다.
-
위 사진의 Server의 의미는 (network + application server + db .. 등등) 서버에서의 대부분의 시간을 의미한다.
-
Response Timed의 Server에 해당하는 점을 중점적으로 측정하고 개선할 예정이다.
TPS
- 1초당 처리 가능한 트랜잭션의 수
- 클 수록 좋다.
- 이상적인 상황에서는 User 수가 증가함에 따라 로그 그래프를 그리며 점차 TPS는 수렴하게 된다.
TPS가 수렴하는 구간 부터 응답속도가 기하 급수적으로 올라가게 된다.
- 튜닝을 통해 TPS 개선시킬 수 있다.
병목
-
병목이라고 함은 프로그램이 작동하는데 있어서 시간이 많이 소요되는 곳이라 할 수 있다.
-
보통의 웹 기반 서비스에서는 DB에서 많은 병목현상이 발생한다.
(DB 연결, DB 쿼리, 결과 수신및 처리,DB해제 등)
-
다른 병목지점으로는 was server, disk, network, 연계서버 등등 많은 요인들로 병목현상이 발생할 수 있다.
성능측정 전 알아야 할 JVM 개념 정리
JVM
- JVM은 자바 어플리케이션이 수행되는 런타임 엔진을 의미
- JDK에 포함되어 있음
간단하게 자바 프로그램은 다음과 같은 순서로 동작
1. 빌드(컴파일 .java -> javac compiling -> .class)
2. 실행(class loading - execute)
JVM Architecture

- 작성한 코드들이 complier에 의해 바이트코드로 변환되고 클래스로더에 의해 각종 메모리에 저장되고 실행 엔진에 의해 작동한다.
JVM 메모리 영역
-
메소드 영역
- 클래스들에 대한 정보를 저장하는 곳 (클래스 메타데이터를 저장한다고 생각하면 됨)
- ex) 패지키명.클래스명, 부모클래스 정보, interface ,class, enum인지에 대한 데이터 저장
-
힙 영역
- new 키워드에 의해 생성된 Object들이 저장되는 곳
-
런타임 스택 영역
- 쓰레드별로 사용하는 저장소
- ex) 지역변수, 메소드 콜 순서 저장
-
PC Registers
- 쓰레드가 생성될 때 마다 생기는 공간으로, Thread의 어떤 명령을 실행하게 될지에 대한 부분을 기록하는 곳
-
네이티브 메소드 스택 영역
- 자바외 언어로 작성된 네이티브 코드가 저장되는 영역. 주로 c/ c++ 등의 코드를 수행하기 위한 스택이다.
클래스 로딩 절차
loading - linking -initalizing 순서로 동작
loading
- 컴파일 된 .class 파일을 읽어서 클래스 정보 JVM Method area에 데이터 저장
- 힘메모리에 class 타입의 객체를 저장
Linking
- .class 파일이 제대로 된 클래스파일인지 검증
- 클래스에 있는 static 변수들을 기본 값으로 메모리에 할당
Initializing
- static 변수들의 값을 static 블록에서 선언한 값으로 지정
- 클래스의 위에서부터 내려가면서 초기화 진행
Executon Engine
실행 엔진은 3가지로 구성됩니다.
- interpreter
- 바이트 코드를 라인단위로 읽어서 번역하고 실행
- 반복되는 부분이 있어도 계속 번역 작업 수행
- JIT Compiler
- interpreter를 효율적으로 활용하기 위해서 사용
- 모든 바이트코드를 컴파일 한 후 네이티브 코드로 변경
- interpreter에서 반복적인 메소드 호출이 있을 때, JIT에서 해당 부분에 대한 네이티브코드 제공 ( warm up이 될 때 프로그램이 느린 이유 이 작업이 진행되어야 하기 때문에)
- GC
- 사용하지 않는 heap 메모리 영역을 정리하는 역할
Reference
scouter를 활용한 시스템 장애 진단 및 해결 노하우 (저자 이상민)
The RED : 성능의 神: 궁극의 성능 튜닝과 트러블슈팅 by 이상민