55
WAS 기반 시스템 하에서의 성능관리 실무지침서 Version 0.92 2005 7 13

%Bc%Ba%B4ɰ%Fc%B8%Ae%Bdǹ%Ab%C1%F6ħ%Bc%Ad %C3ʾ%C8 %C0Ϻι%Df%C3%E9

  • Upload
    -

  • View
    1.245

  • Download
    1

Embed Size (px)

Citation preview

Page 1: %Bc%Ba%B4ɰ%Fc%B8%Ae%Bdǹ%Ab%C1%F6ħ%Bc%Ad %C3ʾ%C8 %C0Ϻι%Df%C3%E9

WAS 기반 시스템 하에서의

성능관리 실무지침서

Version 0.92

2005년 7월 13일

Page 2: %Bc%Ba%B4ɰ%Fc%B8%Ae%Bdǹ%Ab%C1%F6ħ%Bc%Ad %C3ʾ%C8 %C0Ϻι%Df%C3%E9
Page 3: %Bc%Ba%B4ɰ%Fc%B8%Ae%Bdǹ%Ab%C1%F6ħ%Bc%Ad %C3ʾ%C8 %C0Ϻι%Df%C3%E9

서 언

국내에 Java 라는 언어가 기껏해야 Applet 기반의 아기자기한 UI 보완 모습으로 선

보인 것이 1995 년도라면, 1998년도를 기점으로 하여 Java 라는 언어는 J2EE 라는

이름 하에 엔터프라이즈 어플리케이션 환경에서 미션크리티컬한 업무를 서버사이드에서

운영하기 시작하였다 . 그 중추적인 미들웨어는 WAS(Web Application Server) 라는 이름

으로 공급되기 시작하였고 , 그 때 이후 지금까지 2003 년도를 정점으로 현재 2005

년까지 7 년이란 기간 동안 정신없이 달려왔었다 .

아직까지도 C/S환경과 웹 기반 환경 사이에의 장단점에 대한 논란이 일부 끊이지

않고 있기는 하나 , 비록 90 년대의 다운사이징 열풍처럼 구체적인 형식으로 담론화

되지는 않았지만 가랑비에 옷 젖듯이 시대적 대세는 어느 사이엔가 웹 기반 시스템

으로 , Java라는 언어로 , J2EE/WAS라는 웹 미들웨어 하에서 우리들의 프로젝트는 재단

되어 있는 것이 사실이다 .

그 7 년이란 기간을 건너오면서 , 한 시대를 풍미했던 80 년대 IBM 메인프레임

/CORBOL 언어 세대와 파란만장한 역경의 세월을 감수해온 90 년대의 C/S시스템

/OLTP 미들웨어 /4GL 세대 선배들의 인내심의 한계 (?) 와 진정한 IT 발전 보다는 시

장 창출에 열을 올린 거대 IT 기업들의 적잖은 횡포 (?) 로 인해 , 우리들의 존경의

대상이었던 그들은 우리들과의 기술적 교류 단절이라는 뒤틀린 시대를 만들어 버리고

야 말았다 . 동시대를 살아가면서도 서로 다른 시간대에 존재하는 현실은 우리들로 하

여금 하나부터 열까지 처음부터 시작하라 강요해왔었다 .

이러한 현실의 최대의 피해자는 현재 운영 중인 시스템 그 자체였다 . 업체별로 필요

에 의해 제작된 IT 표준이 존재하지 않은 프레임워크와 그 기반 위에 구현된

J2EE 기반의 시스템은 기술인력 공급업체들로부터 그다지 연차가 높지 않은 엔지니어

에 의해 , 깊이 있는 기술적 검증과정을 거치지 않은 채 개발되어 운영되었고 , 박복한

예산과 납기일에 쫓겨 제대로 된 성능테스팅 과정을 거치 않은 채 시스템 오픈이

감행되기가 일쑤였고 , 그러한 시스템은 여지없이 시스템 오픈 첫날 성능장애로 이어졌

다 . 그리고 그 후속 처리는 시스템 담당자의 몫으로 , 개발업체의 몫으로, WAS제품 납

품업체의 몫으로 돌아갔지만 , 실상 최대의 피해는 시스템 장애로 인해 대외적 이미지

손상과 금전적 손실을 맞이한 그 시스템의 주인이었을 것이다 .

1

Page 4: %Bc%Ba%B4ɰ%Fc%B8%Ae%Bdǹ%Ab%C1%F6ħ%Bc%Ad %C3ʾ%C8 %C0Ϻι%Df%C3%E9

이제라도 , 메인프레임 기반의 안정적인 시스템 운영의 노하우와 C/S서버 시스템의 미

션크리티컬한 시스템 운영 시에 겪어 왔던 , 수백 회의 우여곡절을 겪으며 정리되고

발전되어왔던 성능관리를 위한 이론들을 재 조명해보고 , J2EE/ 웹기반 시스템에서의 안

정적인 시스템 운영을 위한 방안들을 도출해 보아야 할 것이다 .

그 첫 번째 단계가 웹 기반 시스템 상에서 직면하고 있는 성능 현상을 설명해 낼

수 있는 성능이론 / 모델에 대한 정립일 것이며 , 그 다음으로는 시스템을 모니터링하고

성능요소를 분별해 내어 효과적인 대응을 위한 어플리케이션성능관리 (Application

Performance Management) 방안과 , 이를 위한 APM 제품의 적극적인 검토와 적용일 것

이다 .

1 성 능분석

수학적 모델링은 어떤 현상을 수식적 표현으로 재구성하는 것을 의미한다 . 현실세계에

일어나는 어떤 현상의 특성 및 구조를 가장 잘 대표하는 변수들을 찾아내고 , 그 변

수들의 상관관계를 수식적으로 재 구성함으로써 수학적 가상공간을 설정하고 , 수식과

논리의 해법을 통해 의미있는 결론 혹은 현상을 이해하게 된다 . 또한 이를 다시 현

실세계의 현상에 적용함으로써 복잡하게만 보이는 현상을 이해할 수 있고 , 하나의 변

수가 변화할 경우 어떻게 현상이 진행될 것인가를 예측할 수 있게 된다 .

예를 들면 , 바람이 잔잔한 따뜻한 봄날 오후에 , 지상 50m 높이의 20 층 아파트 베

란다에서 질량이 50g인 달걀을 떨어뜨리면 , 몇 초 뒤에 지상에 도달할까? 공기에 의

한 마찰이 없다는 가정 하에 , 아이작뉴턴에 의해 지표면 근방에서의 중력가속도 (g) 는

9.81(m/sec2)로 알려져 있고 , 자유낙하하는 물체의 속도(v), 시간 (t) 및 떨어진 거리 (s)

는 다음과 같은 상관 관계 수식으로 모델링 된다 .

s = gt2/2

따라서, t = sqrt(2s/g) = sqrt(2 * 50 / 9.81) ≒ 3.193초 (sec) 임을 도출할 수 있다 . 만약 정

말 지상 50 높이에서 달걀 떨어뜨리기 실험을 했다면 , 위와 매우 유사한 수치를 얻

을 것이다 .

위 수식에서 g = v/t 이므로 (t = v/g), 다음과 같은 수식도 도출할 수 있다 .

2

Page 5: %Bc%Ba%B4ɰ%Fc%B8%Ae%Bdǹ%Ab%C1%F6ħ%Bc%Ad %C3ʾ%C8 %C0Ϻι%Df%C3%E9

s = v2/(2g).

교통사고예방을 위한 텔레비젼 공익광고에서 "차량 시속 150(km/h)는 지상 88 의

높이에서 자유낙하하는 것과 같습니다 "라는 멘트를 기억하는가 ? 시속 150는 초속

150*1,000/3,600(m/s) 이고,3이는 위 수식으로부터 ,

s = v2/(2g) = (150*1,000/3,600) 2 / (2*9.81) ≒ 88.49 (m)

이다 .

앞선 수식들에는 질량에 대한 변수가 없음에 주목할 필요가 있다 . 공기에 의한 마찰

이 없고 , 지표면 근방에서의 중력가속도가 일정하다는 가정 하에서 자유낙하하는 물체

의 속도(v), 시간 (t) 및 떨어진 거리 (s) 사이의 상관관계는 해당 물체의 질량과 무관하

기 때문이다 . 50g의 달걀이나 , 1kg 의 쇠구슬는 거의 동시에 지상에 도달할 것이다 .

어쩌면 당신은 무거운 물체가 먼저 떨어질 것이라고 잘못 생각하고 있지는 않았던가?

그러나 수학적 모델링은 현실세계의 현상 그 자체는 분명 아니다 . 항상 가정

(Assumption) 이 있기 마련이며 , 그 가정 사항이 해당 현상을 얼마나 잘 반영하고

있느냐가 그 모델링이 의미를 갖느냐 그렇지 않느냐를 결정 짓게 된다 . 가정이 거짓

이면 , 그 가정 하에서 도출된 모든 결론은 거짓이지 않던가 . 만약 쇠구슬이 아니라 ,

종이컵 혹은 심지어 풍선과 같은 물체를 동일한 높이에서 떨어뜨리면 어떻게 될까 ?

왜 위 수식들이 전혀 맞아 떨어지지 않는 것일까? 종이컵이 지상으로 떨어지는 운동

은 공기의 저항에 더욱 민감한 자연현상이고 , 이는 자유낙하운동 방정식만으로는 설명

될 수 없는 추가적인 변수를 고려해만하는 자연현상이기 때문이다 . 가정부터가 잘못되

었다 . 혹은 해당 쇠구슬을 지구로부터 220만 광년 떨어진 안드로메다 은하에서 떨어

뜨리면 (?) 그 쇠구슬은 지구를 향하기나 할까? 그렇다고 앞서의 수식이 아무짝에도 쓸

모 없는 것일까?

누구나 알고 있는 이런 이야기를 다소 장황하게 언급한 것은 , 웹기반 시스템하에서의

일어나는 현상을 수식으로 하나씩 풀어헤쳐 제시하게 될 앞으로의 모델링이 얼마나

해당 현상을 잘 설명하고 있는가를 비판적인 시각으로 보기를 바라는 마음에서이다 .

3

Page 6: %Bc%Ba%B4ɰ%Fc%B8%Ae%Bdǹ%Ab%C1%F6ħ%Bc%Ad %C3ʾ%C8 %C0Ϻι%Df%C3%E9

그 어떤 모델링도 현상 그 자체를 완벽하게 표현할 수는 없다 . 그러나 , 모델링을 통

해 의미있는 수식적 결론을 도출하고 , 이를 다시 현상에 대입함으로써 , 우리의 목적을

근사치에 가깝게 달성할 수만 있다면 그것으로도 충분하지 않겠는가 .

1.1 성 능 (Performance) 이 란

서로 다른 웹사이트 A, B 에서 각기 제공하고 있는 단일어플리케이션 a, b에 대한 서

비스가 아래 그림과 같이 있다고 가정해 보자 .

접속된 사용자가 아무도 없는 야심한 밤에 , 웹브라우져로 몇 번의 단위 호출 테스트

를 통해 , A 사의 a 서비스의 경우 단일 호출응답시간이 1초가 걸렸고 , B 사의 b 서비

스는 5초가 걸렸다고 가정해 보자 . 서로 다른 회사에서 제공된 위 두 가지의 서비

스 중에 당신은 어떤 것이 더욱 성능이 높다고 평가 하겠는가? 아마도 단일평균응답

시간이 상대적으로 빠른 A 사의 a 서비스를 주저 없이 택할 지도 모른다 . 어쩌면

“아하 , A 사의 a 서비스 가 B사의 b 서비스보다 자그마치 5 배나 빨라 , a 가 b 보다

성능이 5 배나 차이가 나 !”라는 결론을 내리고 있을지도 모르겠다 . 우리들은 지금껏

이렇게도 단일평균응답시간에 익숙하다 . 그러나 , 과연 그러할까 ?

성능(Performance)이란 무엇인가 ?

갑작스럽게 위와 같은 질문을 받는 다면 당신은 뭐라 대답할 것인가 ? " 응답시간이

빠르냐 그렇지 않으냐가 성능이지 "라고 대답할 수도 있고 , " 평균응답시간을 측정하

려면 , 스트레스테스트툴을 이용하여 , 동시에 부하를 어느 정도 준 후에 그 평균응답시

간을 구하는 것이 성능을 제대로 측정 하는 것이지 "라고 대답을 할 수도 있겠다 .

모 은행 시스템관리자는 " 저희 은행은 하루에 22 만 명이 다녀가는데 , 하루 평균

250만 건의 트렌젝션을 처리합니다 . 그래도 사용자의 평균응답시간은 3초를 넘어서지

4

Page 7: %Bc%Ba%B4ɰ%Fc%B8%Ae%Bdǹ%Ab%C1%F6ħ%Bc%Ad %C3ʾ%C8 %C0Ϻι%Df%C3%E9

않아요 . 시스템성능에 대해서는 아직 큰 무리는 없습니다 " 혹은 , " 우리 사이트는

HTTP세션 (session) 의 Timeout이 10 분으로 조정되어 있는데 , 세션의 개수가 머신

당 500명을 넘어서면 , 시스템 성능이 급격하게 저하됩니다 ".

도대체 성능란 무엇인가? 곳곳에서 "성능 (Performance)" 이란 용어가 사용되는데 , " 성

능을 측정한다 " 함은 뭘 측정한다는 것인가? 예를 들어 "A 서비스 ( 시스템 ) 는 B서비

스 ( 시스템 ) 보다 50% 성능이 높다 " 라고 했을 때 , 그 50% 라는 수치의 기준이 되

는 것은 무엇인가 ?

다음 그림과 같이 어떤 지역의 수돗물

공급을 위한 송수관이 있다고 가정 해

보자 . 만약 , 당신이 상수도 공사의 시공

담당자라면 어떤 점을 고려하여 송수관

을 시공하여야 하겠는가? 목표는 분명하

다 . 해당 지역의 가구에서 수돗물 사용

에 불편함이 없도록 하는 것이다 . 통계적 자료인 해당 지역의 가구수 대비 년간 총

수돗물 사용량 및 연중 가장 물사용량이 높은 한여름의 일일 평균사용량 , 하루 중에

서도 사용량이 가장 급증하는 시간대의 물사용량에 대한 정보를 분석하여야 할 것이

다 . 추가적으로 최근 몇 년간 이 지역의 인구이동 및 공장 혹은 아파트 건축계획과

같은 자료를 통해 향후 필요로 할 물 사용량에 대한 미래예측 또한 중요한 요소가

될 것이다 .

그런데 , 이 통계적 자료에 기반한 정보와 이제 시공할 송수관의 어떤 특성을 비교해

야 할까? 단위시간당 최대로 흘려보낼 수 있는 전송량이 1 차적인 요인이 될 것이다

. 송수관의 지름이 좀 작더라도 압력을 높여 유속을 빠르게 한다거나 , 유속은 좀 느

5

Page 8: %Bc%Ba%B4ɰ%Fc%B8%Ae%Bdǹ%Ab%C1%F6ħ%Bc%Ad %C3ʾ%C8 %C0Ϻι%Df%C3%E9

리더라도 송수관의 지름이 큰 것을 선택하는 것과 같은 행위의 기준은 , 어쨌든 단위

시간당 최대로 전송할 수 있는 능력을 구 하고 , 그것을 기준으로 서비스할 지역의

최대 수돗물 사용량을 고려하여 결정해야 할 것이다 . 송수관의 전송량은 , 단위시간당

이동된 물의 양이므로 , 단면적의 넓이과 유속의 곱으로 표현될 수 있을 것이다 . 결국

