본문 바로가기
Study/우아한 테크 캠프 Pro

우아한 테크 캠프 PRO, 6주차 서비스 진단하기

반응형

우아한 테크 캠프 PRO, 6주차 과제 - 서비스 진단하기


서비스 문제 상황 인지

  • 서비스 구성
    • CPU
    • RAM
    • Network Interface Card (NIC)
    • Disk
  • 각 자원들은 여유가 있거나 일정 수치 이상의 포화 상태로 나뉜다.
  • 요약, 이벤트 기록, 스냅샷 기록으로 각 자원들의 상태 정보를 획득할 수 있다.
  • 요약 정보로 각 리소스의 대략적인 상태를 파악 ( 일정 수치에 알람 설정 ), 스냅샷으로 원인 파악
  • 이벤트 기록은 장애상황에서 사용하기엔 데이터가 방대하여, 그자체로 영향을 줄 수 있기 때문에 문제 상황 재현등에 활용한다.

 

서비스 상태 진단 :: 요약

  • 단위시간 정보의 합계나 평균을 보여준다
  • 평균의 합계에 속으면 안된다!
  • sar 명령어를 통한 시스템 모니터링
    • System Activity Report
    • CPU(default), Memory, I/O 사용량을 수집, 레포트하고 저장하는 명령어
    • sar [interval] [number] [option]
      • -o : stdout
      • -f : 결과를 파일에 저장
      • -r : 메모리 사용량
      • -d : 디바이스 사용량
      • -n : 네트워크 사용량
      • -c : 새롭게 생성된 프로세스 수
      • -W : Swapping의 통계
  • vmstat 명령어를 통한 시스템 모니터링
    • CPU 사용률과 메모리 상황 등, 시스템 리소스를 종합적으로 확인
    • vmstat [option] [interval] [number]
    • 화면 표시 설명
      • procs: 프로세스 상태
        • r(runnable): 실행 대기 상태가 되어있는, 실행 가능한 프로세스 수
        • b(blocked): 인터럽트 불가능한 sleep 상태가 되어있는 프로세스 수
      • memory: 메모리 사용 상황
swpd: 사용중인 가상 메모리 양
        • free: 미사용 메모리 양
        • buff: 사용중인 버퍼 양
        • cache: 사용중인 캐쉬 양
        • swap: 스와핑 상황
        • si(swap in): 스왑 영역에서 메모리로 로드된 1초간의 평균 양
        • so(swap out): 메모리에서 스왑 영역에 기록된 1초간의 평균 양
      • io: 블록 i/o 상황
        • bi(block in): 디바이스로부터 읽어진 블록의 1초간의 평균 양
        • bo(block out): 디바이스에 쓰여진 블록의 1초간의 평균 양
      • system: 인터럽트나 context switch의 횟수
        • in(interrupt): 1초당 인터럽트 횟수
        • cs(context switch): 1초당 context switch 횟수
      • cpu: cpu 가동 상황
        • us: 유저 어플리케이션(비 커널 코드 실행 비율)
        • sy: 시스템(커널 코드 실행 비율)
        • id: idle 시간
        • wa: 입출력 대기 시간
        • st(stolen): 가상 머신 실행 비율
      • 옵션
        • -d : 각 영역별 디스크 상태를 표시
        • -s : 이벤트와 메모리 통계 테이블을 표시

 

서비스 상태 진단 :: 이벤트 기록

  • 패킷과 시스템콜 등의 이벤트 기록을 확인
  • 와이어샤크

 

서비스 상태 진단 :: 스냅샷

  • 순간의 상태를 기록하여, 현재 문제가 발생하고 있지 않은지, 발생한다면 원인조사에 사용한다.
  • top
    • 시스템의 상태를 전반적으로 빠르게 파악 가능
    • 너무 많은 기능이 있어서.. 주로 확인하는 메모리에 대해서 정리!!
      • VIRT
        • 프로세스가 사용하고 있는 virtual memory의 전체 용량
        • SWAP + RES
      • RES
        • 현재 프로세스가 사용하고 있는 물리 메모리의 양
        • 실제로 메모리에 올려서 사용하고 있는 물리 메모리
      • SHR
        • 다른 프로세스와 공유하고 있는 shared memory의 양
        • 공유 메모리에 올려지는 라이브러리 ( 글로벌하게 리눅스 프로세스에 사용되는 라이브러리 등등 )

 

USE 방법론

