CHAPTER 4. 성능 테스트 패턴 및 안티패턴

AMUD·2024년 5월 5일
0

자바최적화

목록 보기
4/6

  • 다양한 종류의 테스트 소개
  • 유형별 베스트 프랙티스
  • 일반적인 안티패턴
  • 리팩터링 방법

🍀 4.1 성능 테스트 유형

  • 좋은 성능 테스트는 정량적
  • 어떤 테스트를 하더라도 그 도메인을 심사숙고해야 함
  • 성능 테스트 기획 요령: 테스트로 확인하고 싶은 정량적 질문 리스트와 그 테스트가 대상 앱 입장에서 중요한 이유
  • 예시
    • 지연 테스트: 종단 트랜잭션에 걸리는 시간은?
    • 처리율 테스트: 현재 시스템이 처리 가능한 동시 트랜잭션 개수는?
    • 부하 테스트: 특정 부하를 시스템이 감당할 수 있는가?
    • 스트레스 테스트: 이 시스템의 한계점은 어디까지인가?
    • 내구성 테스트: 시스템을 장시간 실행할 경우 성능 이상 증상이 나타나는가?
    • 용량 계획 테스트: 리소스를 추가한 만큼 시스템이 확장되는가?
    • 시스템이 부분적으로 실패할 경우 어떤 일이 벌어지나?

4.1.1 지연 테스트

  • 가장 일반적인 성능 테스트
  • ‘고객이 트랜잭션(또는 페이지 로딩)을 얼마나 오래참고 기다려야 하는지’
  • 양날의 검: 너무 정량적이고 명확한 나머지 다른 종류의 성능 테스트 질문을 식별할 필요성마저 흐릿
  • 조심스럽게 취급
  • 단순 평균값은 별로 소용 x

4.1.2 처리율 테스트

  • 그 다음 일반적인 성능 테스트
  • 처리율은 지연과 거의 동등한 개념
    • 지연 테스트를 수행할 때 계속 동시 트랜잭션을 명시한다는 점
    • 지연을 모니터링하면서 테스트
    • 지연 분포가 갑자기 변하는 지점 = 한계점 = 변곡점 = 최대 처리율
  • 시스템 성능이 급락하기 직전, 최대 처리율 수치를 측정하는 것이 목표

4.1.3 부하 테스트

  • 시스템이 이 정도 부하는 견딜 수 있을까?의 예/아니오 답을 구하는 과정
  • 애플리케이션 트래픽이 상당할 것으로 예상 되는 특정 비지니스 이벤트에 대비하기 위함

4.1.4 스트레스 테스트

  • 시스템 여력이 어느 정도인지 알아보는 수단
  • 일정한 수준의 트랜잭션, 즉 특정 처리율을 시스템에 계속 걸어놓음
  • 시간이 갈수록 서서히 동시 트랜잭션이 증가하고 시스템 성능 저하
  • 최대 처리율: 측정값이 나빠지기 시작하기 직전의 값

4.1.5 내구 테스트

  • 메모리 누수, 캐시 오염, 메모리 단편화 등 시간 지나야 드러남
  • 내구 테스트로 주로 감지
  • 빠른 응답을 요구하는(지연이 낮은) 시스템에서 많이 함

4.1.6 용량 계획 테스트

  • 스트레스 테스트와 여러모로 비슷
  • 차이점
    • 스트레스 테스트: 현재 시스템이 어느 정도 부하를 버틸 수 있는지
    • 용량 계획 테스트: 업그레이드한 시스템이 어느 정도 부하를 감당할 수 있는지 미리 내다보는 것
  • 위협 요소 대응 X
  • 예정된 계획의 일부분을 실행하는 경우가 대부분