, 전송량 T(m3/sec) 는 유속 v(m/s) 와 단면적 S(m2) 의 곱이므로 ,

T(m3/sec) = v(m/sec) * S(m2)

와 같이 표현될 것이다 .

문득 생각하기에 , 유속을 무한대로 빠르게만 할 수 있다면 송수관의 단면적을 광섬유

처럼 작게해도 되지 않겠느냐는 발상을 해본다 . 그러나 , 유속을 빠르게 하려면 유압을

높여야 하는데 , 일정한 강도를 갖는 송수관이기에 특정 수압 이상을 견디지 못하니 ,

유속은 제한받을 수 밖에 없고 결국 송수관의 단면적을 무한정 작게만은 할 수 없

을 것이다 .

웹 기반 시스템에서 성능(Performance)를 얘기할 때도 앞서의 예와 매우 유사한 특

성을 갖는다 . 송수관의 성능이 얼마나 많은 가구에 원활한 서비스를 제공할 수 있느

냐가 관심사이듯 웹기반 시스템은 얼마나 많은 사용자에게 안정되고 원활한 서비스를

제공할 수 있느냐가 관건이다 .

이는 다음과 같이 세가지 관점으로 집약될 수 있을 것이다 .

How many clients?: 얼마나 많은 사용자(clients)들에게 서비스를 할 수 있는가 .

Resonable response time: 적정한 응답시간 이내의 안정된 서비스를 제공하는가 .

6

Page 9: %Bc%Ba%B4ɰ%Fc%B8%Ae%Bdǹ%Ab%C1%F6ħ%Bc%Ad %C3ʾ%C8 %C0Ϻι%Df%C3%E9

Cost-effective: 가능하면 비용 대비 효과 (cost-effective) 가 높아야 한다 .

송수관의 성능은 계량기를 통해 단위시간당 이동된 물의 양을 쉽게 측정할 수 있겠

지만 , Request and Response 특성을 갖고 있는 웹 기반 시스템에서의 성능은 어떻게

측정되어져야 할까?

예를 들어 , 다음과 같은 놀이를 연상해 보자 .

구슬이 굴러갈 수 있는 여러 줄의 홈이 파져

있는 다소 길고 넓직한 나무 판이 있다 . 한쪽

에서 구슬을 또루루 굴리면 반대편에서 그 구

슬을 다시 되받아 굴려주는 놀이이다 . 그리고 , 운동신경이 매우 뛰어난 어떤 아가씨의

"구슬 되받아치기 "능력을 측정하고자 한다 . 어떻게 하면 되겠는가?

테스트를 시행하는 한 사람이 먼저 쇠구슬 하나를 홈으로 먼저 굴린다 . 아가씨는 곧

바로 되받아 칠 것이다 . 이 과정을 일정시간동안 반복적으로 시행하면서 시간을 측정

한다 . 그리고 , 그 일정시간동안 몇 개나 되받아 굴렸는지를 세어놓는다 . 또한 , 각 개별

응답시간을 기록하고 평균응답시간도 구해 놓는다 .

그러나 , 하나의 구슬 만으로는 제대로 그 아가씨의 운동신경 능력을 측정 할 수 없

을 것이다 . 더 많은 건수를 처리할 수 있는 잠재적인 능력이 있음에도 불구하고 하

나의 홈으로 굴러오는 구슬 하나로는 제대로

자기 능력을 전부 발휘치 못했던 것이다 . 이제

반대편에서 테스트를 수행하는 인원을 3 명정도

더 보강하여 동일한 테스트를 다시 시행한다 . 아가씨의 손발이 바빠지기 시작한다 .

여기서 조건이 하나 있다 . 테스터들은 반드시 구슬이 되돌아올 때까지 기다려야 한

7

Page 10: %Bc%Ba%B4ɰ%Fc%B8%Ae%Bdǹ%Ab%C1%F6ħ%Bc%Ad %C3ʾ%C8 %C0Ϻι%Df%C3%E9

다. (차츰 이해하게 되겠지만 , 이 조건은 큰 의미를 갖는다 .) 측정시간동안 총 처리된

건수는 앞서의 경우보다 증가했겠지만 , 평균응답 시간은 앞서의 경우보다 느려질 것이

다 . 여러 개를 동시에 되받아 치려다 보니 곧바로 되받아 치지 못하고 큐잉

(Queuing)된 구슬이 생겼기 때문이다 .

논리적인 사고를 해 본다면 , 테스트 인원을 1명 , 2 명 , 3 명,..., 10명등으로 계속 순차

적으로 늘려 가면서 위와 같은 테스트를 했을 때 , 측정시간동안 되받아친 총 건수를

측정시간로 나눈 "단위시간당처리건수 " 는 어떤 특정한 테스트인원까지는 점차 증가하

다가 더 이상 증가하지 못하고 어떤 수치에 머무르게 된다는 것을 예상할 수 있

다 . 그 아가씨의 운동신경의 한계에 기인하기 때문일 것이다 . 또한 , 개별 구슬의 평균

응답시간은 테스트 인원이 늘어남에 따라 점차 느려질 것임을 예상할 수 있다 . 곧바

로 되받아치지못하고 큐잉 (Queuing)된 구슬의 양이 점차 늘어났기 때문이다 . 이를 그

래프로 그린다면 다음과 같다 .

궁극적으로 우리가 구하고자하는 것은 단위시간당 최대로 몇 개를 칠수 있었느냐는

바로 그 수치 , 단위시간당 최대 처리건수가 그 아가씨의 구슬 되받아치기 능력를 나

타내는 가장 적절한 수치가 될 것이다 .

웹기반 시스템 하에서의 요청-응답 모델 (Request-Reponse Model) 역시 앞서 구슬되받

아치기와 매우 유사한 성격을 갖고 있음을 알수 있고 , “ 적절한 응답시간 이내에서의

최대로 처리할 수 있는 단위시간당 최대처리 개수 ”를 “성능 (Performance)”의 수치

적 기준으로 삼는 것이 가장 바람직할 것이다 .

1.2 기 본 용 어 의 정 의

먼저 웹기반 시스템 하에서의 성능분석을 위한 의미있는 각종 변수를 정의해 보고자

한다 .

8

Page 11: %Bc%Ba%B4ɰ%Fc%B8%Ae%Bdǹ%Ab%C1%F6ħ%Bc%Ad %C3ʾ%C8 %C0Ϻι%Df%C3%E9

1.2.1 방문시간 (Visit Time)

앞서 그림에서 보듯 , 한 사용자가 첫 클릭시점부터 , 해당 사이트에서의 마지막 클릭시

점까지 해당 사이트에 머문 시간을 방문시간 (Visit Time)으로 정의한다1 .

1.2.2 응답시간(Response Time)

응답시간은 호출이 발생한 시점부터 , 호출에 따른 마지막 데이타가 모두 도착하였을

때까지의 시간을 응답시간(Response Time)으로 정의한다2 .

1 그러나, 방문시간을 정의함에 있어서, 모호함이 있다. 만약, 한 사용자가 30초간격으로 20회를 클

릭한 후 사이트를 떠났다면, 방문시간이 30(sec) * 20(회) = 10분이겠으나, 30초간격으로 20회를

호출 후 30분이 지난 후 다시 30초간격으로 다시 20회를 호출했다면, 이 사용자의 방문시간을 10분

+30분+10분= 50분으로 해야 할지, 혹은 방문시간은 10분이고, 1일 2회 접속자로 판단해야 할지가

매우 모호하다. 그 사이 간격 시간이 30분이 아니라, 5분,10분, 혹은 1시간, 10시간 등의 경우는 더

더욱 모호해 진다. 따라서, 호출과 호출사이의 간격이 일정 시간이 넘어설 경우는 그 사용자는 사이

트를 떠났다고 판단해야 하며, 다시 접속할 경우 새롭게 접속했다고 판단하는 기준시간이 있어야 한

다. 본 문서에서는 5분으로 지정하여 정의한다.2 일부 서적에서는 응답시간(Respose Time)을 호출 이후, 첫 데이터가 도달했을 때가지의 시간으로

정의하고, 마지막 데이터가 도달했을 때까지의 시간은 서비스시간(Service Time)으로 정의하기도

하나, 본 문서에서는 이를 응답시간(Response Time)으로 요약하여 정의한다.

9

Page 12: %Bc%Ba%B4ɰ%Fc%B8%Ae%Bdǹ%Ab%C1%F6ħ%Bc%Ad %C3ʾ%C8 %C0Ϻι%Df%C3%E9

1.2.3 대기시간 (Think Time)

사용자는 웹사이트에 방문하여 웹페이지를 클릭하게 되는데 , 한 페이지를 클릭한 후 ,

그 다음 페이지를 클릭할 때까지 일정 시간 대기하게 된다 . 때론 해당 페이지의 글

을 읽고 있을 수도 있고 , 혹은 커피를 잠시 마시거나 , 옆사람과 대화를 나누고 있을

대기시간은 접속 사용자의

행동양식 및 해당 사이트

의 웹페이지 구성에 따

라 , 해당 사이트의 고유한

비즈니스 특성을 나타내는

상수(Constant)와 같은 특성을 갖고있다 . 아래는 모 금융사이트에서의 일일 평균대기시

간의 그래프이다 .

대기시간은 비즈니스 도메인별로 유사한 면이 없잖아 있다3 .

TM(Telemarket) 시스템(Teler들에 의한 시스템 ) : 10-15초

MIS 인트라넷 시스템 : 15-20초

인터넷뱅킹 시스템 : 25-35초

온라인쇼핑몰 시스템 : 30-40초

온라인 커뮤너티 사이트 : 보다 길 수 있음

물론 접속사용자마다 행동양식은 숙련도에 따라 다를 수 있으나 , 화면 구성과 비즈니

스 특성에 따라 평균대기시간(Average Thinktime)이 갖는 의미는 성능분석에 매우 중

요한 변수로 대두된다 .

1.2.4 호출간격 (Request Interval)

3 대기시간(Thinktime)의 도메인별 경험수치를 통계적으로 기정 사실화 하는 우를 범해선 안될 것이

다. 단지, 예일 뿐이다.

10

Page 13: %Bc%Ba%B4ɰ%Fc%B8%Ae%Bdǹ%Ab%C1%F6ħ%Bc%Ad %C3ʾ%C8 %C0Ϻι%Df%C3%E9

클릭과 그 다음 클릭 사이의 시간을 호출간격 (Request Interval) 으로 정의한다 . 따라

서 , 호출간격은 응답시간(Response Time)과 대기시간 (Think Time) 의 합으로 표현된다 .

1.2.5 동시단말사용자 (Concurrent Users)

과거 메인프레임 기반의 더미(Dummy)3270 에물레이터나 C/S시스템에서의 “동시접속자

”수를 구하는 것은 그다지 어려운 일이 아니었다 . 사용자가 시스템에 접속하면 사용

자당 TCP/IP 연결이 맺어졌고 , 단지 현재 TCP/IP 연결의 개수 혹은 IP어드레스를 헤

아림으로써 , 현재 “동시접속자 ”를 측정했기 때문이다 . 그러나 , HTTP(Hyper Text

Transfer Protocol) 프로토콜 (Protocol)기반의 웹시스템은 비록 TCP/IP 라는 프로토콜을

사용하는 것은 동일하나, HTTP 프로토콜은 그 속성상 매 호출시마다 새로운 TCP/IP

연결이 새롭게 맺어지는 커넥션레스 (Connection Less) 라는 특성4 을 갖고 있기에 단순

히 연결된 TCP/IP 개수가 현재 해당 시스템을 사용하기 위해 PC 앞에 앉아 있는

“동시접속자 ”를 의미하고 있지 않게 된다 .

4 물론 HTTP Connection Less 특성은 HTTP 1.1에서 기술된 Keep-Alive라는 기능과 함께 맞물려

돌아가며, 웹서버에서 그 Keep-Alive Timeout시간을 지정해 줄 수 있다. Keep-Alive시간을 길게

설정함으로써, 한 사용자는 한번 연결된 TCP/IP연결을 재사용할 수 있게 되나, 그 시간을 너무 길게

설정하게 되면, 사용되지 않는 불필요한 TCP/IP연결이 사용자에게 할당(dedicated)되므로, 더 많은

동시접속자를 수용할 수 없게 된다.

11

Page 14: %Bc%Ba%B4ɰ%Fc%B8%Ae%Bdǹ%Ab%C1%F6ħ%Bc%Ad %C3ʾ%C8 %C0Ϻι%Df%C3%E9

위 그림에서와 같이 개별 사용자의 클릭을 하나의 점으로 표현해 보았을 때 , 각 사

용자는 나름의 호출간격 (Request Interval) 으로 클릭을 반복해 나갈 것이다 . 특정 시점

에서 , 본 시스템을 사용하기 위해 PC 앞에 앉아 있는 사용자수는 몇 명일까? 위 그

림에서라면 , 7 명이 해당 시점에서의 “동시단말사용자수 ”이다 . 이처럼 동시단말사용자수

(Concurrent User)는 해당 시스템을 사용하기 위해 PC 앞에 앉아 있는 서로 다른

사용자수의 수로 정의한다 .

국내 많은 엔지니어들 사이에서 , “ 동시사용자 ”라는 단어에 너무나 익숙해 있는 반

면 , 그 용어에 대한 혼동이 매우 극심하다 . 어떤 이는 “동시사용자 ”를 “동시단말사

용자 ”로 , 어떤 이는 이를 아래에서 설명할 “액티브 (Active)사용자 ”로 각자의 의미로

재해석 해 버린다 . 도통 서로간에 대화가 되질 않고 있다 . 그러한 차원에서 , 본 문서

에서는 “동시사용자 ” , “ 동시접속자 ” 라는 단어를 사용하지 않을 것이며 , “ 동시단말

사용자 (Concurrent User)” 로만 표기할 것이다 .

1.2.6 액티브 (Active)사용자

아래 그림처럼 , 각 개별 동시단말사용자는 각각의 응답시간(Response Time)과 대기시간

(Think Time) 을 가지며 클릭과 클릭을 반복할 것이다 . 특정 시각에서 시간을 칼로

무자르듯 잘라 보면 , 해당 시각에 클릭 이후 아직 응답을 받지 못한 사용자 , 혹은

12

Page 15: %Bc%Ba%B4ɰ%Fc%B8%Ae%Bdǹ%Ab%C1%F6ħ%Bc%Ad %C3ʾ%C8 %C0Ϻι%Df%C3%E9

해당 요청이 현재 수행되고 있는 사용자들이 존재할 것이다 . 아래의 그림에서는 3명

의 사용자가 해당 시점에 요청을 날린 후 응답을 기다리고 있는 사용자이다 . 이처

럼 , “ 요청을 날리고 , 응답을 기다리고 있는 사용자 ”를 “액티브 (Active)사용자 ”로 정

의한다 .

만약 , 네트워크 병목이 없다면 , 액티브 (Active)사용자의 요청은 서버측에서 해당 시점에

서비스가 수행되고 (running) 있을 것이다 . 이처럼 서버측에서 해당 시점에 서비스가 수

행되고 있는 개수를 “액티브 (Active)서비스 ”로 정의한다. 액티브사용자가 클라이언트측

에서의 관점이라면 , 액티브서비스는 서버측 관점에서 바라본 수치이다 . 본 문서에서는

두 용어를 동의어로 사용할 것이다5 .

1.2.7 처리량 (Throughput)

5 사실 [액티브사용자수 ≥ 액티브서비스수]일 것이다. 그러나, 네트워크 병목 및 쓰레스 개수 제한