USE_METHOD

  • 문제 상황을 판단하기 위해 Utilization, Saturation, Error의 기준을 사용
    • U: Utilization => 얼만큼 자원을 썼는지
    • S: Saturation => 얼마나 많은 부하가 몰리는지
    • E: Error => 에러가 발생했는지
  • Flow chart ( E -> U -> S )
    • Errors Present?
      • 로깅을 통한 에러 인지 ( 시스템 로그 + 어플리케이션 로그 )
    • High Utilization?
      • 사용률로도 문제 상황을 인지할 수 있다.
        • 서버의 경우 CPU 사용률,
        • 사용가능한 메모리량
        • RX(Receive)/TX(Transmit) 패킷량
        • DISK 사용률
        • Network 사용률
    • Saturation?
      • 부하 확인

 

 

사용률 확인 :: CPU

  • CPU 사용률이 높다는건 CPU를 잘쓰고있다는 뜻, 하지만 100퍼라면 포화상태를 나타내고, 대기할 프로세스가 생긴다.
  • user vs kernel 비율을 확인
  • wait I/O 보단 process의 block 상태를 확인
  • stolen time은 hipervisor가 차지한 시간

 

사용률 확인 :: Memory

  • swap in, out이 발생한다면 현재 시스템에 메모리가 부족하다는 의미
  • 메모리를 가져오는 방식
    • 프로세스가 커널로 메모리의 할당량을 알려주고 메모리를 요구
    • 커널은 프로세스에게 해당 양 만큼의 가상 메모리를 넘긴다.
    • 물리 메모리와의 매핑은 필요할 때가 되면 수행한다. ( 하드웨어에서 제공하는 paging이라고 하는 가상 메모리 구조 )
    • 가상 메모리를 사용하면 본래 물리 메모리 용량 이상의 메모리를 다룰 수 있는 것처럼 프로세스에 꾸며 보일 수 있다.
    • 모든 프로세스가 자신만의 주소공간을 가지므로, 가상메모리가 없으면 매우 큰 공간이 필요
      • 따라서 실제 필요한 부분만 메모리에 올리는 demand-paging 기법을 사용
    • 물리 메모리가 부족한 경우 장시간 사용되지 않은 영역의 가상메모리와 물리메모리 영역 매핑을 해제
    • 해제된 데이터는 HDD등에 저장해두고 다시 필요해지면 메모리에 올리는데 이를 SWAP이라고 한다.
      • SWAP이 발생한다는 것은 물리메모리 공간이 실행에 필요한 프로세스보다 부족하단 의미
      • Swap이 발생한다면 RES가 큰 프로세스가 없는지 확인
      • RES: 실제 물리 메모리 영역의 크기
      • VIRT: 프로세스가 확보한 가상 메모리 영역의 크기 ( top 명령어 )

 

부하 확인 :: 프로세스 상태

  • 부하가 높다면 프로세스 상태가 R, D이면서 CPU 사용률이 높은 프로세스를 찾아 원인을 파악해야한다.
  • uptime
    • load average: 타이머 인터럽트가 발생했을때 실행 가능 상태인 Task와 I/O 대기인 Task의 개수를 단위시간으로 나눈 것
    • 즉 해당 숫자가 core 수보다 높다면 프로세스가 처리할 양보다 높다는 뜻
  • 프로세스 상태
    • D: uniterruptible sleep
    • R: running
    • S: sleeping
    • T: stopped by job control signal
    • t: stopped by debugger during trace
    • z: zombie

 

네트워크 상태 확인

  • TIME_WAIT
    • 네트워크 상태중 TIME_WAIT은 정상적인 상태이나, 너무 많으면 장애로 이어질 수 있는 상태
  • CLOSE_WAIT
    • 장애 상황에서만 볼 수 있는 상태
    • 서버 행업 상태라고도 한다.
    • lsof 명령어로 상태 확인
      • list of files의 약자로 시스템의 열린 파일 목록을 확인하기 위해서 사용하는 명령어
      • 특정 프로토콜과 포트에 붙어있는 파일 시스템(소켓) 상태를 확인
      • lsof -i:8080 // 8080포트 상황 lsof -i TCP:8080 // TCP 프로토콜 8080포트 상황
      • CLOSE_WAIT 상태 수가 많이 쌓여있다면 곧 장애가..난다는 뜻..
    • 포트를 잡고 있는 프로세스의 종료 또는 네트워크 재시작외에는 해결 방법이 없다..
    • 발생하는 원인은 무엇일까?
      • Client로 부터 FIN 요청을 받았으나, ACK를 응답하지 못한 상태 ( 서버의 부하가 높아 프로세스를 정상적으로 처리하지 못한 상태 )
      • 요청과 응답이 Recursive하다면 교착상태에 빠질 수 있다.
      • 카카오 테크, CLOSE_WAIT 최종 분석
    • 참고 문서

 