4.1.7 저하 테스트

  • = 부분 실패 테스트
  • 업무 체계가 잘 잡혀있고 정규화된 환경에서는 대부분 페일 오버 및 복원 테스트를 아주 꼼꼼하게 기획하며, 매우 엄격한 기준 하에 수행
  • 평상시 운영 환경과 동등한 수준의 부하를 시스템에 가하는 도중, 어떤 컴포넌트나 전체 서브 시스템이 갑자기 능력을 상실하는 시점에 벌어지는 일들을 확인
  • 중요한 측정값: 트랜잭션 지연 분포와 처리율
    카오스 멍키
  • 부분 실패 테스트의 한 종류
  • 넷플릭스가 자사 인프라의 견고함을 검증하고자 수행한 프로젝트 → 짱짱 멋있음
  • 실제 운영 환경에서 라이브 프로세스를 하나씩 랜덤하게 죽이면서 검증 ㄷ
    → 복원성이 있는 아키텍처에서는 어느 한 컴포넌트가 잘못돼도 다른 컴포넌트까지 연쇄적으로 무너뜨리면서 전체 시스템에 부정적 영향을 끼치는 일은 없어야 함

🍇 4.2 기본 베스트 프랙티스

  • 성능 튜닝 시 주안점
    • 나의 관심사가 무엇인지 식별하고 그 측정 방법을 고민
    • 최적화하기 용이한 부분이 아니라 중요한 부분을 최적화
    • 중요한 관심사를 먼저 다루기

4.2.1 하향식 성능

  • 난이도: 자바 애플리케이션을 대규모 벤치마킹하는 일 << 작은 코드 섹션별로 정확하게 수치 얻는 것
  • 하향식 성능 접근 방식으로 성과 극대화하는 법
    • 테스트팀이 테스트 환경 구축
    • 무엇을 측정하고 무엇을 최적화해야 하는지
    • 성능 활동을 전체 소프트웨어 개발 주기에서 어떻게 병행
    • 전 팀원이 명확하게 이해

4.2.2 테스트 환경 구축

  • 가급적 모든 면에서 운영환경과 똑같이 복제해야 함
  • 서버(CPU 수, OS, 자바 런타임 버전 등), 웹 서버, DB, 로드 밸런서, 네트워크 방화벽
  • 클라우드로 요즘에는 껐다 켰다 쉽게 가능 ~

4.2.3 성능 요건 식별

  • 성능을 평가하는 지표는 코드 관점에서 생각하는 것이 아니라, 시스템을 전체적으로 바라보는 것이 중요
  • 이렇게 최적화하려는 핵심 지표를 성능 비기능 요건
  • 목표 예시
    • 명확: 95% 백분위 트랜잭션 시간을 100밀리초 줄인다
    • 모호: 일반 고객을 서비스하는 리소스 비용을 50% 줄인다

4.2.4 자바에 특정한 이슈

  • JVM의 경우에도 신경써야하는 요소 존재
  • 특히 JIT 컴파일, 최신 JVM은 어떤 메서드를 JIT 컴파일해서 최적화한 기계어로 변환할지 분석
  • JIT 컴파일 여부 선별 기준 예시
    • JIT 컴파일할 정도로 자주 실행되는 메서드가 아닙니다.
    • 메서드가 너무 크고 복잡해서 도저히 컴파일 분석을 할 수 없습니다.

4.2.5 SDLC 일부로 성능 테스트 수행하기

  • Software Development LifeCycle
  • 수준이 높은 팀일수록 성능 테스트를 전체 SDLC의 일부로서 수행
  • 특히 성능 회귀 테스트(Performance regression testing)을 상시 수행

🎧 4.3 성능 안티패턴 개요

  • 이러한 잘못된 패턴을 분류하고 유형화함을 통해서 팀원들이 서로 소통하고, 안티패턴을 제거할 수 있도록 를 개발
  • 대충 팀에 해악을 주는 사람들의 동기 모임

4.3.1 지루함

  • 지루함을 느끼고 비효율적인 방법 채택
  • 예시
    • 알려지지 않은 기술로 컴포넌트를 제작
    • 맞지도 않은 유스케이스에 억지로 기술을 욱여넣기

4.3.2 이력서 부풀리기

  • 이력서를 부풀리기 위해서 과대 포장 구실 만들기
  • 프로젝트를 불필요한 방향으로 갈 때가 존재

4.3.3 또래 압박

  • 팀원들이 기술을 결정할 때 관심사를 분명히 밝히지 않고 충분희 논의 없이 진행하는 경우