등의 변수를 고려하기 시작하면, 수식적 모델을 전개해 나가는데 있어서, 측정할 수 없는 변수가 등

장함으로 인해, 수식적 모델의 활용성이 떨어지게 된다. 따라서, 네트워크 상에서, 혹은 쓰레드의 개

수제한 등에서 큐잉되어 있는 요청 또한 액티브서비스로 의미를 부여한다면, 액티브사용자는 액티

브서비스로 1:1 맵핑이 될 것이다.

13

Page 16: %Bc%Ba%B4ɰ%Fc%B8%Ae%Bdǹ%Ab%C1%F6ħ%Bc%Ad %C3ʾ%C8 %C0Ϻι%Df%C3%E9

단위 시간당 처리한 건수를 처리량 (Throughput) 으로 정의한다6 .

처리량 (Throughtput) 은 다시 두가지로 나뉠 수 있는데 , 단위시간당 호출이 발생한 건

수인 요청률 (Arrival Rate,호출빈도 ) 과 단위시간당 서비스한 건수인 서비스처리율

(Service Rate)으로 나뉘게 된다 .

처리량 (Throughput) 을 측정하는 방법은 측정구간 (measure time) 동안 호출된 혹은 서

비스된 건수를 해당 측정구간으로 나누어 , 단위시간당 처리건수를 구하게 된다 . 처리량

의 단위는 초당처리건수인 tps(Transaction Per Second) 혹은 분당 처리건수인

tpm(Transaction Per Minute) 혹은 시간당 처리건수인 tph(Transaction Per Hour) 등의 단

위를 사용하게 된다. 1 tps는 60 tpm 이며 , 3,600 tph 와 같은 의미이다 .

일부 서적에서는 단위를 tps 와 같이 Trsanaction이라 표현하지 않고 , 웹기반 시스템

임을 강조하기 위해 , pps(Page per second), rps(Request per second) 혹은 ops(Operation

per second), 심지어 HTTPops(HTTP operation per second) 라는 단위를 사용하기도 한

다 . 그러나 본 문서에서는 이미 광범위하게 통용되고 있는 tps 라는 단위를 사용할

6 Throughtput은 사실 “처리율”로 번역되는 것이 마땅하나, 너무나 광범위하게 이미 “처리량”으로

통용되고 있는 만큼, 본 문서에서도 “처리량”으로 표기했다.

14

Page 17: %Bc%Ba%B4ɰ%Fc%B8%Ae%Bdǹ%Ab%C1%F6ħ%Bc%Ad %C3ʾ%C8 %C0Ϻι%Df%C3%E9

것이며 , 본 문서에서의 Transaction 의 단위는 서블렛 /JSP(Java Service Page) 와 같은

동적컨텐츠 (Dynamic Content)에 대한 요청을 1 transaction 으로 정의한다7 .

1.2.8 부하 (Load)

부하 (Load) 는 개념적인 용어이다 . 웹기반 시스템하에서의 부하 (Load) 에는 " 량 "이란

단어를 붙이기가 꽤나 어색한데 , 굳이 붙여서 부하량이라고 한다면 , 부하량의 대표값은

처리량 (Throughput) 의 두가지 요소인 요청률 (Arrival Rate) 과 서비스처리율 (Service

Rate) 중 요청률이 적합할 것이다 .

그러나 , 웹 기반 시스템 하에서의 부하 (Load) 는 비단 요청률뿐만 아니라 , 동시단말사

용자수 (Concurrent User)와 시스템의 CPU 사용률 , 네트워크 부하량 등 , " 과부하 (Over

load)"와 " 저부하(Low load)" 등의 상태를 종합적으로 지칭하는 것으로 , 어느 하나를

대표값으로 사용할 수는 없다고 본다 .

1.3 호 출 - 응 답 (Rquest-Response) 모 델

앞서 우리는 아래의 그림과 같은 [구슬되받아치기 ]에서의 성능측정에 대한 언급을

했었다 .

7 사용자에 의한 1 클릭(click)을 1 transaction으로 하는 것이 개념을 전개해 나가는데 있어서 가장

바람직하다고 판단하고 있다. 그러나, 웹페이지는 경우에 따라 프레임(frame)으로 나뉘어 있거나,

혹은 sendRedirect라는 기능을 통해, 한번의 클릭에 의해 여러 개의 동적컨텐츠가 동시에 불려지기

도한다. 문제는 이러한 경우에 있어서 사용자에 의한 1클릭을 측정할 방법이 기술적으로 모호하다는

것에 있다. 이 부분에 대한 연구가 지속되기를 희망한다.

15

Page 18: %Bc%Ba%B4ɰ%Fc%B8%Ae%Bdǹ%Ab%C1%F6ħ%Bc%Ad %C3ʾ%C8 %C0Ϻι%Df%C3%E9

그렇다면 , 우리의 시스템에서 단위시간당 최대 처리 가능 건수인 최대처리량 (Maximum

Throughout)을 어떻게 측정할 수 있을까?

부하

테스트 도구를 이용하여 가상사용자 (Virtual User)를 점진적으로 증가시킨다 . 각 가상사

용자는 본 테스트에서는 응답이 오자말자 곧바로 다시 호출을 발생하는 것으로 가정

한다 . 즉 , 대기시간 (Thinktime) 은 0(sec)로 가정한다 . 각 가상사용자는 독립적으로 처리

한다 .

16

Page 19: %Bc%Ba%B4ɰ%Fc%B8%Ae%Bdǹ%Ab%C1%F6ħ%Bc%Ad %C3ʾ%C8 %C0Ϻι%Df%C3%E9

위와 같은 조건상황에서 , 점진적으로 가상사용자를 증가시키면서 , 증가된 각 가상사용자

수 마다 일정 시간 동안 측정한 평균응답시간 및 단위시간당 처리건수를 구해보면 ,

아래와 같은 그래프로 나타나게 된다 . 단위시간당 처리건수(Throoughput, tps)는 가상사

용자가 증가함에 따라 어느 정도 함께 증가 한 후 , 더 이상 증가하기 않는 시점이

발생한다 .

그 시점을 지나면서 , 평균응답시간의 그래프는 원점을 향하는 점근선에 수렴하는 형태

로 지속적으로 가상사용자수에 비례하여 증가하게 된다8 . 이처럼 단위시간당 처리건수

는 주어진 테스트 환경 내에서 그 한계를 갖고 있기 마련이며 , 단위시간당 최대처리

건수를 “성능 (Performance)”의 단위로 정의한다9 .

1.3.1 리틀의 법칙 (Little’s Law)

이 때 , 각 수치간의 수식은 다음과 같이 도출된다 .

고정된 특정 가상사용자 (N 명 ) 이 지속적으로 응답이 오자말자 다시 호출하는 과정을

반복하고 있을 때 , 만약 평균응답시간이 R( 초 ) 가 걸렸다고 해 보자 . 초당 몇건을

처리하고 있겠는가? N/R(건수 /sec, tps) 일 것이다10 .

8 증명은 본 문서의 후반부에 기술되어 있다.9 “단위시간당 최대처리건수(tps)가 성능의 단위이다”로 표현하지 않고, “정의한” 이유는 이렇게 정

의한 성능의 단위가 향후 성능분석(Performance Analysis)에 매우 유용하기 때문이다.10 예를 들어, 10명이 각각 2초의 응답시간을 보내고 있다면, 10개가 들어가 모두 2초만에 돌아오는

형국이므로, 10/2 = 5(tps), 즉, 1초당 5개를 처리하는 꼴일 것이다.

17

Page 20: %Bc%Ba%B4ɰ%Fc%B8%Ae%Bdǹ%Ab%C1%F6ħ%Bc%Ad %C3ʾ%C8 %C0Ϻι%Df%C3%E9

따라서 , 단위시간당 처리건수 (tps) 는 가상사용자수 (N) 을 평균응답시간으로 나눈 것이

며 , 위 수식은 리틀의 법칙 (Little’s Law) 으로 알려져 있다 .

테스트 과정에서 각 가상사용자수는 모두 액티브유저 (Active User) 로 맵핑된다 . 왜냐

면 , 응답이 오자말자 곧바로 호출하기는 대기시간 (Thinktime) 이 0(sec)인 조건상황이기

때문이다 .

1.3.2 대기시간 0 조건(Thinktime=0) 하에서의 그래프 유형

대기시간 (Thinktime) 이 0(sec)인 상황에서 점진적인 가상사용자 증가에 따른 단위 시

간당 처리건수의 그래프가 항상 앞서의 경우처럼 “ 각진 형태 ”로 나타나지는 않는

다 . 아래처럼 다양한 그래프의 유형으로 나타날 수 있다 .

웹기반 환경하에서의 요청-응답 (Request-Response) 모델에서의 전형적인 그래프 유형은

18

Page 21: %Bc%Ba%B4ɰ%Fc%B8%Ae%Bdǹ%Ab%C1%F6ħ%Bc%Ad %C3ʾ%C8 %C0Ϻι%Df%C3%E9

위에서 그래프 E이다11 . 그래프A는 “ 각진 부분 ”을 좀더 확대하여 보면 사실 그래프

E와 다르지 않고 , 그래프 B 역시 X축의 비율을 늘이면 E그래프와 동일한 유형이

다 . 그래프D는 아직 “ 각진 부분 ”을 만나지 아니하였으니 , 가상사용자수를 더 높여보

아야 할 것이며 , 결국 그래프 E의 유형에서 벗어나지 않을 것이다 . 결국 , 그래프 E와

그래프 C 유형으로 좁혀진다 .

1.3.3 경합구간 (Buckle Zone)

위 그래프에서 , 구간 (1) 을 저부하구간 (Light Load Zone) 이라 정의하며 , 구간 (2) 를 고부

하구간(Heavy Load Zone)이라 정의하고 , 구간 (3) 을 경합구간 (Buckle Zone) 이라 정의한

다12 .

고부하구간(Heavy Load Zone)이 나타나는 이유 , 즉 , 단위시간당 최대 처리건수가 일정

수치 이상 증가하지 않는 이유는 어떠한 1 차적인 병목 (Bottleneck)현상이 발생하여

아무리 가상사용자수를 올리더라도 해당 병목원인으로 인해 더 이상 단위시간당 처리

건수 ( 처리량 , Throughput)가 증가하지 않기 때문이다 . 이에 반해 경합구간 (Buckle

Zone)이 발생하는 이유는 가상사용자수가 증가함에 따라 1 차로 발생한 병목원인 이

외에 2 차적인 병목현상이 추가로 발생하여 , 하나 이상의 병목이 중첩되어 오히려 단

위시간당 처리건수를 끌어내리는 효과 때문이다 .

11 증명은 차후에 하겠다.12 참조문서http://www-306.ibm.com/software/webservers/appserv/doc/v40/ae/infocenter/was/0901.html#b109

19

Page 22: %Bc%Ba%B4ɰ%Fc%B8%Ae%Bdǹ%Ab%C1%F6ħ%Bc%Ad %C3ʾ%C8 %C0Ϻι%Df%C3%E9

예를 들면 , CPU 종속적인 어플리케이션이 있을 때, CPU가 100%가까이 도달할 때부

터 더 이상 처리량 (Throughput) 이 높아지지 않게 되며 , 이 상황에서 더욱 가상사용

자수를 높이게 되면 , 액티브 쓰레드 (Thread) 의 증가로 인해 해당 OS 의 컨택스트

스위칭 (Context Switching) 이 과도하게 발생하고 , 이 것이 2 차적인 병목원인으로 대두

되는 결과를 얻을 것이다13 .

1.3.4 임계점 (Saturation Point)

더불어 , 최초로 최대의 단위시간당 처리건수가 나타나는 변곡점(inflection point)을 임계

점(Saturation Point)14라 정의하고 , 임계점에서의 가상사용자수를 임계사용자수 (Saturated

Users) 으로 정의한다15 .

1.3.5 액티브사용자의 법칙 (Active Users’ Law)

액티브사용자수(Active Users)와 동시단말사용자수 (Concurrent Users) 의 상관관계에 대한

수식을 찾아보자 .

13 웹어플리케이션서버(WAS)의 최대 허용 Thread개수를 매우 높게 설정하여 적절히 제한시키 않았

을 경우에 이 같은 현상이 발생할 수 있다.14 Saturation Point는 사실 “임계점(Critical Point)”이라는 용어보다 “포화점”이란 용어를 사용하는

것이 그 의미에 있어서 더욱 적절하다. 그러나, 이미 국내에서 대중적으로 “임계점”이란 용어를 사

용하고 있기에 본 문서에서도 “임계점”으로 기술한다.15 이러한 정의 하에서의 임계점(Saturation Point)는 사실 명확한 수치로 측정가능하지 않다. 본 문

서 후반부에 기술하겠지만, 처리량 그래프의 방정식은 y=a라는 직선에 한없이 수렴하는 분수함수로

모델링되며, 변곡구간 근방의 곡선의 굴절도는 다양하기 때문이다. 임계점을 정의하는 새로운 기법

에 대한 연구가 지속되기를 희망한다.

20

Page 23: %Bc%Ba%B4ɰ%Fc%B8%Ae%Bdǹ%Ab%C1%F6ħ%Bc%Ad %C3ʾ%C8 %C0Ϻι%Df%C3%E9

먼저 리틀의 법칙을 상기하자 .

또한 , 다음과 같은 수식을 주장한다 .

예를 들어 10 명의 동시단말사용자가 각각 5초간격으로 호출을 지속적으로 발생하

면 , 전체적으로 1초당 5 건씩 처리한 셈이다 . 즉 , 동시단말사용자수 (ConcurrentUser) 를

평균호출간격 (Request Interval) 으로 나누면 단위시간당 평균처리량 (Throughput) 이 나온

다 .

위 두 수식에서 처리량 (Throughput)변수를 제거하면 , 다음과 같은 식이 도출된다 .

21

Page 24: %Bc%Ba%B4ɰ%Fc%B8%Ae%Bdǹ%Ab%C1%F6ħ%Bc%Ad %C3ʾ%C8 %C0Ϻι%Df%C3%E9

또한 , 호출간격 (Request Interval) 은 평균응답시간 (ResponseTime)과 대기시간 (Thinktime)

의 합이므로 , 다음과 같은 수식으로 표현된다 .

이를 액티브사용자의 법칙 (Active Users’ Law) 이라 정하겠다16 .

1.3.6 액티브사용자 법칙의 의미

위 수식의 우항을 통해 , 액티브사용자수는 동시단말사용자수의 {평균응답시간/(평균응답

시간+대기시간)}배이다 . 그런데 , 대기시간 (Thinktime) 이라는 것은 해당 사이트 접속사용

자의 행동양식에 따라 결정되는 상대적으로 고정된 통계적 상수 (Constant)로 취급될

수 있는 반면 평균응답시간은 동시단말사용자수가 증가함에 따라 가변적인 변수이므

로 , 우항의 비를 다음과 같이 평균응답시간 (x) 에 대한 함수 f(x)로 표현해 보자 .

분수함수로 표현된 f(x)는 x가 0 으로 한없이 접근할 때, f(x)0으로 수렴하며 , x 가

무한대()로 갈 때 , f(x) 는 1 로 수렴하는 특성이 있다 .

이것이 의미하는 바는 , 아무리 동시단말사용자수가 많더라도 , 평균응답시간 (x) 이 한없이

0 에 가까우면 액티브사용자수는 거의 0 으로 나타나며 , 반대로 몇 안되는 동시단말사

용자가 접속하여도 평균응답시간이 무지 느리다면 동시단말사용자수 전체가 액티브유저

