서버를 어떻게 세팅해야 할까?

📌 시작하기 앞서

설정에 대한 튜닝을 반드시 해야 한다. 세팅 값 하나 때문에 애플리케이션 성능이 안 좋아지는 경우가 많다. 보통 기본값으로 최대한의 성능을 낼 수 있는 것은 없다. 따라서 설정에 대한 튜닝은 반드시 하자.

📌 주로 영향을 줄만한 곳

개발하는 것만큼 서버 세팅은 중요하다. 잘못하면 1초, 10초도 걸릴 수 있다. 가장 좋은 방법은 성능 테스트를 통해 병목 지점을 미리 파악하는 것이다. 문제가 될만한 세팅 값을 먼저 진단하는 것이 가장 효율적이다. 웹 기반에서 영향을 줄만한 세팅은 아래와 같다.
1.
웹 서버 세팅
2.
WAS 서버 세팅
3.
DB 서버 세팅
4.
장비 세팅

📌 아파치 웹 서버에서 설정해야 할 것

웹 서버는 앞단에 두자

WAS의 부담을 줄이기 위함이다.
아래 글에서 웹 서버를 앞단에 배치시켜야 하는 이유를 알 수 있다.

httpd-mpm.conf에서 세밀한 스레드 설정을 하자

StartServers : 서버를 띄울 때 프로세스의 개수를 지정한다. (child 프로세스)
MaxClients : 최대 처리 가능한 클라이언트 수를 지정한다.
MinSpareThreads : 최소 여유 스레드 수를 지정한다.
MaxSpareThreads : 최대 여유 스레드 수를 지정한다.
ThreadsPerCHild : 프로세스당 스레드 수를 지정한다. 아파치 프로세스 하나에 n개의 스레드가 만들어진다. 따라서 작게 지정되어 있다면 늘려서 더 많은 사용자의 요청을 처리할 수 있도록 하자.
MaxRequestsPerChild : 최대 요청 개수를 뜻한다. 0이면 제한을 두지 않겠다는 의미를 가진다. 가급적이면 기본값인 0으로 두고 사용하길 권장한다.

503 에러 코드에 대한 조치

WAS가 응답하지 않을 때, backlog라는 값이 100이면 100개의 요청까지 큐에 담아두는데 100개가 넘으면 해당 사용자들은 503 에러 코드를 받게 된다. 아래와 같은 조취를 취하는 것이 좋다.
서버를 늘린다(Scale Out) : 가장 편한 방법이다. 금전적인 여유가 있다면..
서비스를 튜닝한다 : 응답이 안 되는 원인을 찾고 튜닝한다.
GC 튜닝을 한다 : GC가 오래 소요되어 응답되지 않는 경우 GC 튜닝을 한다.
각종 옵션 값을 튜닝한다 : 옵션 값을 잘못 설정하면 더 큰 문제가 생길 수 있기 때문에 웹 서버 및 WAS 전문가나 엔지니어와 같이 이야기해서 설정해야 한다.

📌 웹 서버의 KeepAlive 설정하기

웹 서버와 웹 브라우저가 연결되었을 때 keepAlive가 켜져 있지 않으면, 매번 HTTP 연결을 맺었다 끊었다 하는 작업을 반복해야 한다. 해당 기능을 사용하면 두 개 정도의 연결을 열어서 끊지 않고, 연결을 계속 재사용한다. 그 결과 대기 시간이 짧아지기 때문에 사용자가 느끼는 응답 속도고 엄청나게 빠라진다.
무조건 KeppAlive를 켜면 성능이 좋은 것은 아니라서 상황에 맞게 사용하자.

KeepAlive-Timeout 설정

반드시 KeepAlive-Timeout을 같이 설정해야 한다.
마지막 연결이 끝난 이후 다음 연결이 될 때까지 얼마나 기다릴지를 지정한다.
사용자가 많은 경우 5초 정도로 짧게 주는 것도 서버 리소스를 보다 효율적으로 사용할 수 있다.

📌 정적인 파일들은 CDN을 고려하자

많은 사이트에서 이미지나 CSS와 같은 정적인 것들은 웹 서버에서 처리하지 않고, CDN(Content Delivery Network)라는 서비스를 이용하고 있다.
CDN을 이용하면 별도의 URL에서 해당 컨텐츠들을 내려받고, 동적인 것들은 WAS에서 처리해놓으면 서버 부담을 줄일 수 있다.
비용이 비싸다는 단점이 존재한다.

📌 DB Connection Pool 및 스레드 개수 설정하기

가장 성능에 많은 영향을 주는 것이 DB Connection Pool과 스레드 개수이다.
많이 사용할 수록 메모리를 많이 점유하게 된다. 적게 지정하면 많은 요청을 처리하지 못하는데 트레이드 오프 상황이 발생할 수도 있다.

DB Connection Pool 개수

최소치

최소치 말고도 증가치, 최대치 등이 있으며 이를 자세하게 설정할 수 있다.
서버가 기동될 때 연결을 수행하는 개수이다.
이 값이 높으면 서버를 기동하는데 시간이 오래 소요된다. 개발 환경에서 이 값은 높을 필요가 없어 최소로 설정하자.
운영 환경에서는 최소 및 최대 값을 동일하게 하자. 사용자 수가 갑자기 몰리면 DB Connection Poll의 개수도 증가하기 때문이다.
DB 서버 리소스가 부족하면 최소값을 적게 하는 것도 방법이다.