4.3.4 이해 부족

  • 지금 사용하는 툴의 기능도 온전히 모르는데, 무턱대고 새로운 툴로 문제를 해결하는 경우
  • 기술복잡도를 높이기 때문에 복잡도를 높히는 것과 현재 툴 사이의 균형 중요

4.3.5 오해와 있지도 않은 문제

  • 문제 자체를 제대로 이해하지 못한채 오로지 기술을 이용해서 문제를 해결하려는 경향
  • 성능 수치를 측정도 안했기 때문에 문제의 본질을 정확하게 이해할 수 없음

💪 4.4 성능 안티패턴 카탈로그

4.4.1 화려함에 사로잡히는 경우

  • 증상
    • 최신의 멋진 기술을 튜닝 타깃 → 대충 홍머병
    • “처음이라 말썽이 많군. 뭐가 문제인지 원인을 밝혀야 해”
  • 현실
    • 측정보다 어떻게 해보면 되겠지 마인드
    • 신기술을 제대로 알지 못함
  • 처방
    • 측정해보고 진짜 성능 병목점을 찾기
    • 새 컴포넌트는 전후로 충분한 로그
    • 베스트 프랙티스 및 단순화한 데모를 참조
    • 팀원들이 새 기술을 이해하도록 독려하고 팀 차원의 베스트 프랙티스 수준을 정하기

4.4.2 단순함에 사로잡히는 경우

  • 증상
    • 프로파일링해서 객관적으로 아픈 분위를 들추려 하지 않고 무작정 시스템에서 제일 간단한 부분만 파고듬
    • “우리가 알고 있는 부분부터 한번 파봅시다”
  • 현실
    • 원개발자는 그 시스템 파트를 어떻게 튜밍해야 할지 알고 있음
    • 지식 공유하지 않고 혼자 개발해서, 독보적인 전문가만 양성
  • 처방
    • 측정을 해보고 진짜 성능 병목점 찾기
    • 본인이 익숙하지 않은 컴포넌트에 문제가 생기면 잘 아는 전문가에게 도움 요청
    • 개발자가 전체 시스템 컴포넌트를 고루 이해하도록 독려

4.4.3 성능 튜닝에 관심이 있는 경우

  • 증상
    • 흡사 고독한 천재
  • 현실
    • 명망 높은 마법사나 초안이 하는 일이라곤 드레스 코드에 도전하는 일이 고작
  • 처방
    • 측정을 해보고 진짜 성능 병목점 찾기
    • 새로 채용된 팀내 전문가가 다른 팀원들과 지식을 공유하고 팀워크를 유지할 수 있게 리드

4.4.4 민간 튜닝에 관심이 있는 경우

  • 증상
    • 웹사이트에서 마법의 설정 매개변수 발견
  • 현실
    • 전후 맥락이나 기초를 모르고 그 팁이 진짜 어떤 영향을 미칠지 모름
    • 실제로는 더 나빠질지도
  • 처방
    • 시스템의 가장 중요한 부분에 직접 영향을 미치는 기술은 확실히 파악하고 충분히 검증된 것들만 적용
    • 매개변수를 UAT에서 시험하기. 어떤 변화라도 철저히 검증하고 효용을 프로파일링하는 일이 중요
    • 다른 개발자나 운영 요원, 데브옵스팀과 함께 설정 문제를 리뷰하고 토의

4.4.5 안되면 조상 탓

  • 증상
    • 정작 이슈와 아무 상관도 없는 특정 컴포넌트를 문제 삼음
    • “JMS, 하이버네이트 그 머시기 라이브러리가 항상 문제라니까”
  • 현실
    • 충분히 분석도 안 해보고 성급한 결론 내림
    • 평소 의심했던 범인을 수사 과정의 유일한 용이자로 지목
  • 처방
    • 성급한 결론 내리고픈 욕망에 굴하지 않기
    • 정상적으로 분석
    • 분석 결과를 모든 이해관계자와 의논