로 도출된다는 것을 시사한다 .

16 액티브사용자의 법칙에서 평균응답시간을 좌변으로 이동시킨 수식은 평균응답시간의 법칙

(Response Time’s Law)으로 알려져 있기도 하다.

22

Page 25: %Bc%Ba%B4ɰ%Fc%B8%Ae%Bdǹ%Ab%C1%F6ħ%Bc%Ad %C3ʾ%C8 %C0Ϻι%Df%C3%E9

일반적으로 (?) 액티브사용자수는 동시단말사용자수의 몇%일까? 우리는 흔히 이 같은 질

문을 던지고 통계적 경험치를 구하려 했다 . 그러나 , 동시단말사용자수 대비 액티브사용

예를 들면 , 대기시간 (thinktime) 이 27 초인 사이트에서 , 액티브사용자수가 동시단말사용

자수의 10% 가 되기위한 조건은 평균응답시간이 3초인 경우이다 . f(x) = x/(x+C) =

액티브사용자수가 동시단말사용자수의 절반인 50% 가 되기 위한 조건은 무엇일까 ?

f(x)=x/x+C=0.5 일 조건이면 되는데 , 평균응답시간이 대기시간 (thinktime) 과 동일하면

된다17 .

1.3.7 액티브사용자수의 특성

액티브사용자수의 변화에 대해 직관적인 이해를 돕기 위한 예로 , 깔때기에 물을 흘려

보내는 현상에 대해 언급해 보자18 . 단위시간당 유입되는 물의 양 (Arrival Rate) 과 깔

때기에서 최대로 단위시간당 흘려보낼 수 있는 물의 양 (Maximum Service Rate), 그리

고 , 유입되는 유량의 “울컥거림 ” , 이로인한 진동 등이 결과적으로 깔때기에 큐잉

(queuing) 된 물의 양과 높이가 결정될 것이다 .

시스템 운영 중에 나타나는 액티브사용자수의 또 한가지

특성은 , 액티브사용자수는 시스템이나 어플리케이션이 다를

경우 , 동시단말사용자수나 부하량에 항상 비례하지는 않는다

는 것이다 . 예를 들어 , A 사이트는 동시단말사용자수가 1 만

명이며 1초당 330 tps 을 처리하고 있는 반면 , B 사이트는

동시단말사용자수가 100명이며 , 1 초당 3.3 tps 로 처리하고

있다고 가정해 보자 . 어느 사이트의 액티브사용자수가 많을

까? 당연히 A사이트가 많을 것 같지만 , 각 사이트의 어플

17 f(x) = x/(x+C) = C/(C+C) = 0.5 (50%)18 호출응답모델은 사실 깔때기모델보다는 여러 개의 요요(yoyo)를 동시에 깊은 통속에 넣었다 뺐다

를 반복하는 현상과 더욱 일치한다. 요요(yoyo): 자이로스코프의 원리를 응용한 장난감. 나무·플라

스틱·함석·토제(土製) 등으로 평평하고 둥글게 된 것을 맞붙여서 짧은 축으로 연결하고, 그 축에 실

을 감은 다음 실 끝을 손에 쥔 상태로 던졌다 당겼다 하면 실이 바퀴의 축을 감았다 풀었다 하면서

바퀴가 동시에 회전하며 실을 따라 상하로 움직인다. http://100.naver.com/100.php?id=716773

23

Page 26: %Bc%Ba%B4ɰ%Fc%B8%Ae%Bdǹ%Ab%C1%F6ħ%Bc%Ad %C3ʾ%C8 %C0Ϻι%Df%C3%E9

리케이션 특성 및 평균응답시간에 따라 이는 달라진다 .

이는 마치 , 다음 그림과 같이 서로 다른 두개의 깔때

기에서 큐잉 (Queuing)된 물의 량이 어느 쪽이 더 많

겠느냐는 문제와 유사하다 . 좌측 깔때기의 경우 , 단위시

간당 엄청난 양의 물을 흘려보내고 있지만 , 막상 깔때

기에 큐잉되어 있는 물의 양은 상대적으로 매우 적을

수 있다 . 반면 , 우측 깔때기의 경우는 단위시간당 최대로 흘려보낼 수 있는 물의 양

이 그다지 높지 않음에도 불구하고 , 깔때기의 특성상 오랫동안 큐잉되어 있는 물의

양이 상대적으로 전자보다 많다 .

스트레스테스트 툴을 이용하여 가상사용자를 점진적으로 증가시키며 처리량 (Thoughput)

과 액티브사용자수의 변화를 살펴보면 다음과 같다 . 깔때기의 물높이가 유입되는 물의

양이 단위시간당 최대로 흘려보낼 수 있는 유량에 근접함에 따라 순식간에 차 올라

오듯 , 액티브사용자수의 변화는

임계점 근방을 근접할 때 , 상대

적으로 급격한 상승을 하게 된

다 . 동시단말사용자수의 증가에

따른 액티브사용자수의 그래프는

사실 분수함수식으로 표현되며

임계점 근방에서 무한대를 향하는 특성을 갖고 있다19 .

19 본 문서의 후반부에서 증명하고 있다.

24

Page 27: %Bc%Ba%B4ɰ%Fc%B8%Ae%Bdǹ%Ab%C1%F6ħ%Bc%Ad %C3ʾ%C8 %C0Ϻι%Df%C3%E9

( 편집중… )

25

Page 28: %Bc%Ba%B4ɰ%Fc%B8%Ae%Bdǹ%Ab%C1%F6ħ%Bc%Ad %C3ʾ%C8 %C0Ϻι%Df%C3%E9

2 WAS 시 스 템 성 능 장애 유형 분석

다음 장에서 언급하게 될 APM 제품에 대한 검토 이전에 , 먼저 WAS/J2EE기반 시스

템으로 운영되어왔던 실 사이트에서 그 동안 겪어 왔던 각종 성능 장애의 유형들에

대해서 정리해 보고자 한다 .

2.1 성 능 장 애 현 상 의 외 형 적 특 성

시스템에서 성능저하현상이 발생했을 때 , 우리들은 다음과 같은 용어들로 그 상황을

지금껏 묘사해 왔다 .

응답시간이 전반적으로 갑자기 느려졌어요 . 계속 모래시계가 돌고 있어요 .

WAS 프로세스는 죽지 않았는데 , 내부에서 뭔가 일을 안하고 있는 듯 해요 .

네트웍은 이상없습니다 . 메모리도 충분해요. DB서버도 이상없어요 .

CPU 사용률은 어느 순간부터는 오히려 낮아요 . 뭔가 일을 안하고 있음이 분명

해요 .

어플리케이션로그를 보면 정상적인 것처럼 보이긴 한데 , 어느 순간부터는 벅벅거

리는 듯 합니다 .

웹서버와 WAS 서버 사이의 TCP 연결개수가 너무 많아요 . 왜 이렇게 많죠 ?

WAS 재기동 (restart) 할까요 ? restart 하고 나면 한참 동안은 괜찮거든요 .

시스템 오픈 이후 이 같은 성능장애 상황에 직면했다면 , 신속하게 판단해야 할 일들

은 다음과 같다 .

26

Page 29: %Bc%Ba%B4ɰ%Fc%B8%Ae%Bdǹ%Ab%C1%F6ħ%Bc%Ad %C3ʾ%C8 %C0Ϻι%Df%C3%E9

현재 Active 하게 서비스 수행 중인 어플리케이션은 무엇인가 ? 특정 어플리케이션

인가 ? 아니면 불특정 다수의 어플리케이션인가 ?

도대체 접속된 동시단말사용자수는 몇 명인가 ? 성능장애현상이 발발한 시점이 동

시단말사용자수의 증가와 연관성을 갖는가 ?

성능장애현상이 CPU의 부족에 의해 발생한 것인가 ? CPU증설이 필요한 것인가 ?

아니면 특정 어플리케이션 혹은 특정 모듈이 비정상적으로 CPU를 과도하게 사

용하고 있는 것인가 ? 현재 과도하게 서비스큐잉되고 있는 어플리케이션은 도대체

CPU를 다른 어플리케이션에 비해 얼마나 더 많이 사용하고 있는 것인가 ?

해당 현상이 데이터베이스의 특정 SQL의 성능저하나, Backend시스템의 특정 TP

서비스의 성능저하에 기인한 것인가 ? 그렇다면 그 SQL 혹은 그 트렌젝션명은

무엇이고 , 동시단말사용자수의 증가에 따른 평균응답시간 및 Active 서비스의 개수

는 몇 개인가 ?

마지막 질문은 , 그래서 , 어떤 부분을 혹은 어떤 어플리케이션을 어떻게 , 얼마나

성능적 관점에서 개선 시키면 해당 성능장애현상을 극복할 수 있는가 ?

생각해 보면 당연한 질문이지만 , WAS/J2EE시스템 기반 하에서 위와 같은 정보를 추

출해 내기란 특별한 기술적 노하우와 성능모니터링 / 분석도구가 존재하지 않으면 지금

껏 사실상 불가능했다 . Black Box 라고 칭하지 않았던가 ?

2.2 성능 장애의 유형 분류

시스템 장애의 유형은 크게 정상적으로 동작하는 어플리케이션 하에서의 상대적성능장

애 (Relative Performance Problem) 와 비정상적인 특정 조건 상황에 의해 발생하는 조

건적성능장애 (Conditional Performance Problem)로 분류할 수 있다 .

사용자가 상대적으로 많지 않을 경우는 극히 정상적인 응답시간을 보이다가 사용자가

점차 증가함에 따라 특정 어플리케이션 혹은 불특정 다수의 어플리케이션들이 점진적

으로 혹은 갑작스럽게 응답시간의 저하를 보이는 현상이 전자에 해당하고 , 반면 지속

적으로 특정 어플리케이션에서의 JDBC 연결과 같은 리소스 미반환 현상이나 메모리누

수 등과 같은 현상에 의해 일정 서비스 시간 경과 후에 더 이상 정상적인 서비스

를 수행할 수 없는 것과 같은 현상이 후자에 해당한다 .

27

Page 30: %Bc%Ba%B4ɰ%Fc%B8%Ae%Bdǹ%Ab%C1%F6ħ%Bc%Ad %C3ʾ%C8 %C0Ϻι%Df%C3%E9

2.3 상 대 적 성 능 장 애 (Relative Performance Problem)

정상적 어플리케이션 하에서 발생하는 상대적성능장애의 대표적인 유형은 , 개발과정 및

테스트 전 과정에서 극히 정상적인 동작을 하였음에도 불구하고 , 부하량의 폭주라든가

예상했던 것 보다 H/W 의 상대적 용량부족등에 기인하여 발생하는 성능장애 현상이

시스템의 성능이라는 것은 항상 상대적인 특성을 갖고 있기에 , 다각적인 측면에서 고

려하지 않으면 핵심을 놓칠 수 있다 . 다양한 웹기반 시스템에서의 성능진단 및 장애

진단의 경험에 비추어 보면 , 어플리케이션의 성능저하로 인한 성능장애의 특성은 특정

한 두개의 어플리케이션 성능저하로 인해서 발생하는 경우가 많다 . 즉 , 각각의 어플리

케이션들은 각자 고유한 “단위시간당 최대처리가능건수 (Ti)” 가 특정 H/W, S/W 플렛폼

하에서 결정지어져 있는데 , 시스템을 사용하는 사용자들이 어떤 응용어플리케이션을 상

실제 발생한 단위시간당 호출빈도 (ti) 대비 해당

응용어플리케이션의 최대처리가능건수 (Ti) 에 따른

비율이 좌측과 같을 때 , 해당 시스템의 임계성

능사용률 (%) 은 92% 이다 . 어떤 응용어플리케이

션을 튜닝하면 가장 효과적이겠는가의 이슈를

해결하기 위해 , 아래와 같은 방사형 그래프와

그 비율의 막대형 그래프를 보면 직관적인 이

해가 쉬울 것으로 판단된다 .

28

Page 31: %Bc%Ba%B4ɰ%Fc%B8%Ae%Bdǹ%Ab%C1%F6ħ%Bc%Ad %C3ʾ%C8 %C0Ϻι%Df%C3%E9

즉 , 비율이 가장 높은 a4 응용어플리케이션을 튜닝하는 것이 가장 효과적이라는 결론

을 얻을 수 있다 . 또한, a4어플리케이션을 튜닝하여 몇 배로 성능을 향상시키면 , 전체

적으로 임계성능사용률 (%) 이 얼마나 떨어지겠는가를 시뮬레이션 할 수도 있다 . 이처럼

통계적 관점에서 어떠한 어플리케이션을 튜닝하는 것이 가장 효과적인가를 찾는 방법

은 시스템 성능진단의 핵심에 가깝다 .

직관적으로 a4 어플리케이션이 “ 문제다 ”라는 사실을 인식하는 과정은 경우에 따라

보다 단순해 질 수 있다 . 튀어나오는 두더지를 고무 망치로 차례로 내리치는 두더지

게임과 같이 , 장애현상의 수면 위로 먼저 불거져 나오는 것이 a4 일 가능성이 매우

높기 때문이다 .

이 같은 상대적 성능장애의 유형을 사례별로 좀 더 세분화 시켜 보자 .

Case A. SQL 쿼 리 의 상 대 적 성 능 저 하 에 의 한 장

모 보험사의 모 CRM 시스템의 경우 , 시스템 오픈 첫날 , 동시단말사용자수가 100여명

에 이르기전 까진 그 어떤 성능장애 징후도 없었다 . 그러나 오전 10 시를 기점으로

120여명의 동시단말사용자수가 이르렀을 때 , 불과 1분 사이에 Active 서비스의 개수

가 급증하더니 급기야 시스템이 더 이상 응답을 전혀 주지 않는 행(hang)현상이 일

어났다 .

그 때 당시의 Active 서비스 목록을 확인한 결과 특정 어플리케이션 하나가 유독

WAS 시스템의 최대 Thread개수 100여 개에 꽉 차 있었다 . 또한 그 어플리케이션

은 전부 특정 테이블의 SQL쿼리를 수행 중에 있었고 , 해당 테이블엔 적절한 인덱스

가 달려있지 않음이 확인되었다 .

이 같은 상황을 그 즉시 인식할 수 있었던 것은 다음과 같은 항목을 모니터링하고

있었기 때문이었다 .

현재 접속된 동시단말사용자수는 몇 명인가 ? 어떻게 변해 가고 있는가 ?

29

Page 32: %Bc%Ba%B4ɰ%Fc%B8%Ae%Bdǹ%Ab%C1%F6ħ%Bc%Ad %C3ʾ%C8 %C0Ϻι%Df%C3%E9

Active 서비스의 개수는 몇 개고 , 현재 어떤 어플리케이션이 수행 중에 있는가 ?

현재 그 어플리케이션은 무엇을 수행하고 있는 중인가? SQL인가 ?

그 SQL문장은 무엇이고 , 응답시간은 얼마나 되는가 ?

현재 응답이 전반적으로 느린 SQL들간에 어떤 공통적인 요소가 발견되는가 ?

물론 , 그 SQL문장이 왜 동시단말사용자수가 증가함에 따라 느려졌는가는 시스템

엔지니어 및 DBA 의 몫일 것이다 .

Case B. 백 엔 드 (Backend) 트 렌 젝 션 의 상 대 적 성 능 저

하에 의한 장애

모 은행의 인터넷 뱅킹 시스템의 경우 , 메인프레임 /CICS/CORBOL 로 동작하고 있는

백엔드 시스템을 차세대 시스템 구축이라는 기치하에 전면적인 재개발 이후 시스템을