몇개가 적당할까?

DB Connection Pool의 개수

대부분 WAS에서 10~20개 정도로 설정되어 있다.
기본 값으로 서비스 오픈 하면 원하는 요청량을 처리하지 못하기 때문에 40~50개 정도로 지정한다.

스레드 수

DB Connection Pool보다 10개 정도 더 지정한다.

스레드 수가 더 적으면 안될까?

스레드는 입구, DB Connection Pool는 출구라고 보면 된다.
스레드 개수가 DB Connection Pool 개수보다 작으면 적은 수만큼의 연결은 필요없게 된다.
예를 들어 스레드 개수가 40개이고, DB Connection Pool 개수가 50개이면 10개는 전혀 사용하지 않게 된다.

그러면 왜 더 많아야 할까?

모든 스레드가 DB에 접근하지 않기 때문이다.
이런 상황을 고려해서 보통 여유분을 갖도록 지정한다.

적합한 개수를 어떻게 찾을까?

상황에 맞게 찾아야 한다.
가장 좋은 방법은 성능 테스트를 통해 가장 적절한 값을 구해야 한다.

DB Connection Pool의 개수를 많이 늘리면 좋은게 아닐까?

아니다. 40개로 지정해놓고 100%를 쓴다면 무작정 늘리는 것이 좋은 방법인지 고민해봐야 한다.
이 경우에는 DB의 CPU를 점유하는 쿼리를 찾아서 튜닝을 해야 한다. 무작정 개수만 늘린다고 응답 속도가 높아지는 것은 아니다.

어떻게 쿼리를 튜닝할까?

쿼리의 플랜을 떠서 확인해보자.
인덱스가 없는지 확인하자.
테이블을 풀 스캔하는 쿼리가 있는지 확인하자.

DB CPU 사용량 50%, WAS CPU 사용량 100%

이런 경우는 WAS 애플리케이션을 튜닝해야 한다.
튜닝 후에도 같은 상황이 생긴다면, DB Connection Pooldl 20개였다면 25~30개로 지정하는 것이 좋다.

대기 시간도 중요하다.

DB Connection Pool 개수가 넘어섰을 때, 애플리케이션에서 남는 Connection이 없다 찾게 된다. 이때 발생하는 시간이 대기 시간이다.
대기 시간을 크게 잡는 것도 좋지 않고, 짧게 잡는 것도 좋지 않다. 내 시스템에 맞는 상황에 적절하게 조절하자.

📌 WAS 인스턴스 개수 설정하기

하나의 장비에서 여러 인스턴스를 사용하면, 인스턴스끼리 경합을 하면서 CPU를 차지하려고 한다. 따라서 무한정 인스턴스를 늘리는 것도 답이 될 수 없다. 따라서 절대값은 존재하지 않는다.

성능 테스트를 통해 적절한 개수를 구하자

CPU core 개수가 36개라고 해도, 36개의 인스턴스를 띄우는 것은 좋은 방법이 아니다.
성능 테스트를 통해 구하는 것이 가장 바람직한 방식이다.
인스턴스 1개일 때 500TPS, 2개일 때 700TPS, 3개일 때 720TPS, 4개일 때 730TPS라면 2~3개만 띄우는 것이 적합하다. 무작정 늘려서 TPS가 증가하지 않는다면 오히려 유지보수성만 떨어진다.

여유분이 생기면..?

메모리 여유분이 4GB가 남는다고 해서 하나의 인스턴스에 모두 지정하는 것도 좋지 않다. Full GC가 발생할 때마다 많은 시간이 소요될 가능성이 높아진다. 512MB ~ 2GB 사이에서 지정하는 것을 권장하는데 1GB로 지정해서 2개의 인스턴스를 사용하는 것을 권장한다. (절대값은 아니다)
여유분이 생긴다고 인스턴스를 늘리는 것보다는 차라리 여유분을 두는게 낫다. 예기치 못한 상황이 생길 수 있기 때문이다.

DB Connection Pool의 개수가 많아지면?

100개 이상으로 정해야 한다면, 두 개의 인스턴스로 분리하는 것이 낫다.

📌 Session Timeout 시간 설정

활성된 세션 개수 모니터링

시간에 지남에 따라 세션의 개수가 증가했다가 감소하는 것을 볼 수 있는데 이는 정상적인 상황이다.
위 그래프는 세션 수가 지속적으로 증가하는 것을 볼 수 있다. 첫 번째 그래프는 1,300개 내외의 세션을 유지하는데 위 그래프는 88,000개의 세션을 유지하고 있다. 이 문제의 원인은 세션 종료 시간이다. 이 부분은 간과하기 쉽다. 이 점을 유의하자.

📌 결론

튜닝부터 할 생각을 하고, 서버를 늘리는 것은 마지막에 하자
절대적인 숫자는 없다. 따라서 가장 적절한 설정 값은 성능 테스트를 통해 찾자.
내가 맡고 있는 시스템이 견딜 수 있는 사용자 수를 알고 있자.

📌 참고 자료

TOP