4.4.6 숲을 못 보고 나무만 보는 경우

  • 증상
    • 변경 영향도 완전히 파악하지 않은 채 일단 그냥 변경하거나 국소적인 부분만 프로파일링
  • 현실
    • 변경 영향도를 완전히 이해한 사람이 아무도 없음
    • 새로 바꾼 JVM 설정값 하에서 애플리케이션을 완전히 프로파일링하지 않음
    • 마이크로벤치마킹 때문에 빚어질 전체 시스템 영향도를 파악하지 않음
    • JVM 스위치 직접 설정은 긁어 부스럼일수도
  • 처방
    • 운영계에서 스위치 변경하기 전 절차
      1. 운영계 성능 지표 측정
      2. UAT에서 한번에 스위치 하나씩 변경
      3. 스트레스를 받는 지점이 UAT와 운영계가 동일한지 확인
      4. 운영계에서 일반적인 부하를 나타내는 테스트 데이터를 확보
      5. UAT에서 스위치를 변경하며 테스트
      6. UAT에서 다시 테스트
      7. 직접 추론한 내용을 다른 사람에게 재검토 요청
      8. 직접 내린 결론을 다른 사람과 공유

4.4.7 내 데스크톱이 UAT인 경우

  • 증상
    • UAT 환경이 운영계 환경과 전혀 다른 경우, 저성능 데스크톱에서 고성능 운영 서버로 서비스할 코드
  • 현실
    • 서비스가 둥단되는 사태가 벌어지면 장비 몇 대 더 추가하는 비용보다 훨씬 비싼 대가
  • 처방
    • 서비스 중단 비용과 고객 이탈로 인한 기회비용을 잘 따져보기
    • 운영 환경과 동일한 UAT 환경 구입
    • 소 잃고 외양간 고치는 비용이 더 비싸니, 관리자에 올바른 사례 제시하기

4.4.7 운영 데이터처럼 만들기는 어려워라고 말하는 경우

  • 증상
    • 운영계와 유사한 데이터를 내고자할 때, 데이터셋이 단순화 되는 경우
  • 현실
    • 최대한 맞추어야 함
  • 처방
    • 데이터 도메인 전문간에게 컨설팅을 받고 운영 데이터를 UAT로 다시 이전하는 프로세스에 시간과 노력을 투자
    • 다수의 고객이 몰리고 엄청난 트랜잭션이 예상되는 서비스는 출시 전 철저히 준비

🐱 4.5 인지 편향과 성능 테스트

  • 안티패턴 대부분, 전체/부분적으로는 하나 이상의 인지 편향으로 비롯된 것들

4.5.1 환원주의

  • 시스템을 아주 작은 조각으로 나누어서 그 구성 파트를 이해하면 전체 시스템도 다 이해할 수 있다는 분석주의적 사고방식
  • 그러나 복잡한 시스템에서는 그렇지 않음

4.5.2 확증 편향

  • 성능 면에서 중대한 문제를 초래하거나 애플리케이션을 주관적으로 바라보게 함
  • 테스트 세트가 부실하거나 테스트 결과를 통계적으로 건전하게 분석하지 않을 때

4.5.3 전운의 그림자(행동 편향)

  • 시스템이 예상대로 작동하지 않는 상황, 또는 아예 중단된 시간 중에 발현되는 편향
  • 원인
    • 영향도를 분석해보지도 않고, 또 다른 사람에게 연락도 안 하고 시스템 인프라 변경
    • 시스템이 의존하는 라이브러리를 변경
    • 연중 가장 업무가 빠듯한 날에 처음 보는 버그나 경합 조건 발생

4.5.4 위험 편향

  • 위험을 피하고 변화를 거부하는 본성
  • 적절한 조치를 하지 못한 까닭에 더 고착화

4.5.5 엘스버그 역설

  • 인간이 확률을 이해하는 데 서투른지 보여주는 사례
  • 사람들은 위험은 수용하지만 불확실성에는 소극적

🐊 4.6 마치며

  • 다음에는 저수준 성능 측정 방법과 마이크로벤치마크의 잠재적 위험성 등

🦴 참고

  • 자바최적화 - 벤저민 J. 에번스 , 제임스 고프 , 크리스 뉴랜드 저자(글) · 이일웅 번역
  • https://bcho.tistory.com/1328
profile
210's Velog :: Ambition Makes Us Diligent

0개의 댓글