오픈하였다 . 백엔드 시스템만 변경되었고 , 앞 단의 Unix 기반에서 동작하는 WAS 시스

템은 백엔드와 연동하기 위한 인터페이스만 바뀌었을 뿐 전혀 수정된 것이 없었다 .

시스템에 오픈되고 1 시간이 채 못되어 , 동시단말사용자수 1,500 여명에 이르자 인터넷

뱅킹 시스템 전체가 느려지기 시작하고 서비스가 더 이상 불가능한 상황이 되었다 .

확인결과 백엔드의 CICS 트렌젝션 중 타행계좌이체가 상대적으로 성능이 느려졌다는

것이 곧바로 확인되었다 . 해당 어플리케이션 로직에 다소 문제가 있었다 . 특정 트렌젝

션 하나의 성능저하는 상대적으로 아주 짧은 시간이 채 지나지 않아 , 인터넷뱅킹 시

스템 전체에 영향을 미쳤다 . 백엔드와 연동되는 인터페이스의 대부분이 해당 트렌젝션

으로 꽉 막혔으니 , 정상적인 다른 거래조차 진입을 못하게 되고 대기상태 (waiting) 가

되었기 때문이다 .

이 것을 그 즉시 확인할 수 있었던 것은 , 앞서와 마찬가지로 다음과 같은 항목들이

모니터링 되고 있었기 때문이었다 .

현재 접속된 동시단말사용자수는 몇 명인가 ? 어떻게 변해 가고 있는가 ?

30

Page 33: %Bc%Ba%B4ɰ%Fc%B8%Ae%Bdǹ%Ab%C1%F6ħ%Bc%Ad %C3ʾ%C8 %C0Ϻι%Df%C3%E9

Active 서비스의 개수는 몇 개고 , 현재 어떤 어플리케이션이 수행 중에 있는가 ?

현재 그 어플리케이션은 무엇은 수행하고 있는 중인가 ? 백엔트 트렌젝션인가 ?

그 트렌젝션 명은 무엇인가 ? 응답시간은 어떠한가 ? 단위시간당 요청건수는 어떠한

가 ?

Case C. 특 정 어 플 리 케 이 션 의 상 대 적 성 능 저 하

에 의한 장애

모사이트의 대국민서비스를 위한 모시스템의 경우 , 2-3 일에 한번씩 성능장애가 일어났

다 . 특별한 장애시간대가 있는 것도 아니고 , 지난 몇 주간의 동시단말사용자수의 변화

와 장애발생시점은 그 어떤 연관관계로 없었다 . 불특정 시간에 갑작스럽게 장애는 발

생했다. CPU사용률이 몇십초간 100%를 치는가 싶더니 그 이후론 오히려 CPU 사용

률이 비정상적으로 떨어졌다 .

확인 결과 어플리케이션 중 보험료 시뮬레이션이 있는데 , 20년 장기 조건을 넣었을

겨우 , 어플리케이션의 로직 미비로 CPU 를 100%가까이 소모하는 로직을 타게 된

것이 원인이었다 . 해당 어플리케이션이 일단 호출되면 CPU 100% 현상이 몇 십 초간

발생하게 되고 , 동시단말사용자수 750명이 1초당 30 여 tps 의 호출빈도를 보이고

있는 상황에서 정상적인 서비스조차 모두 응답이 느려지고 , 불과 10 여초 사이에

300여개의 Active 서비스개수 증가를 야기시킨 것이다 . 비록 문제의 해당 어플리케이

션이 10 여초 후에 끝났더라도 300여개의 Active 서비스개수 증가는 WAS 시스템

튜닝의 미비로 인해 Thread경합이 발생하여 정상적인 복구를 할 수가 없었던 것이

다 . 1 초당 30 개씩 밀려오는 요청 속에서 이미 300개가 쌓여 있으니 , 그것 처리하

랴 , 들어오는 것 처리하랴 , 그 와중에 WAS 에서 너무 높게 설정된 Thread Max값은

Thread경합까지 일어나 재 성능조차 못내는 Bucklezone 에 빠져들었기 때문이다 .

해당 현상을 분석하는 과정에서 , 만약 불과 그 10 여초 동안 일어난 상황을 놓쳐버

리면 , 결과론적으로 보이는 현상은 문제의 어플리케이션은 보이지 않고 , 극히 정상적인

어플리케이션들이라고 여겨지는 불특정 다수의 어플리케이션들만 300여개가 쌓여 있는

형국만 보이게 된다 . 자칫 핵심을 놓칠 수 있는 상황이었다 .

이 상황을 신속하게 판단할 수 있었던 것은 다음과 같은 항목을 모니터링 하고 있

었기에 가능했다 .

31

Page 34: %Bc%Ba%B4ɰ%Fc%B8%Ae%Bdǹ%Ab%C1%F6ħ%Bc%Ad %C3ʾ%C8 %C0Ϻι%Df%C3%E9

CPU사용량이 급증한 것이 몇 시 , 몇 분 , 몇 초부터인가 ?

장애근방에 동시단말사용자수 및 호출빈도(tps)는 얼마였던가 ?

특별히 그 시간 근방에 CPU를 많이 소모한 어플리케이션이 무엇인가 ? 해당 어

플리케이션은 얼마나 CPU시간을 점유했던가 ?

해당 어플리케이션이 종료된 시점부터 전체적인 CPU사용률은 떨어졌는가 ?

해당 어플리케이션이 불려진 이후부터 Active 서비스개수가 덩달아 급증했던가 ?

Case D. 전 반 적 인 어 플 리 케 이 션 의 상 대 적 성 능

저 하 에 의 한 장 애

앞서의 경우처럼 특정 어플리케이션이 두더지 게임처럼 불거져 나오는 경우는 성능장

애진단관점에서는 매우 쉽다 . 적절한 항목들을 모니터링만 할 수 있다면 , 어떤 어플리

케이션이 문제인가를 직관적으로 판단할 수 있기 때문이다 .

그러나 , 지금 이야기하는 상황은 사뭇 다르다 . 모쇼핑몰 시스템의 경우 , 동시단말사용자

수가 2,300 여명이 이른다 . 간간이 응답이 3초이상 걸리는 느린 어플리케이션도 있지

만 , 상대적으로 서비스 호출빈도가 낮기에 해당 어플리케이션은 문제가 아니었다 . 대부

분의 SQL응답시간도 0.5초로 매우 짧다 . 어플리케이션들의 응답시간도 1초미만으로

매우 짧았다 . 그럼에도 불구하고 동시단말사용자수가 2,000 여명으로 넘어서면 Active

서비스의 개수가 급증하고 불특정 다수의 어플리케이션들이 서비스큐잉되어 사용자 체

감 응답시간은 불과 몇 분 사이에 느려지기 시작했다 . 아무리 찾아도 성능저하를 보

이는 특정 어플리케이션이 도출되지 않았다 . CPU 사용률 및 메모리 , 네트워크 이슈도

아니었다 .

여기서 간과하지 말아야 할 부분이 , 우리들에게 익숙한 단위의 수치에 관행적으로 얽

매이지 말아야 한다는 것이다 . 아니 응답시간이 1초미만인데 뭐가 문제죠? SQL쿼리시

간도 0.5초 미만인데 뭐가 문제죠? 이는 마치 , 단거리 육상선수가 100M를 9.9초

에 돌파하는데 왜 1등을 못하느냐고 우문을 던지는 것과 같다 . 1 등은 9.8초에 돌

파했기 때문이다 .

시스템의 성능은 단위시간당 밀려들어오는 호출빈도(arrival rate)와 단위시간당 최대 처

32

Page 35: %Bc%Ba%B4ɰ%Fc%B8%Ae%Bdǹ%Ab%C1%F6ħ%Bc%Ad %C3ʾ%C8 %C0Ϻι%Df%C3%E9

리가능건수 (service rate) 사이에서 항상 상대적이다 . 모 고객사를 위한 대규모 벤치마크

테스트를 시행한 적이 있었다 . 목표는 1초당 2,000tps 였다 . 그런데 튜닝이 진행되고

있는 당시 1,500 tps밖에 나오지 않았다 . 그 때 당시의 어플리케이션의 평균응답시간

은 0.02 초였고 , 모든 SQL의 평균응답시간은 0.01 초 미만 이었다 . 이처럼 수치의

단위가 우리들에게 익숙한 단위가 아닌 매우 작은 단위로 내려가기 시작하면 머리

속에서 감성적으로 판단할 수 있는 단계를 뛰어넘게 된다 .

그럼에도 불구하고 Active 서비스의 개수는 동시단말사용자수가 무한히 증가함에 따라

어느 한계 지점에 이르게 되면 급증하게 된다 . 그 한계점이 현재 운영되고 있는 시

스템에서 나타났고 , 어떤 어플리케이션을 튜닝하는 것이 가장 효과적이겠는가를 찾아야

하는 것이다 . 이 시점에서 접근할 수 있는 방법이 앞서 [상대적 성능장애 ]에서 기

술한 임계성능사용률을 계산하여 통계적 기법으로 접근하는 것이다 .

문제의 그 사이트는 그렇게 접근하여 상위튜닝대상 어플리케이션을 20 여개 선정하고

스트레스테스트과정을 거치면서 프로그래밍 소스에서의 미세한 병목지점을 다음과 같은

기법으로 발견해 내었다 .

해당 어플리케이션의 소스에서 각 block별로 평균응답시간을 측정할 수 있도록

trace 를 걸었다 . 모든 응답시간을 찍지 않고 , 1 초에 한번씩 구간별 통계적 평균응답

시간만 기록토록 했다 .

스트레트테스트 툴을 이용하여 가상사용자수 (Virtual User) 를 대기시간 (Thintime) 0초로

설정하여 점차적으로 가상사용자수를 증가시켰다 . 그리고 가상사용자수 증가 따른 각

구간별 평균응답시간을 아래의 도표와 그래프로 표현했다 .

33

Page 36: %Bc%Ba%B4ɰ%Fc%B8%Ae%Bdǹ%Ab%C1%F6ħ%Bc%Ad %C3ʾ%C8 %C0Ϻι%Df%C3%E9

여기서 주목할 부분은 가상사용자수 14-16명이 되기 전까지의 자료만 보면 , 구간 C

가 0.09 초로 다른 구간에 비해 평균응답시간이 가장 느렸다 . 가상사용자수를 지속적

으로 증가시키지 않고 , 단지 고정된 10 명의 사용자로 단 한번의 테스트만을 치른

후 , 자칫 잘못 판단하면 “아하 , 구간C가 문제였군 ”이라는 오판을 하게 된다 . 그러나

가상사용자수가 증가함에 따라 다른 구간에 비해 응답시간이 더 빠른 속도로 느려지

는 구간은 사실 구간D임을 알 수 있다 . 반면 구간C는 항상 일정한 0.09 초를 보

이고 있기 때문에 , 단위시간당 최대처리건수의 한계점에 영향을 미치는 수치가 아니었

위 구간별 평균응답시간의

그래프에 덧붙여 단위시간당

처리건수의 그래프를 합성하

면 다음과 같다 . 가상사용자

34

Page 37: %Bc%Ba%B4ɰ%Fc%B8%Ae%Bdǹ%Ab%C1%F6ħ%Bc%Ad %C3ʾ%C8 %C0Ϻι%Df%C3%E9

14 명에서 최대 50tps를 보인 이후 더 이상 처리능력이 올라가지 않으며 , 그 때부

터 구간D의 응답시간이 가장 빨리 느려지는 것이 확인된다 .

이러한 유형의 성능이슈는 일정한 동시단말사용자수의 증가로 인해 한계성능을 들어내

기 전까지 결코 도출되지 않는다 . 또한 특정 시점에서의 구간별 평균응답시간의

snapshot 만으로 판단하기는 완전하지 않다 . 이 같은 성능장애현상이 발생하고 있는

시점에서 구간별 응답시간을 기록해 보았더니 , 위 그래프상에서 가상사용자 14-26명

사이의 snap shot 한 두개를 확보했다고 가정해보면 , 구간 A, 구간F 및 구간C도 구간D

만큼이나 평균응답시간이 느리다 . 어디가 문제인지를 그 snap shot 하나로는 부족하다 .

특히 단위가 미세할 경우는 더욱 직관적인 판단이 어렵다 . 이론적으로는 어떤 시점에

서의 정적인 평균응답시간은 최대처리가능건수와 직접적인 비례관계에 있지 않으며 , 평

균응답시간의 변화량이 핵심이라는 것을 강조한다 .

차후 성능분석단계로 진입하기 이전에 이 같은 상황을 모니터링함에 있어서 도움이

될 법한 모니터링 항목은 다음과 같다 .

동시단말사용자수는 어떻게 변화하고 있나 ?

단위시간당 처리건수 (TPS) 는 어떻게 변화하고 있나 ?

Active 서비스개수는 어떻게 변화하고 있나 ? 특히 어떤 어플리케이션이 표면에 나

타나는가 ?

구간별 평균응답시간은 어떻게 변화하고 있나 ? ( 특정 snap shot하나로는 부족하다)

동시단말사용자수는 계속 증가하는데 , TPS 는 더 이상 증가하지 않으면서 , 평균응

답시간은 특정 구간에서 다른 구간들 보다 더 빨리 증가하고 있는가 ?

2.4 조 건 적 성 능 장 애 (Conditional Performance Problem)

조건적 성능장애 (Conditional Performance Problem)은 특정 조건 상황에 이르기 전까지

극히 정상적인 서비스를 수행하게 된다 . 시한폭탄처럼 시간이 딱 정해져 있지는 않지

35

Page 38: %Bc%Ba%B4ɰ%Fc%B8%Ae%Bdǹ%Ab%C1%F6ħ%Bc%Ad %C3ʾ%C8 %C0Ϻι%Df%C3%E9

만 , 조금씩 조금씩 장애현상이 발생할 원인을 누적시켜 나간다 . 그리고 어느 순간이

되면 , 정상적인 서비스를 수행할 수 없는 상황이 도래한다 . 사례별로 하나씩 짚어보자.

Case E. JDBC Connection/Statement/ResultSet 리 소 스 미 반 환 에

의 한 장 애

꼼꼼하지 않은 프로그래머에 의해 개발된 국내 상당수의 사이트에서 성능장애의 70-

80% 이상을 차지하는 아주 대표적인 유형의 조건적 성능장애 유형이다 .

데이터베이스의 SQL쿼리를 실행하려면 JDBC(Java Database Connectivity) API 를 사용해

야 하는데 , java.sql.Connection을 확보하여 관련 작업을 수행 후에는 반드시 리소드

반환 (conn.close() 등 ) 을 하여야 한다 . 왜냐면 Connection 과 같은 객체는

GC(Garbage Collection) 시점에 명시적으로 close() 라는 메소드를 자동으로 호출시켜주

는 것이 아니기에 GC 의 대상이 되지 않기 때문이다 20 . 특히 JDBC Connection

Pool21을 사용하고 있을 경우는 어플리케이션에서 JDBC 연결을 사용한 후 반환하지

않으면 해당 Connection 은 pool로 돌아가지 않기에 다른 서비스요청에서 사용될 수

없게 되고 , pool에 가용한 연결의 개수가 점차 고갈되어 , 특정 시점부터는 더 이상

가용한 연결을 얻을 수 없게 되는 상황이 벌어진다 .

또한, java.sql.PreparedStatement, java.sql.Statement 역시 사용 후에는 반드시 close() 를

해 주어야 한다 . 그렇지 않을 경우 , 데이터베이스의 오픈된 CURSOR 가 증가함과 동