프로세스 vs 쓰레드

  • 프로그램: 파일이 저장장치에 저장되어 있지만 메모리에는 올라가 있지 않은 정적인 상태
  • 프로세스: 운영체제로부터 자원을 할당받는 작업의 단위 ( 실행되고 있는 프로그램, 동적인 상태 )
  • 쓰레드: 프로세스가 할당받은 자원을 이용하는 실행 흐름의 단위
    • 탄생 배경
      • 한 프로그램을 처리하기 위해 프로세스를 여러개 만들면 되지않나?
      • OS는 안전성을 위해서 프로세스마다 자신에게 할당된 메모리 내의 정보만 접근 할 수 있도록 제약을 두고 있고, 이를 벗어나는 정보에 접근하려면 오류가 발생한다.
      • 프로세스 보다 더 작은 실행 단위 개념이 필요하게 되었고, 이 개념이 바로 스레드이다.
  • 메모리 비교
    • Process
      • 각 프로세스마다 독자적인 CODE, DATA, STACK, HEAP 영역 구축
      • 프로세스는 오류나서 종료가 되도 다른 프로세스에 영향을 미치지 않음
    • Thread
      • 프로세스의 Code, Data, Heap 영역을 쓰레드마다 공유하고 Stack 영역만 독립하여 구축
      • 프로세스 하나가 오류가 발생해서 죽는다면 같은 프로세스내의 다른 스레드 모두가 강제 종료
      • 장점
        • Context-Switching할 때 공유하고 있는 메모리만큼의 메모리 자원을 아낄 수 있다.
        • 통신 비용이 적어 응답시간이 빠르다.
  • Context-Switching이란?
    • 인터럽트 요청에 의해 현재 진행하고 있는 Task(Process, Thread)의 상태를 저장하고 다음 진행할 Task의 상태 값을 읽어 적용하는 과정
    • CPU가 Task를 바꿔 가며 실행하기 위해 필요
    • 라운드 로빈 스케줄링
    • Context Switching 비용은 Process가 Thread보다 많이 소요
      • Thread는 Stack 영역을 제외한 모든 메모리를 공유하기 때문에 Context Switching 발생시 Stack 영역만 변경하면 된다.
      • 즉 Thread는 메모리 공간을 전환하지 않게 되면 CPU 상의 메모리 캐시를 그대로 유지할 수 있다.

 

Thread dump

  • jstack을 이용한 Thread dump 뜨기
  • jstack [pid] > thread.dump
  • RUNNABLE 상태면서 지속시간이 긴 Thread가 없는지, Lock 처리가 제대로 되지 않아 문제가 발생하고 있지는 않은지 확인
  • WAITING, TIMED_WAITING은 정상적인 상태

 

웹 서버에 영향 받는 지표

  • TLS 및 HTTP 헤더 보안성 + JS 라이브러리의 보안 취약성
  • 서버 응답시간 + 네트워크 비용 ( 웹서버에서 받은 컨텐츠의 첫번째 바이트가 얼마만에 도착? )
  • keep-alive 설정 ( connection 재사용을 하는지 )
  • gzip 압축을 했는지 ( 패킷 사이즈 줄이기 )
  • 이미지 압축 ( 이미지 품질에 따른 차이보다, 네트워크 지연에 더 민감하다 )
  • 정적 컨텐츠 캐싱 여부 ( 불필요한 요청 수를 줄이자 )
  • CDN을 사용하는지 ( 가까운 리전에서 받는 것이 속도차이 )
  • 지표 확인

 

