반응형
우아한 테크 캠프 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 : 이벤트와 메모리 통계 테이블을 표시
- procs: 프로세스 상태
서비스 상태 진단 :: 이벤트 기록
- 패킷과 시스템콜 등의 이벤트 기록을 확인
- 와이어샤크
서비스 상태 진단 :: 스냅샷
- 순간의 상태를 기록하여, 현재 문제가 발생하고 있지 않은지, 발생한다면 원인조사에 사용한다.
top
- 시스템의 상태를 전반적으로 빠르게 파악 가능
- 너무 많은 기능이 있어서.. 주로 확인하는 메모리에 대해서 정리!!
VIRT
- 프로세스가 사용하고 있는 virtual memory의 전체 용량
- SWAP + RES
RES
- 현재 프로세스가 사용하고 있는 물리 메모리의 양
- 실제로 메모리에 올려서 사용하고 있는 물리 메모리
SHR
- 다른 프로세스와 공유하고 있는 shared memory의 양
- 공유 메모리에 올려지는 라이브러리 ( 글로벌하게 리눅스 프로세스에 사용되는 라이브러리 등등 )
USE 방법론
- 문제 상황을 판단하기 위해 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
반응형
'Study > 우아한 테크 캠프 Pro' 카테고리의 다른 글
우아한 테크 캠프 PRO, 7주차 레거시 코드 리팩토링 (0) | 2021.08.07 |
---|---|
우아한 테크 캠프 PRO, 5주차 인수 테스트 기반 TDD (0) | 2021.08.07 |
우아한 테크 캠프 PRO, 4주차 그럴듯한 서비스 만들기 (0) | 2021.08.07 |
우아한 테크 캠프 PRO, 3주차 인수 테스트 주도 개발 (0) | 2021.08.07 |
우아한 테크 캠프 PRO, 2주차 JPA (0) | 2021.08.07 |