시에 JVM 의 힙 메모리 증가를 야기하게 된다22 . java.sql.ResultSet 역시 마찬가지이

다23 . 이처럼 야금야금 누수된 Statement미반환 건수는 각 데이터베이스의 특성에 따

라 때론 “ Open Cursor Exceed” 와 같은 SQL예외사항 (SQLException) 을 발생시키거

20 IBM웹스피어5.0/6.x, 웹로직8.x과 같이 일부 WAS서버는 어플리케이션에서 명시적으로

Connection을 close하지 않더라도, 어플리케이션로직이 끝날 때 자동으로 반환시켜 주기도 한다.21 JDBC Connection Pool: 데이터베이스서버와의 물리적인 TCP/IP연결은 상대적으로 부담스러운

절대적 응답시간을 필요로 한다. 그렇기에 미리 JDBC연결을 pool상에서 연결시켜두고, 어플리케이

션의 요청이 있을 때, 곧바로 가용한 연결을 제공함으로써, 물리적인 TCP/IP연결에 따른 부담을 해

결하는 기법을 일컫는다.22 Statement/PreparedStatement 등은 JDBC Connection이 물리적으로 close될 때 함께 close되는

것이 일반적이지만, WAS서버의 경우 Connection의 close()는 물리적인 연결이 닫히는 것이 아니라

Connection Pool로의 복귀가 일어나기 때문에 Connection의 close가 PreparedStatement 의 close

를 보장하지 않게 된다. 23 ResultSet역시 일반적으로 Statement/PreparedStatement가 close될 때 함께 close되는 것이 일

반적이지만, WAS서버에서는 PreparedStatement에 대한 캐싱(Caching)을 사용하기 때문에,

Statement의 close가 반드시 ResultSet의 close를 보장하지 않는다.

36

Page 39: %Bc%Ba%B4ɰ%Fc%B8%Ae%Bdǹ%Ab%C1%F6ħ%Bc%Ad %C3ʾ%C8 %C0Ϻι%Df%C3%E9

나24 , 데이터베이스 프로세스의 메모리점유량을 증가시키게 된다25 .

예를 들면 , 모사이트의 모시스템은 사용자가 4,500명 정도 다녀가고, peak시에도 최대

동시단말사용자수는 25 명 , 2-3 tps 정도의 부하량을 보이고 있는 상대적으로 부하량이

작은 사이트였다. 서비스 기동 후 한 2-3일이 지나면 정상적인 서비스를 수행하지

못하고 , NullPointerException 을 발생시켰다. WAS서버로 운영 중인 Tomcat 을 재기동시

키면 또 앞으로 2-3일은 버틴다 . 확인 결과 자주 불려지지는 않으나 특정 어플리

케이션에서 JDBC Connection Pool 에서 가져온 후 이를 반환하지 않는 것으로 드러났

고 , 그 어플리케이션이 JDBC Connection Pool 에서 최대 수치로 지정된 횟수만큼 불려

진 이후로는 더 이상 가용한 연결을 꺼내올 수 없게 되어 null 값이 나오게 되는

것이었다 . 해당 사이트에서는DBConnectionManager라는 종류의 JDBC Connection Pool 을

사용하고 있었는데 , 이처럼 최대값이 도달하면 새로운 연결을 시도하지 않고 null값을

제공토록 설정되어 있었다 .

또 다른 모사이트의 경우는 상대적으로 부하량이 높은 사이트였는데 , 서비스 후 5-8

시간이 지나면 더 이상 응답이 없거나 무지 느려지는 현상이 일어났다 . 확인 결과

특정 어플리케이션에서 Connection 을 제대로 반환하고 있지 않았었다 . JDBC Pool 에

설정된 최대값에 도달하면 최대로 10 초동안 waiting하도록 셋팅되어 있었는데 , Pool

에서 가용한 연결이 모두 소진되는 순간부터 모든 요청이 10 초동안 waiting하기

때문에 순식간에 다량의 어플리케이션들이 적절한 응답시간을 제공해 주지 못하고 ,

Active 서비스의 개수를 증가시킨 형국이었다 .

앞서 두 경우 모두 , 어플리케이션 로직에서 제대로 Connection 을 반환시키지 않았기

때문에 나타난 현상이지만 , JDBC Connection Pool 의 종류 및 셋팅 상태에 따라 시스

템의 결과론적인 장애반응은 다르게 나타날 수 있다 .

또 다른 모사이트의 경우는 어플리케이션에서 Statement/PreparedStatement 를 제대로

반환시키지 않아 , 일정 서비스 후부터 관련 SQL수행작업에서 “ open cursor exceed”라

는 SQLException을 간헐적으로 발생시켰다 . 데이터베이스에서 설정된 초대

OPEN_CURSOR 개수만큼 , 해당 JDBC Connection 에서 열려진 Statement를 제대로

close 하지 않게 되면 , 해당 Connection 으로는 더 이상 정상적인 SQL작업을 할 수

없게 되는 것이다 . JDBC Connection Pool 상에서 어떤 JDBC Connection 이 더 빨리

24 Oracle의 경우가 그러하다.25 IBM DB2의 경우가 그러하다.

37

Page 40: %Bc%Ba%B4ɰ%Fc%B8%Ae%Bdǹ%Ab%C1%F6ħ%Bc%Ad %C3ʾ%C8 %C0Ϻι%Df%C3%E9

cursor 개수를 증가시켰느냐에 따라 , 때론 정상적인 결과가 나올 때도 있고 , 때론

SQLException을 발생시킬 때도 있었던 것이다 .

결국 , 이 같은 류의 조건적 성능장애를 미연에 방지하려면 다음과 같은 항목을 모니

터링할 필요성이 절대적으로 존재하게 된다 .

JDBC Connection 미반환 추적이 가능한가 ?

JDBC Statement/PreparedStatement/CallableStatement 미반환 추적이 가능한가 ?

JDBC ResultSet 미반환 추적이 가능한가 ?

어떤 어플리케이션 , 어떤 메소드 , 어떤 SQL과 관련된 어플리케이션에서 발생하였

는가 ?

Case F. 메 모 리 누 수 에 의 한 장 애

메모리 누수 현상은 어지간해서는 개발자의 J2EE 어플리케이션에서는 발생하지 않는

다 . 클래스로더(ClassLoader) 및 Thread 프로그래밍 등 상대적으로 고급스런 (?) 어플리케

이션 구현시에 발생하게 된다 . Java는 기본적으로 Object 를 생성하고 특별히 그

Object 의 인스턴스 (instance)가 사용했던 메모리에 대해서 C나 C++ 처럼 메모리해

제에 관련해서 코딩할 필요가 없다 . 그 Object 의 인스턴스를 그 어떤 Thread도

더 이상 참조하고 있지 않을 때 , Garbage Collector 에 의해 자동으로 반환되기 때문

이다 . 그러나 , 미비한 코딩을 했을 경우는 그 Object 가 여하 한의 Thread에서 더

이상 사용되고 있지 않음에도 불구하고 참조 (reference) 가 특정 Thread사엥 남아

있다면 그 Object 는 GC 의 대상이 되지 못하고 , 계속 메모리 누수로 남아있게 되

는 것이다 .

메모리 누수현상을 근본적으로 잡으려면 어떤 Thread, 어떤 어플리케이션이 어떤 객체

를 생성했고 , 언제 GC 에 의해 얼마나 반환되었는지를 JVMPI라는 프로파일링

(profiling)기법을 사용해야만 가능하다 . 그러나 JVMPI기법은 설정을 enable 시키는 것

만으로도 ( 상대적으로 ) 극심한 성능저하를 일으키기 때문에 , 부하량이 매우 높은 운영

중인 서버에 적용하는 것은 신중을 기해야 한다 .

38

Page 41: %Bc%Ba%B4ɰ%Fc%B8%Ae%Bdǹ%Ab%C1%F6ħ%Bc%Ad %C3ʾ%C8 %C0Ϻι%Df%C3%E9

경험적으로 대부분의 메모리 누수에 의한 조건적 성능장애는 JVM 의 버그, WAS제품

의 버그 , 특정 JDBC 드라이버의 버그 , 특정 회사의 패키지 모듈의 버그에 기인하였

다 . 물론 간혹 모 사이트의 경우처럼 , 데이터베이스 처리 결과를 메모리공간에 담아두

고 (cache), 동일한 요청이 발생했을 때 메모리 공간에서 곧바로 결과값을 돌려주는

메커니즘을 사용할 때 , 이를 적절하게 지속적으로 메모리가 증가하지 않도록 제거해

주는 로직을 첨가했어야 함에도 불구하고 마냥 밀어넣기만 한 경우도 있었다 . 그러니

시간이 지나면 지날수록 계속 자바의 힙 메모리는 증가했던 것이다 .

이러한 메모리 누수에 의한 조건적 성능장애 현상을 해결하기 위해서는 부하량이 높

지 않은 개발 시스템에 모니터링 제품을 적용하는 것은 상대적으로 별도 도움이 되

지 않는다 . 실제 메모리 누수현상을 목격하고 있는 실 운영서버에 적용하여야만 의미

있는 결과를 낼 수 있다 . 그러나 운영서버는 부하량이 높아 JVMPI기법을 사용하고

있는 모니터링 툴을 적용하기엔 또한 부담이 따를 수 있다 . 만약 , 여러 대의 서버로

운영 중이라면 그 중 부하량을 의도적으로 낮추어 특정 한 두 대의 서버에 적용하

는 것도 한가지 기법이다 .

반면, OS가 IBM AIX라면 특별한 기법을 사용치 않더라도 IBM JDK 가 기본적으로 제

공하고 있는 HeapDump 라는 메커니즘을 이용하면 , 어떤 객체가 얼마만큼 힙메모리를

사용하고 있는지 매우 쉽게 분석가능하다26 . IBM JDK는 OutOfMemoryError 가 발생하

면 heapdump라는 파일을 떨어뜨려 주고 , 이를 IBM이 제공하는 HeapRoot 혹은

HeapAnalyzer라는 도구를 이용하여 누구나 분석할 수 있다27 .

혹은 JVM 프로파일링 기능을 제공하는 APM 제품 중에는 자바힙메모리누수를 잡아주

기는 제품들이 있다 . 그러나 , 운영 중에 적용하기엔 성능저하가 발생하고 , 실 운영중인

서버에 적용하지 않으면 메모리누수현상 자체가 제대로 감지되지 아니하니 , 이러지도

저러지도 못하는 경우가 있기는 하나 , 클러스트링되어 운영되는 여러 대의 서버로 부

하량을 분산시킨 후 한대 정도에 적용하여 모니터링 하는 것도 한가지 방법일 것이

다 .

지속적인 메모리 증가현상이 야금야금 어디선가 메모리 누수(memory leak)이 일어났든

혹은 프로그램 내 캐싱 (caching) 기법에 의해 발생되었든 혹은 제품의 버그 (bug) 에

의한 것이든 , 해당 현상이 메모리관련된 이슈인가를 우선적으로 판단하는데 도움이 되

26 최근 IBM의 HeapDump 모듈은 비단 AIX뿐만 아니라, Sun Solaris OS에 포팅이 진행중이며, 현재

테스트용도로 사용할 수 있다.27 IBM JDK는 AIX, Windows, Linux용만 제공하고 있다.

39

Page 42: %Bc%Ba%B4ɰ%Fc%B8%Ae%Bdǹ%Ab%C1%F6ħ%Bc%Ad %C3ʾ%C8 %C0Ϻι%Df%C3%E9

는 모니터링 항목은 다음과 같다 .

자바힙 (heap) 메모리를 실시간 관찰가능한가 ? 또한 일자별로 추적가능한가 ?

실시간 Active 서비스의 목록과 힙메모리의 증가에 따른 직관적인 파악이 가능한

가 ?

명시적으로 Full GC 를 발생시켜, GC이후에 실제 힙메모리 사용량을 그 즉시 확

인할 수 있는가 ?

비단 JVM내부의 힙메모리 뿐만 아니라 , 시스템 OS 관점에 바라본 해당 JVM프

로세스의 메모리 점유량을 함께 모니터링 가능한가 ?

자바의 힙메모리누수현상은 이처럼 상대적으로 찾기가 쉬울 수 있다. IBM HeapDump를

이용하거나 , 혹은 APM 제품을 이용하면 되기 때문이다 . 반면 , 자바의 힙메모리가 아니

라 , 네이티브 (native)메모리 누수일 경우는 원인을 찾기가 만만치 않다. Unix의 top 이

나 ps 명령을 통해 해당 프로세스 (process) 가 점유하고 있는 RSS(Real Memory

Size) 혹은 SIZE(RSS+Pageing된 메모리합 ) 값이 지속적으로 증가한다면 네이티브메모리

누수를 의심해 볼 수 있다 .

Case G. 시 스 템 /WAS 튜 닝 미 비 에 의 한 성 능 장 애

만약 , JDBC Connection Pool 의 최대 개수, WAS의 최대 Thread 개수, Backend 트렌젝션

서비스의 최대허용개수 등을 기형적으로 누군가 작게 설정해 두었다고 가정해 보자 .

어떤 현상이 일어날까?

만약 , 최대값에 도달했을 때 추가적인 요청은 waiting하게 설정되어 있다면 , 일정 부

하량이 증가함에 따라 추가적인 요청은 모두 해당 자원을 얻기 위해 대기하는 과정

에서 전체적으로 Active 서비스의 개수가 증가하게 될 것이다 . 대부분의 모듈들은 그

같이 waiting하는 시간을 관리자에게 지정토록 제공하고 있다 . 어느 정도의 수치가

40

Page 43: %Bc%Ba%B4ɰ%Fc%B8%Ae%Bdǹ%Ab%C1%F6ħ%Bc%Ad %C3ʾ%C8 %C0Ϻι%Df%C3%E9

가장 적절한 waiting시간일까 ?

반면 , 최대값에 도달했을 때 추가적인 요청은 곧바로 Reject되도록 설정되어 있다면 ,

추가적인 요청은 그냥 곧바로 Reject되면서 단지 정상적인 서비스가 되지 않을 것이

다 .

각 지점의 최대값 설정을 위한 기본적인 가이드는 해당 어플리케이션들이 “단위시간

당 최대한 많은 처리건수를 보이는 가장 작은 값 ”을 설정하는 것이다 . 단위시간당

최대한 많은 처리건수를 보이는 때가 몇 개일지는 사이트마다 , 시스템 마다 다르니

특정 수치를 가이드 할 수는 없다 . 그러나 , 경험적으로 보면 , 일반적인 시스템 관리자

는 그 수치를 무조건 높여주는 경향이 있으나 , 높다고 좋은 것이 아니다 . 너무 높으

면 , 부하량이 증가했을 때 , 원래 제 성능조차 내지 못하는 Bucklezone 이 발생하게

된다 .

이러한 경우를 어떻게 모니터링하면 어느 지점이 병목인지를 아닌지를 곧바로 확인할

수 있을까? 특정 지점에 병목일 경우는 해당 지점을 통과하려는 Active 서비스의 개

수가 증가하는 현상으로 나타날 것이다 . 따라서 , 설정가능한 각 지점의 Active 한 서

비스의 개수를 지속적으로 모니터링 하는 것이 너무나 중요하다 .

튜닝을 위한 이러한 수치 설정을 위해서는 경험적 감각에 의존하는 것도 중요하지

만 , 해당 사이트에서 운영되는 시점에 실측 데이터를 활용해야만 한다 . 실측 데이타를

확인하려면 운영 중인 시스템에서 다음과 같은 항목들이 모니터링 되고 있어야 할

것이다 .

