Foundry
성능 최적화
중급
핵심

성능 측정과 병목 분석

느린 서비스의 원인 찾기, 어디가 병목인가?

성능 측정과 병목 분석

핵심 지표

지표의미기준
Latency요청-응답 시간API < 200ms
Throughput초당 처리량서비스에 따라 다름
p99상위 1% 응답 시간평균보다 중요!
Error Rate에러 비율< 0.1%

병목 찾기 순서

전체 시간에서 작은 비중을 차지하는 구간을 최적화해도 전체는 그 비중만큼만 줄어든다 한 요청의 시간 300ms DB 대기 270ms 코드 30ms 코드를 열 배 빠르게 하면 270ms 그대로 300ms 가 273ms 가 된다. 9퍼센트 개선이다 가장 큰 구간을 먼저 재고 그것부터 고친다 코드를 무한히 빠르게 해도 전체는 10퍼센트를 넘어 줄지 않는다
  1. 모니터링: 어떤 API가 느린지 확인
  2. DB 쿼리 분석: slow query log, EXPLAIN
  3. 애플리케이션 프로파일링: CPU, 메모리, 스레드
  4. 인프라: 네트워크, 디스크 I/O

재기 전에 고치면 대개 틀린다

성능 문제는 짐작이 잘 안 맞습니다. 코드를 읽고 느릴 것 같은 곳을 고치면, 그 구간이 전체의 몇 퍼센트였는지 모르고 고친 것이 됩니다.

짐작실제로 흔한 것
반복문이 느리다DB 를 기다리는 시간이 대부분이다
직렬화가 느리다같은 질의를 여러 번 부르고 있다
서버가 부족하다연결 풀 자리를 기다리고 있다

기다리는 시간과 일하는 시간을 나눠 재는 것이 첫 걸음입니다. CPU 사용률이 낮은데 느리면 어딘가를 기다리는 것이고, 그것은 서버를 늘려도 줄지 않습니다.

무엇을 재나

지표무엇을 알려 주나
구간별 시간어디가 긴지
호출 횟수한 번이 아니라 여러 번인지
상위 백분위평균에 숨은 느린 요청

호출 횟수가 특히 값싼 발견을 줍니다. 한 번에 20ms 인 질의가 화면 하나에서 50번 돌면 1초입니다. 그 질의를 빠르게 하는 것보다 횟수를 줄이는 것이 훨씬 크게 듣습니다.

실무 포인트

  • 평균보다 p99가 더 중요 (사용자 경험에 직접 영향)
  • 대부분의 병목은 DB 쿼리 → EXPLAIN 먼저 확인
  • 추측하지 말고 측정부터 시작
면접에서 이렇게 나옵니다

Q.서비스 성능 병목을 어떤 순서로 찾나요?

위에서 아래로 좁힙니다. 추측으로 코드를 보기 전에 어느 구간에서 시간을 쓰는지 먼저 나눕니다.

순서확인도구
1어떤 요청이 느린가요청별 지연 분포, p99
2그 요청의 어느 구간인가분산 트레이싱, 구간 타이머
3자원 중 무엇이 포화인가CPU, 메모리, 디스크, 네트워크, 커넥션 풀
4외부 의존인가 자기 코드인가DB 쿼리 시간, 외부 호출 시간
5코드의 어느 함수인가프로파일러

2번을 건너뛰면 대개 헛수고가 됩니다. 느린 API 의 시간이 DB 대기인지, 외부 호출인지, 직렬화인지에 따라 손댈 곳이 완전히 다릅니다.

3번에서 자주 놓치는 것이 커넥션 풀입니다. CPU 와 메모리가 한가한데도 느리면 풀 대기를 봐야 합니다.

흔한 실수: 평균만 보고 판단하는 것. 평균이 정상이어도 p99 가 나쁘면 일부 요청이 크게 느린 것이고, 원인이 평균과 다릅니다.

Q.프로파일러 결과에서 self time과 total time을 어떻게 구분해 읽나요?

지표의미
total time그 함수가 시작해서 끝날 때까지의 시간. 호출한 함수들의 시간을 포함한다
self time그 함수 자체가 쓴 시간. 하위 호출을 뺀 값

읽는 방법이 다릅니다.

상황해석
total 이 크고 self 는 작다이 함수는 통로다. 아래를 봐야 한다
total 과 self 가 모두 크다이 함수 자체가 무겁다. 여기를 고친다
self 가 큰 함수가 여럿 흩어져 있다특정 병목이 없다. 구조를 봐야 한다

최상위 진입점은 항상 total 이 가장 큽니다. 그것을 병목이라고 읽으면 아무것도 못 합니다. 고칠 대상은 self 가 큰 함수입니다.

I/O 대기가 섞이면 해석이 또 달라집니다. self 가 큰데 실제로는 소켓 대기인 경우가 있어서, CPU 프로파일과 벽시계 기준 프로파일을 구분해서 봐야 합니다.

흔한 실수: 호출 횟수를 함께 보지 않는 것. 한 번에 100밀리초 걸리는 함수와 1밀리초씩 100번 불리는 함수는 self 가 같아도 대응이 다릅니다. 후자는 호출을 줄이는 쪽입니다.

Q.APM 도구로는 무엇을 보고 병목을 판단하나요?

보는 것판단하는 것
요청별 지연 분포어떤 엔드포인트가 느린가
트레이스의 구간 분해그 안에서 어디에 시간을 쓰는가
느린 쿼리 목록DB 가 원인인가
외부 호출 시간남의 서비스 때문인가
오류율과 예외느린 것과 실패가 같은 원인인가
처리량과 지연의 관계부하가 원인인가

가장 먼저 보는 것은 어떤 엔드포인트가 전체 시간을 많이 쓰는지입니다. 요청당 200밀리초짜리가 초당 1,000회면, 요청당 2초짜리가 초당 1회인 것보다 훨씬 큰 문제입니다. 지연만 보면 순서가 뒤바뀝니다.

마지막 항목이 판단을 크게 바꿉니다. 처리량이 늘면서 지연이 나빠졌다면 용량 문제이고, 처리량이 그대로인데 나빠졌다면 코드나 데이터가 바뀐 것입니다.

흔한 실수: 느린 엔드포인트 하나만 잡고 최적화하는 것. 호출량을 곱해 전체에 기여하는 시간으로 순위를 매겨야 개선 효과가 큰 곳부터 손댑니다.

먼저 스스로 답해보고 아래 답변과 견줘보세요. 막히는 부분은 문제로 확인할 수 있어요.

더 깊이 공부하기

읽었으면 문제로 확인해보세요

성능 최적화 문제를 풀면 틀린 문제가 자동으로 노트에 쌓입니다. 가입 없이 5문제를 먼저 풀어볼 수도 있어요.