부하 테스트 종류

  • smoke
    • 최소한의 부하로 테스트 시나리오 오류를 검증
    • VUser 1~2
    • 최소한의 부하로 구성된 테스트로, 테스트 시나리오에 오류가 없는지 확인할 수 있다.
  • Load
    • 서비스의 평소 트래픽과 최대 트래픽으로 구성
    • 기능이 정상 동작하는지 검증
    • 서비스의 평소 트래픽과 최대 트래픽 상황에서 성능이 어떤지 확인, 기능 정상 동작도 확인
    • 어플리케이션 배포 및 인프라 변경시에 성능 변화를 확인
    • 외부 요인에 따른 예외 상황을 확인
  • Stress
    • 점진적으로 부하가 증가하도록 구성
    • 최대 사용자, 최대 처리량등 한계점을 확인
    • 테스트이후 시스템이 수동 개입없이도 복구되는지 확인
    • 서비스가 극한의 상황에서 어떻게 동작하는지 확인
    • 장기간 부하 발생에 대한 한계치를 확인하고 기능이 정상 동작하는지 확인

 

부하 테스트시 주의할 점

  • 실제 사용자가 접속하는 황경에서 진행하여야 한다.
  • 내부 네트워크에서 부하를 발생시킬 경우 응답시간에 차이가 발생
  • 부하테스트는 클라이언트 내부 처리시간이 배제되어 있음
  • 테스트 DB에 들어 있는 데이터의 양이 실제 운영 DB와 동일해야한다.
    • 통상 전체 성능의 70% 이상이 DB에 좌우된다.
    • 테스트 대상의 테이블의 데이터 양이 다르면 쿼리의 실행계획이 달라져 성능이 다르게 나타날 수 있다.
  • 배치나 후속작업등 실제 서비스 요청외에 별도로 수행되는 작업이 있다면 테스트 시나리오에 포함되어야한다.
  • 외부 요인의 경우, 시스템과 분리된 별도의 서버로 구성해야한다.
  • 객체를 모킹하는 경우 네트워크 I/O가 발생하지 않는다.
  • 같은 어플리케이션의 더미 컨트롤러를 구성하는 경우 테스트 시스템의 자원과 리소스를 같이 사용하므로 테스트 신뢰성이 떨어진다.

 

서비스 모니터링

  • CloudWatch
    • Amazon Web Services 를 모니터링 서비스
    • 실행되고 있는 애플리케이션 모니터링을 실시간으로 지원합니다.
    • 공식문서 - CloudWatch 를 사용하여 리소스 및 애플리케이션에 대해 측정할 수 있는 변수인 지표를 수집하고 추적할 수 있습니다.
    • 사용자가 설정한 이벤트(조건)에 따라 알람 발송 기능
    • 시간 순서별 데이터 요소 셋(CPU 사용량, 메모리 사용량 등등)을 쌓아 보여준다. (Metrics)
  • Spring Actuator
    • Spring Boot Application의 상태 정보를 제공해주는 자체 모니터링 툴
    • 각종 추상화 클래스(HealthIndicator 등)을 제공하여, 상태 정보를 변경할 수 있도록 Service를 제공.
    • 제공 하는 endpoint
      • beans: application의 전체 Spring beans를 출력
      • caches: 사용가능한 cache를 노출
      • conditions: configuration 또는 auto-configuration 되는 class들의 성공 여부와 이유를 설명
      • env: Spring Boot의 현재 환경설정 정보(application.yml의 정보 등)를 출력
      • health: application의 현재 상태를 보여줍니다.
      • httptrace: http를 trace한 정보를 노출(기본적으로 최신 100건의 reqest-response를 보여줍니다.)
      • mappings: Request와 mapping되어있는 handler 정보를 가져옵니다.
      • sessions: Spring Session이 가지고 있는 정보를 가져옵니다.
      • threaddump: threaddump를 가져옴
      • logfile: log를 가져옵니다.
      • metrics: metrics 정보를 노출합니다.
    • 제공하는 endpoint들 중 민감한 정보( beans, evn )가 있기 때문에 반드시 환경설정을 해줘야한다.
    • management: endpoints: web: exposure: include: "*" exclude: env, beans
    • /health 더 알아보기
      • 어플리케이션에 대한 기본적인 정보를 제공한다.
      • Status가 UP 인 경우 어플리케이션이 정상적인 상태
      • DOWN 인경우 디비와 연결 문제가 있거나 디스크 공간이 부족하거나 등등의 문제가 있는 상태
    • /metrics 더 알아보기
      • JVM memory 사용률
      • CPU usage
    • 반드시 보안에 신경써서 설정해야한다.. Spring Security등을 활용해서 권한있는 사용자만 쓸 수 있게..
    • 커스텀 endpoint 만들기
      • HealthIndicator 를 구현하거나 AbstractHealthIndicator 를 상속받아 커스텀한 인디케이터를 만들 수 있다.
728x90
반응형