동시단말사용자수는 지난 몇 달 , 혹은 지난 몇 주간 어떻게 변화해 왔는가 ?

WAS 의 Thread개수 조정을 위해 , Active 하게 서비스하고 있는 개수의 변화는

어떠했는가 ?

각 지점별 ,( 예: JDBC Active SQL수 , Backend Active 트렌젝션 개수 ) 등의 변화는 어떠

했는가 ?

월중 , 주간별 , 일자별 최대 peak시간대에서의 위 개수 및 CPU사용률 변화는 각

시스템별로 어떠했는가 ?

41

Page 44: %Bc%Ba%B4ɰ%Fc%B8%Ae%Bdǹ%Ab%C1%F6ħ%Bc%Ad %C3ʾ%C8 %C0Ϻι%Df%C3%E9

물론 WAS 의 튜닝영역은 매우 광범위하고 다양하다 . JVM 옵션설정 , JVM의 힙메모리

조정 , JDBC Connection Pool 의 최대 / 최소 수치 , 연결제한시간(connectionTimeout, 유휴제

한시간 (idleTimeout), WAS Thread Pool 의 Thread Lifetime, connectionTimeout, 웹서버의

최대 / 최소, KeepAliveTimeout, 웹서버와 WAS 사이의 연결 시에 필요한 각종 설정 등

장애상황에 따라 하나하나가 의미를 갖고 있다 . 이러한 수치들은 대부분 상용 WAS

제품 자체가 제공하는 Viewer 를 이용하여 항시 모니터링 할 수 있다 . 그러나 , 그

수치를 해석하고 분석하여 장애상황에 따른 의미를 간파하지 않는 한 , 이러한 각종

수치를 APM 툴들이 단지 또다시 그냥 보여주고 모니티링하는 것만으로는 충분하지

않다 . 또한 늘여야 할지 줄여야 할지에 대한 판단은 때론 그렇게 직관적이지만은 않

기 때문이다 . 이러한 분야는 해당 WAS 제품을 납품하는 업체로부터 전문적인 기술지

원을 받기를 적극 권고한다 .

Case H. JVM/WAS/JDBC 등 제품의 버그에 기인한 장애

모든 제품은 결함 (bug) 가 있기 마련이다 . 그 결함이 시스템 운영에 심각한 영향을

미치지 않기를 바랄 뿐이다 . 하물며 WAS 제품의 기반이 되는 JVM 조차 버전이 올

라감에 따라 각종 메모리누수현상 (memory leak), 바이트코드 (byte code) 를 런타임시에

parsing하여 컴파일하는 과정에서의 JIT(Just In-time) 컴파일러 결함 등 지난 6-7년

간을 돌이켜 보면 시스템 운영에 심각한 영향을 미치는 결함들이 새롭게 발견되고

패치가 끊임없이 나왔었다 . WAS 또한 , 어느 상용 WAS 할 것 없이 3-6개월에 한번

씩 결함을 수정한 공식 패치버전이 나왔었다 .

결국 자사의 시스템을 운영하고 모니터링하는 관점에서는 해당 현상이

JVM/WAS/JDBC드라이버 등 제품의 결함에 의한 것인지 아닌지를 신속하게 선별하는

방법이 필요하다 .

JVM JIT컴파일러의 결함에 의한 JVM 프로세스 다운과 같은 유형은 프로세스

다운시에 JVM이 남겨주는 JVM Stack Trace 및 시스템 core 파일을 확보해 두는

것이 중요하다 . JVM Stack Trace 의 경우 , IBM JDK 의 경우는

javacore.<pid>.<timestamp>.txt라는 파일로 생성되고 , Solaris/HP-UX 의 경우는 통상 해

당 WAS 의 표준에러파일 (stderr)에 기록된다 . JIT 컴파일러에 의한 JVM 다운은

JIT 컴파일러의 최적화 알고리즘의 버그에 기인하는 경우가 많은데 , 해당 클래스

의 메소드 부분만 JIT 컴파일링을 제외시킴으로서 임시 대처가 가능한 경우가

있긴 하지만 근본적으로는 해당 JVM을 제공하는 업체의 기술지원을 받아야 한

다 .

42

Page 45: %Bc%Ba%B4ɰ%Fc%B8%Ae%Bdǹ%Ab%C1%F6ħ%Bc%Ad %C3ʾ%C8 %C0Ϻι%Df%C3%E9

JNI(Java Native Interface) 기법을 사용하는 일부 보안패키지 제품의 경우 JNI 를 통

해 C 언어로 처리하는 메커니즘에서 메모리 핸들링이나 포인터 (pointer) 연산을 잘

못했을 경우 , JVM 전체를 다운시키기도 한다 . 최근엔 대부분 매우 안정화 되었으

나 지난 몇 년 전에는 이로 인한 장애가 심심찮게 발생하기도 하였다 . 이 경

우 역시 JVM StackTrace 나 시스템 core 파일에 장애를 유발시킨 모듈의 위치가

대부분 담겨 있다 .

JVM/WAS/JDBC 드라이버 등의 제품도 결국 자바언어로 기술된 제품으로서 , JVM

메모리누수(memory leak)과 같은 제품의 결함을 안고 있을 수 있다 . 지속적으로

메모리가 증가하는지 모니터링 하고 , 자바 힙메모리의 누수인지 , native 메모리 누

수인지를 우선적으로 선별해야 한다 . 자바 힙메모리 누수의 경우는 상대적으로

원인을 밝히기가 쉽지만 , native 메모리누수의 경우는 상대적으로 원인을 찾기가

쉽지 않다 . 어플리케이션 수행 전후를 기점으로 native 메모리 증가량을 통계화해

주는 APM 툴이 있다면 장애진단에 큰 도움이 될 것이다 .

WAS 제품 역시 경우에 따라 특정 모듈 별로 대규모 부하량을 견뎌낼 수 있

는 성능 및 확장성을 적절하게 제공할 수도 , 그렇지 않을 수도 있다 . 모

WAS 의 경우는 하나 이상의 데이터베이스 간에서 2PC(Phase Commit) 트렌젝션

처리를 위한 XA 연동에서 상대적으로 성능이 저하되기도 하며 , 어떤 WAS 의

경우는 EJB CMP 기반에서의 운영 시에 성능이 상대적으로 저하되기도 한다 . 모

WAS 의 경우는 웹서버와 WAS 서버 사이의 연동 시에 고려되어야 할 필수

제어 파라메터가 존재하지 않기도 하며 , 어떤 WAS 서버의 경우는 JDBC

Connection Pool 구현 부에 N/W 장애나 방화벽을 사이에 두고 일어날 수 있는

특정 장애현상을 극복하는 파라메터가 존재하지 않아 데이터베이스의 연결 개수

가 시간이 지남에 따라 기형적으로 증가되는 경우도 있다 .

이러한 유형의 장애 현상을 매우 쉽게 판별할 수 있는 표준적인 모니터링 / 분석 가

이드는 솔직히 일반화 되기 어렵다 . N/W부터 OS 시스템 , 데이터베이스 , WAS 등 인프

라기술에 대한 경험과 어플리케이션 개발 기술 및 비즈니스 업무를 상당 부분까지

이해하는 실력있는 엔지니어의 지속적인 관심과 모니터링이 가장 핵심적이라고 하면

너무 무책임한 표현일까 . 실로 오늘날의 시스템 복잡도 및 장애 유형은 과거 그 어

느 때 보다 다양하지 않던가 .

43

Page 46: %Bc%Ba%B4ɰ%Fc%B8%Ae%Bdǹ%Ab%C1%F6ħ%Bc%Ad %C3ʾ%C8 %C0Ϻι%Df%C3%E9

Case I. WAS/Framework 등의 Thread Lock/Deadlock에 기인한 성능

장 애

JVM 은 단일 프로세스상에서 여러 개의 Thread가 기동되어 운영되는 Multi-thread

모델이다 . 서로 다른 Thread가 같은 객체의 변수 등과 같은 자원을 동시에 접근할

경우는 그 리소스의 동시성 이슈를 극복하기 위해 ( 자바언어에서는 ) synchronized 블

록을 이용하여 제어하게 된다 . synchronized 블록은 특정 lock(혹은 monitor)을 가진

단 하나의 Thread만 진입할 수 있으며 , lock을 획득하기 전까지 해당 블록에서 진

입대기하고 있게 되는데 , 이 같은 Thread의 상태를 MW(Monitor Wait)이라 부른다 .

synchronized 블록에 진입한 Thread는 필요에 의해 lock.wait()를 통해 자신의 lock

을 다른 Thread가 사용할 수 있도록 반환하켜 줄 수 있다 . lock.wait()에 대기 중

인 Thread의 상태를 CW(Condition Wait) 이라 부른다 . CW 상태인 Thread는 다른

Thread가 lock.notity()를 해 줄 때 비로소 깨어날 수 있다 .

이러한 Thread Lock 메커니즘은 JDBC Connection Pooling과 같이 특정 서비스의 동시

실행 개수를 제어하려 할 때 사용되곤 한다 . 자바라는 언어에서는 상대적으로 대단히

쉽게 구현 가능하기 때문에 , 이러한 기법은 개발자의 코드에서도 필요에 의해 종종

사용되며 특히 Framework 를 설계할 때는 자주 사용되는 기법이기도 하다 . 그러나

쉽게 사용할 수 있는 기법인 반면에 대단히 주의하여 구현하지 않으면 , 성능 저하라

든가 혹은 Deaklock28과 같은 상태에 빠질 수도 있다 .

특정 synchronized 블록의 성능 저하는 해당 블록의 응답 시간 및 CPU 사용시간

등을 측정할 수 있는 프로파일링 기법과 스트레스 테스트를 통해 목표 성능을 확인

하는 과정에서 비로소 검증될 수 있다 . 혹은 성능 저하가 극심한 상황에서 JVM 의

snapshot 에 해당하는 javacore 를 획득하여 각 Thread의 수행 위치를 확인함으로

써 , Thread Lock에 의한 성능 장애의 원인을 분석하게 된다 . 반면, Deadlock과 같은

상태는 대부분이 실시간 원인을 밝히기가 어렵고 , javacore 를 떨어뜨려 각 Thread의

lock 점유 상태를 분석함으로써만 원인 분석이 가능하다 .

경험적으로 이러한 유형의 성능 장애는 APM 툴이 자동으로 감지하기는 기술적으로

한계가 존재한다 . 왜냐면 , 대부분의 APM 은 특정 메소드 블록의 수행이 끝이 나야만

이 그 메소드를 수행한 수행시간과 같은 분석정보가 추출되는데 , 진입 후 끝이 나지

28 Deadlock: 서로 다른 하나 이상의 Thread 각각이 서로 상대방의 lock을 획득하기 위해 대기하고

있는 상태를 일컫는다.

44

Page 47: %Bc%Ba%B4ɰ%Fc%B8%Ae%Bdǹ%Ab%C1%F6ħ%Bc%Ad %C3ʾ%C8 %C0Ϻι%Df%C3%E9

않을 경우는 정보가 ( 일반적으로) 추출되지 않기 때문이다 . 그나마 다행스러운 것은

대부분의 JVM 이 javacore 를 떨어뜨려 주는 기능을 제공하고 있고 , JVM의

javacore 를 분석할 수 있는 엔지니어들이 이젠 국내에서도 적잖이 존재한다는 점이

다 .

2.5 외 부 적 요 인 에 의 한 성 능 장 애

( 편집중… )

2.6 네 트 워 크 이 슈 에 기 인 한 성 능 장 애

( 편집중… )

3 APM(Application Performance Management)

3.1 개 요

지난 2000 년도부터 WAS 기반 시스템에 대한 성능모니터링 , 장애감시를 위한 APM

제품의 탄생은 예고되었었다 . 관행적으로 특별한 논리적 근거 없이 H/W 용량 산정

후 프로젝트는 시작되고 , 짧은 공기를 맞추기 위해 충분한 성능테스트 및 성능분석

단계를 생략한 채 시스템은 오픈되었다 . 그리고 그 날 곧바로 성능장애는 100이면

100 모두 발생했다 . 단지 성능장애의 규모와 그것이 미치는 비즈니스 영향도가 차이

가 있었을 뿐이었다 .

45

Page 48: %Bc%Ba%B4ɰ%Fc%B8%Ae%Bdǹ%Ab%C1%F6ħ%Bc%Ad %C3ʾ%C8 %C0Ϻι%Df%C3%E9

2003 년부터 인식 전환이 시작되더니 지난 2004 년을 기점으로 불과 1 년 사이에

한국에서도 WAS 기반 시스템 하에서의 APM 제품 도입의 필요성은 누구나 인식하는

단계에 이르렀고 서너 업체의 외산 제품이 국내에 상륙했다. 그러나 2005 년 현 시

점에서 되짚어 보면 , 전세계적으로도 가장 복잡다단한 국내 시스템 환경에서 우리들이

찾고자 했던 입맛에 딱 맞는 APM 제품은 사실 존재하지 않았다고 판단된다 . 구매해

두고도 제대로 활용하지 않고 있는 우리들의 현실은 이를 반증하고 있다 .

APM 제품을 공급하는 업체들은 상대적으로 비즈니스기술최적화 (BTO), 어플리케이션 라

이프사이클 관리 (ALM), 엔드투엔드(End-to-end) 통합 성능관리의 필요성 , 서비스목표수준

(SLA)관리 등등의 기치를 내걸며 APM 시장 확장에 안간힘을 쓰고 있지만 , 막상

시스템을 운영 / 관리하는 담당자로서는 여전히 당장 직면하고 있는 성능장애현상을 해

결하기 위해 APM 제품 검토를 요청하는 등 엇박자가 연출되고 있다 .

본 장에서는 국내 시장에서 유통되고 있는 APM 제품들이 어떠한 것이 있는지 확인

해 보고 , 각 제품의 특징과 포지션 (Position), 가능하다면 ( 업체간 이슈를 야기하지

않는 선에서의) 장단점에 대해 기술하고자 한다 .

3.2 APM의 분류

APM 제품 도입 검토를 위해서는 각 APM 제품의 용도와 특성을 이해할 필요가 있

다 . 같은 APM 제품이라지만 현재까지 출시된 제품들은 각각의 용도와 쓰임새가 완전

히 동일한 제품은 현재까지 단 하나도 존재하지 않는다 .

A. 프로젝트 단계 및 시스템 범주별 구분

APM 제품에 대한 분류를 다음과 같이 프로젝트 단계 및 시스템 범주 별로 구분해

보도록 하자 .

46

Page 49: %Bc%Ba%B4ɰ%Fc%B8%Ae%Bdǹ%Ab%C1%F6ħ%Bc%Ad %C3ʾ%C8 %C0Ϻι%Df%C3%E9

A그룹은 … ??제품 등이 여기에 해당한다 .

B그룹은 … ??제품 등이 여기에 해당한다 .

C그룹은 … ??제품 등이 여기에 해당한다 .

D그룹은 … ??제품 등이 여기에 해당한다 .

E그룹은 … ??제품 등이 여기에 해당한다 .

( 편집중… )

Pre-

Production

Staging

System

Integration

Final QA

Testing

Load Testing

Monitoring

MaintenanceUnit TestingCoding

DeployTestDevelop

Application

System

NetworkHigh Level

System

View

Deep

Diagnostics

DeveloperQA/Tester

Operators

A B

D

C

E

A : Test design & Management

B : Test Case / Unit Test, Memory leak / Code coverage

C : Functional Test, System Integration/Load Test

D : Performance Monitoring/Analysis, Problem Determination

E : Network/System Management

47

Page 50: %Bc%Ba%B4ɰ%Fc%B8%Ae%Bdǹ%Ab%C1%F6ħ%Bc%Ad %C3ʾ%C8 %C0Ϻι%Df%C3%E9

B. 기 능 별 구 분

APM 제품을 사용하려는 목적 / 용도에 맞게 기능별로 다음과 같이 7 가지 영역으로

구분 볼 수 있다 .

접속자 / 부하량 실시간 모니터링

부하량 / 응답시간 /SQL/TX 수행 통계화 및 상관관계 , 추이분석

성능장애분석 / 어플리케이션 성능장애코드 검출

최종 사용자 체감 응답시간 등 비즈니스 수준 서비스 가용성 모니터링

OS/ 시스템 자원 모니터링

JVM 실행 메소드 / 리소스 프로파일링 (Profiling)

부하테스트 / 스트레스테스트 발생 및 성능 측정

접속자 / 부하량 실시간 모니터링 기능

현재의 시스템에 몇 명의 동시단말사용자가 접속해 있는지 , 어떤 어플리케이션이 현재

실행되고 있으며 , 응답시간은 어떠한지 , 해당 어플리케이션이 수행하고 있는 SQL문장

및 어떠한 Backend 시스템 트렌젝션을 호출하고 있는지 , 단위시간당 처리건수는 어떠

한지 등을 실시간으로 제공해 주는 기능이 절대적으로 필요하다 . 수 십대의 서버로

운영할 경우는 중앙에서 일괄적으로 모니터링 하면서 서버 별로 로드발란생 (Load-

balancing)은 적절한지 , 어떠한 시스템에 현재 성능적인 이슈가 있는지를 직관적으로

실시간 모니터링 할 수 있어야 한다 .

부하량 / 응답시간 /SQL/TX 수행 통계화 및 상관관계 , 추이분석 기능

일자별로 일자별접속자 / 시간당방문자수 / 동시단말사용자 / 부하량 / 응답시간 및 해당 어플

48

Page 51: %Bc%Ba%B4ɰ%Fc%B8%Ae%Bdǹ%Ab%C1%F6ħ%Bc%Ad %C3ʾ%C8 %C0Ϻι%Df%C3%E9

리케이션이 호출한 SQL 및 Backend 트렌젝션에 대한 상관관계 및 통계데이타를 관

리하고 다양한 형태로 검출 추적할 수 있어야 한다 . 과거에 발생한 성능장애의 원인

분석을 위해 해당 시점의 기본적인 시스템 자원 (CPU,MEM 등 ) 에 대한 정보와 , 성능

저하를 야기한 어플리케이션 /SQL등을 분석할 수 있어야 한다 . 더불어 일자별로 방문

자수 및 CPU 사용률의 변화를 통해 향후 성능데이타 추이분석이 가능해야 한다 .

성능장애분석 / 어플리케이션 성능장애코드 검출 기능

WAS 서버 다운 , 힙 메모리 과다 사용에 따른 장애 (OutOfMemoryError), 특정 어플리

케이션 CPU 과다사용에 따른 시스템 성능장애 , 특정 어플리케이션의 상대적 성능저하

로 인해 Active 서비스 큐잉현상에 따른 성능장애 시 해당 어플리케이션이 무엇인지

를 감지할 수 있는 능력 , JDBC 리소스(Connection/ Statement/ ResultSet) 미반환에 따른

조건적 성능장애 감지 및 해당 어플리케이션 코드 검출 , 성능장애 발생시 적절한 어

플리케이션 덤프기록을 통해 향후 분석가능한 데이터가 제공되어야 한다 .

최종 사용자 체감 응답시간 등 비즈니스 수준 서비스 가용성 모니터링 기능

대부분 WAS 서버 사이드에서의 모니터링 만으로도 시스템의 서비스 현황을 모니터링

할 수 있지만 , 경우에 따라 , 국내 N/W 망 별로 혹은 최종 사용자의 N/W 접속사정

및 어플리케이션의 유형에 따라 최종 사용자 체감응답시간이 어떠한지 모니터링 되어

야 한다 . 내부망에서는 정상적인 서비스가 이루어지고 있는 반면 , 최종사용자 체감응답

시간이 상대적으로 느려진다면 , 이는 N/W 혹은 방화벽에서의 이슈일 가능성이 있으며

이를 보다 직관적으로 판단할 수 있어야 한다 .

OS/ 시스템 자원 모니터링 기능

전통적인 시스템 자원 모니터링인 SMS(System Management Solution) 솔루션의 역사가

깊기는 하지만, WAS/J2EE 모니터링 관점에서는 다소 거리가 있다는 것에 다들 공감하

고 있다 . 그렇다 하더라도 시스템의 자원인 CPU, 메모리 , 디스크 , 네트워크 등 기본적

인 시스템 자원에 대한 모니터링은 WAS/J2EE환경에서도 통합되어 모니터링 되어질

필요가 있다 . 특히 CPU 모니터링의 경우 CPU 개수별로 User/Kernel/IO/Idle 사용률을

모니터링하여야 특정 Thread가 특정 CPU 하나를 100% 사용하는지를 직관적으로 추

적할 수 있다 . 반면 , 시스템의 메모리나 네트워크 사용률 등은 굳이 APM 툴이 아니

더라도 별도의 관리 툴에서 다양하게 제공하고 있고 , 그 판단이 상대적으로 수월하기

에 중요도 측면에서는 CPU( 개수별 ) Disk 메모리 네트워크 수순으로 판단된

다. 중요한 것은 시스템 모니터링 항목의 다양성이 아니라 , 어플리케이션의 성능모니터

49

Page 52: %Bc%Ba%B4ɰ%Fc%B8%Ae%Bdǹ%Ab%C1%F6ħ%Bc%Ad %C3ʾ%C8 %C0Ϻι%Df%C3%E9

링이라는 관점에서 , 해당 어플리케이션이 사용한 기본적인 시스템 자원에 대한 정보

및 종합적인 시스템 자원 모니터링 기능이 함께 전체적으로 통합되어 단일뷰로 모니

터링되고 통계적으로 관리되어야 한다는 것이다 .

JVM 실행 메소드 / 리소스 프로파일링 (Profiling) 기능

클래스의 메소드별 응답시간이나 CPU 사용시간 , 메모리 사용량 등을 추출하는 기능을

프로파일링 (Profiling)기능이라 부른다 . 프로파일링 기능에 대한 구현방법은 크게 2 가지

인데 , 하나는 삽입 (injection)기법이고 , 또 하나는 JVM 의 JVMPI(Java Virtual Machine

Profiler Interface) 를 이용하는 것으로 나뉠 수 있다 .

컴파일되어 있는 파일(*.class)인 바이트코드에 직접 메소드별 시작과 끝부분에 추출로

직을 삽입하는 것으로 , 이는 컴파일된 클래스의 디렉토리를 지정해 명시적으로 삽입

(injection)시키게 된다 . 삽입 (injection)기법의 장점은 코드 자체에 약간의 추출 로직이

삽입되는 것에 지나지 않으므로 , 성능저하가 상대적으로 적은 반면 , 개발자의 소스코드

가 변경될 경우 다시 삽입 (injection)과정을 거쳐야 되고 , 향후 제거 시에는 보관해둔

원본 클래스로 대치하거나 새로 깨끗하게 컴파일하는 등의 관리적인 요소가 추가적으

로 발생하게 된다 . 이러한 삽입 (injection)기법도 클래스로더 (ClassLoader) 의 기능을 변

경하여 JVM 기동 시에 자동으로 삽입 (injection)과정이 일어나도록 할 수 있으나 , 이

또한 단점은 클래스로딩시간이 다소 느려질 수 있고 , WAS/OS의 제품 및 버전에 민

감한 경향이 있다 .

반면 JVMPI기법을 사용할 수도 있는데 , JVM 스펙에서 제공하는 JNI(Java Native

Interface) API로써 , 모든 자바 메소드 실행 시마다 호출된 메소드명과 응답시간 , 그

때 당시의 메모리자원 할당 / 제거의 이벤트를 가로챌 수 있다 . 이를 C언와 같은

native 모듈에서 그 과정을 추출하고 기록하여 사용자에게 제공하게 된다 . JVMPI를

이용할 경우 원하는 대부분의 리소스 정보를 추출할 수 있다는 장점이 있는 반면 ,

단점은 자바의 버전과 OS 의 버전에 매우 민감하다는 것과 JVMPI 자체의 성능저하

가 ( 현재까진) 매우 심각할 수준으로 크기 때문에 부하량이 높은 운영 중인 서버에

적용하기에는 다소 부담스럽다는 것이 단점이다 .

프로파일링 기법은 이처럼 언급한 성능적 장단점이 존재한다는 부분과 , 프로파일링 기

능이 필요한 시점이 운영 중 항시 필요한 것이 아니라 JVM 힙 메모리 누수현상의

원인 추적이나 혹은 성능저하를 보이고 있는 특정 어플리케이션이 도출되었을 때 그

50

Page 53: %Bc%Ba%B4ɰ%Fc%B8%Ae%Bdǹ%Ab%C1%F6ħ%Bc%Ad %C3ʾ%C8 %C0Ϻι%Df%C3%E9

것이 SQL이나 Backend 트렌젝션에 의한 것과 같이 명확하게 도출되지 않고 , 특정

어플리케이션의 내부적 메소드 어디에선가 성능저하의 원인이 있을 것이라는 좁혀진

추정 단계에서 필요하기 때문에 대부분 운영 중에는 프로파일링 기법을 적용치 않다

가 필요 시에만 적용하는 방향으로 채택되고 있다 .

따라서 , 필요한 시점에서만 프로파일링 기법을 적용하여 성능저하로 추정되는 특정 어

플리케이션의 메소드별 응답시간 및 메모리사용량 , 메모리 누수현상의 원인추적을 효율

적으로 할 수 있는 기능이 선택적으로 제공되어야 한다 .

부하테스트 / 스트레스테스트 발생 및 측정 기능

협의의 관점에서는 부하테스트 / 스트레스테스트 툴은 APM 제품군에 포함시키지 않는

다 . 그러나 어플리케이션의 성능관리라는 광의의 해석으로는 부하 / 스트레스테스트 툴도

여러 APM 제품군 중의 하나이다 .

우리들 중 다수는 아직 “부하테스트 (Load Test)” 와 “스트레스 테스트(Stress Test)”

의 용어의 차이를 잘 모른 채 그냥 동의어로 사용하는 경향이 있다 . 이러한 용어의

명확한 구분 없이 사용하는 사이트의 경우는 , 적절한 부하테스트를 하자는 것인지 , 의

미있는 스트레스 테스트를 하자는 것인지 목표가 명확하지 않는 경우가 대부분이다 .

스트레스테스트 (Stress Test) 는 어플리케이션이 실행 시에 필요로 하는 각종 리소스

(CPU, RAM, Disk 등 ) 의 허용하는 한도를 넘어서서 비정상적인 높은 부하를 발생시켜

보는 테스트를 일컫는다 . 일정한 한도를 넘어서는 부하 상황이 되면 경우에 따라

JVM 이 다운되거나 , 데이터를 잃어버리게 되는 것 등과 같이 시스템의 비정상적인

작동을 유발시킬 수도 있다 . 이 같은 결점 (Bug) 이나 결함 (failure)을 찾기 위해 스트

레스를 가해 보는 것이다 . 스트레스 테스트 시의 부하 ( 일련의 들어오는 요청 ) 는 이

처럼 시스템 리소스의 한계점을 시험하려는 의도이기 때문에 , 다분히 의도적으로 왜곡

되는 경향이 있으며 , 향후 실제 접속자에 의해 발생하는 부하량 패턴과는 거리가 멀

수도 있다 .

반면 , 부하테스트 (Load Test) 는 적절한 부하를 발생시켜 통계적으로 의미있는 수치를

측정하는 테스트를 일컫는다 . 부하테스트의 두 가지 중요한 목적 중 하나는 장시간

서비스 가능 여부를 확인하는 신뢰성 (reliability) 테스트와 두 번째는 성능 테스트

51

Page 54: %Bc%Ba%B4ɰ%Fc%B8%Ae%Bdǹ%Ab%C1%F6ħ%Bc%Ad %C3ʾ%C8 %C0Ϻι%Df%C3%E9

(Performance Test) 이다 . “ 부하테스트 (Load Test)” 라는 용어 자체는 대단히 모호하며

그 용어를 의미있게 사용하기엔 너무나 일반적이고 미흡한 면이 없잖아 있다 . 예를

들어 “부하 (Load) 라는 것이 “과부하 (Overload)”나 “높은부하 (High Load)” 를 암묵

적으로 항상 의미한다고 생각하는가 ? 성능테스트 (Performance Test) 관점에서의 부하

(Load) 는 최소레벨 (0 tps) 에서부터 , 리소스 고갈 상황이나 기형적인 응답시간의 극심

한 저하 혹은 트렌젝션 실패 등과 같은 상황이 발생하기 직전까지의 최대 레벨

(Maximum tps)까지 다양할 수 있다 .

성능테스트 (Performance Test) 는 부하테스트 중 하나의 관점 , 즉 성능적 관점만 측정

하겠다는 뜻이 담겨 있다 . 해당 시스템 혹은 어플리케이션의 성능을 측정한다함은 점

진적인 부하량 증가 과정에서 더 이상 단위시간당 최대 처리량 (TPS)이 증가하지 않

을 때 , 그 때의 수치를 측정하고 그 수치를 해석하는 과정을 의미한다 . 성능테스트의

일반적인 목적은 현재의 시스템 혹은 어플리케이션이 최대로 수용가능한 동시단말사용

자수가 몇 명인지 , 혹은 목표로 정한 성능이 도출되지 않을 때 병목지점이 어딘지를

밝히고 목표성능을 획득하기 위해 무엇을 시정해야하는지를 찾아내기 위함이다 . 성능테

스트 과정에서 매우 중요한 부분은 목표성능을 설정하고 그러한 목표성능을 확인 / 측

정하기 위해 향후 시스템 운영 중에 실제로 발생할 접속사용자의 호출패턴이 어떠하

냐를 분석 / 추정하는 과정이 반드시 필요하고 , 이를 근간으로 점진적 부하를 발생시켜

야 의미있는 성능테스트 결과를 도출할 수 있다 . 그렇지 않을 경우 성능테스트가 자

칫 스트레스테스트로 끝나고 만다.

각 용어를 도식으로 표현하면 다음과 같다 .

--------

부하테스트

스트레스테스트신뢰성

테스트

성능테스트

52

Page 55: %Bc%Ba%B4ɰ%Fc%B8%Ae%Bdǹ%Ab%C1%F6ħ%Bc%Ad %C3ʾ%C8 %C0Ϻι%Df%C3%E9

시스템 운영 중 성능 모니터링 과정에서 도출된 성능저하 / 성능장애현상이 발생했을

때 이를 극복하기 위해서는 이처럼 스트레스테스트 , 신뢰성테스트 , 성능테스트 과정을

경우에 따라 반드시 적절히 시행해 보아야만 원인분석이 가능할 때가 있다 . 따라서 ,

성능장애의 유형 및 용도에 맞게 스트레스테스트를 할 것인지 , 신뢰성 테스트를 할

것인지 , 성능테스트를 할 것인지를 결정해야 하고 , 그러한 테스트를 지원하는 툴의 필

요성이 있다 .

그러나 , 이러한 부하테스트 지원툴은 본 문서에서 중점적으로 서술하고 있는 성능모니

터링을 위한 APM 제품군과는 별도의 제품군으로 시장에서 형성되어 있다 .

( 이하 생략 )

53