17 KiB
운영 센터 사용법
AdminFront에서 시스템 → 운영 센터를 연다. 주소는 /system/operations다. System Role이 super_admin인 사용자만 메뉴와 API를 사용할 수 있다. Tenant Authority의 owner나 admin만 가진 사용자는 대상이 아니다. 역할의 의미는 권한 컨텍스트를 따른다.
시스템 상태 확인
시스템 상태 탭이 보이는 동안 5초마다 상태를 갱신한다. 인스턴스 ID, 빌드 정보, 수집 시각을 먼저 확인한다. 여러 서버를 운영한다면 각 응답은 요청을 처리한 서버의 상태이며 전체 서버의 합계가 아니다. 이전 응답이 남아 있어도 갱신 오류나 오래된 수집 시각이 보이면 현재 상태로 판단하지 않는다.
- Heap allocation은 Go 객체가 현재 사용하는 힙이다. Heap reserved는 런타임이 확보한 힙 공간이다.
- RSS는 운영체제가 집계한 프로세스의 상주 메모리다. Go 힙과 같지 않다.
- Total allocated는 시작 이후의 누적 할당량이다. 현재 메모리 사용량이나 누수 크기가 아니다. 초당 할당량과 힙 추이를 함께 확인한다.
- Goroutines는 현재 goroutine 수다. 같은 부하에서 계속 늘어나는지 관찰한다.
- GC 정지와 스케줄러 대기 histogram은 수집 구간별 bin의 발생 횟수다. 첫 수집에는 이전 표본이 없어 구간 통계가 없다. 상한이 없는 마지막 bin은
null로 표현한다. - 지원하지 않는 RSS·cgroup 항목이나 수집이 꺼진 항목은 사용할 수 없음으로 표시한다. 0으로 해석하지 않는다.
최근 약 15분의 런타임 이력은 인스턴스 메모리에 보관되며 재시작하면 사라진다. 장기 관찰에는 별도의 시계열 저장소가 필요하다.
의존 서비스 확인
Backend 연결 풀에서는 사용 중 연결 수, 최대 연결 수, 누적 대기 횟수와 시간을 확인합니다. 서버 통계는 Backend PostgreSQL, Backend ClickHouse, Ory 로그 ClickHouse로 구분합니다. 이미지 배포는 하나의 ClickHouse 서버 안에 업무 DB와 Ory 로그 DB를 나누므로 두 카드의 서버 전체 수치는 같을 수 있습니다. 수집 실패는 대상별로 표시합니다. 풀 통계 조회 성공만으로 원격 서비스의 정상 상태를 판단하지 마십시오.
PostgreSQL에서는 연결 수와 한도, 실행 쿼리, 열린 채 대기 중인 트랜잭션, 잠금 대기와 DB 크기를 확인합니다. 커밋·롤백·교착 상태·임시 데이터·캐시 적중·디스크 읽기는 각 DB의 통계 초기화 이후 누적값입니다. 화면의 초기화 시각은 가장 최근 DB 초기화 시각입니다. 서버 전체 통계에는 관측 계정의 pg_read_all_stats 권한과 대상 DB의 CONNECT 권한이 필요합니다. 권한을 자동으로 부여하지 않으며 부족하면 사용할 수 없음으로 표시합니다.
Ory PostgreSQL은 격리된 DB 네트워크에 두며 운영센터에서 직접 조회하지 않습니다. Ory 서비스 카드에서 Kratos Public·Admin, Hydra, Keto, Oathkeeper의 준비 상태와 검사 응답 시간을 확인합니다. 검사 응답 시간은 readiness API의 응답 시간입니다. 실제 업무 요청의 오류와 지연은 아래 요청 통계에서 함께 확인합니다.
이미지 배포 번들은 Ory 로그 스키마를 초기화하고 Vector 수집기를 시작합니다. 수집기는 INSERT 전용 계정으로 Oathkeeper 파일 로그를 저장하고 backend는 SELECT 전용 계정으로 읽습니다. 계정 설정은 번들에서 생성하며 별도 비밀번호 입력은 필요하지 않습니다. 로그 조회 연결은 저장소가 일시적으로 중단되어도 다음 조회에서 다시 연결합니다. 수집기는 볼륨에 둔 디스크 버퍼와 전송 확인으로 재시작에 대비하며, 원본에 유효한 시각이 있으면 이를 보존합니다. 재전송 중 같은 기록이 다시 전달될 수 있습니다.
ClickHouse의 연결 수, 메모리, 실행 쿼리와 병합 수는 서버 전체 수치입니다. 저장공간과 데이터 조각 수는 접속 DB의 활성 MergeTree 데이터 조각만 포함합니다. 실행 쿼리 수에는 통계를 수집하는 쿼리도 포함합니다.
Redis에서는 현재 사용량, 시작 이후 최대 사용량, 상주 메모리, 데이터 메모리와 설정 한도를 확인합니다. 값은 Redis 서버의 모든 DB를 포함합니다. 최대 사용량은 누적 할당량이 아니며 캐시를 비워도 초기화되지 않습니다. 설정 한도 0은 사용량 0이 아니라 별도 한도가 없다는 뜻입니다.
Identity 캐시 비우기는 기존 identity cache API를 사용합니다. 확인창에서 동의하면 해당 캐시 키만 삭제하고 메모리를 다시 조회합니다. 로그인 진행 상태와 중복 실행 방지 키는 유지합니다. 캐시가 복구될 때까지 로그인 조회가 실패할 수 있습니다. 세대별 projection 데이터 전체를 삭제하지 않으므로 서버 전체 메모리 반환을 보장하지 않습니다.
성능 비교 이력 가져오기
정상 실행에서 수집한 baseline과 candidate의 원시 지연 시간 배열을 JSON 파일로 준비해 성능 이력 화면에서 가져온다. 서버가 배열을 정렬해 nearest-rank 방식으로 p50·p95·p99를 다시 계산한다. 예를 들어 30개 표본의 p95는 정렬한 29번째 값이다. 기존에 계산한 분위수만 보내는 형식은 받지 않는다.
한 파일의 최상위 객체에 name, baseline, candidate, p95BudgetRatio를 넣는다. baseline과 candidate는 각각 실행 객체이며 각 실행의 metrics는 측정 항목 객체의 배열이다. fixture의 사용자·테넌트·actor 수는 정수이고 hash는 문자열이다. 입력 구조를 그대로 사용할 수 있는 완전한 JSON 예제를 먼저 내려받아 확인한다. 새 비교에는 실행 식별자와 측정값, 소스·이미지·fixture 정보를 해당 실행의 실제 값으로 바꾼다.
각 실행에는 다음 정보가 필요하다. 정확한 필드 정의는 성능 이력 API 코드를 참조한다.
| 항목 | 입력 조건 |
|---|---|
| 실행 식별 | runId, 소스 식별 해시 sourceRevision, 불변 이미지 ID imageId |
| 소스 | Git revision 40자리 또는 소스 manifest SHA-256 64자리. manifest 해시는 별도 원본과 함께 보관한다. |
| 이미지 | sha256: 뒤에 64자리 16진수 |
| 환경 | local, test, staging 중 하나 |
| 측정 방식 | normal-http 또는 normal-browser |
| fixture | identities, tenants, actors, 전체 측정 데이터 조건의 SHA-256 hash |
| 동시성 | 양의 정수 concurrency |
| 진단 여부 | diagnosticsEnabled, cpuProfileEnabled, traceEnabled를 모두 명시적으로 false |
| 측정 항목 | 고유한 이름, warmupCount 5 이상, 양수 밀리초 배열 samplesMs 30개 이상 |
| 처리량 입력 | 선택 항목 measuredElapsedMs는 워밍업을 제외한 측정 구간의 실제 경과 시간. 개별 표본의 최댓값보다 작을 수 없음 |
| 오류 | httpFailures와 transportFailures는 모두 0 |
| 허용 비율 | p95BudgetRatio 기본 1.1. 더 엄격한 양의 값으로 낮출 수 있으며 1.1을 초과할 수 없음 |
baseline과 candidate의 환경·측정 방식·fixture·동시성·측정 항목·워밍업 횟수가 일치해야 한다. 프로파일링을 켠 실행을 정상 실행과 비교할 수 없다. 파일은 1 MiB 이하, 실행당 항목은 20개 이하, 항목당 표본은 10,000개 이하다.
비교 상태가 passed라는 것은 모든 항목의 candidate p95가 설정한 비율 이내라는 뜻이다. p99나 절대 응답 시간 목표를 달성했다는 뜻은 아니다. p99와 원시 표본도 확인한다. 오류가 발생한 실행은 비교용 성공 표본에서 조용히 제외하지 말고 측정 실행의 별도 증거로 남긴다.
처리량은 표본 수를 실제 측정 경과 시간으로 나눈 requests/second다. measuredElapsedMs가 없으면 사용할 수 없음으로 표시한다. 지연 시간의 역수로 처리량을 추정하지 않는다. 같은 조건의 여러 측정 구간을 합칠 때는 표본 배열을 합치고 해당 구간의 경과 시간도 합산한다.
이력은 PostgreSQL에 저장된다. 동일 사용자가 같은 내용을 재전송하면 기존 기록을 반환한다. 원본 실행의 진위를 서버가 인증하는 기능은 아니므로 기록은 operator_imported 출처로 표시한다. 소스·이미지·fixture manifest와 실행 로그는 원래의 이슈나 Actions artifact에도 보관한다.
실제 측정값 예제는 이전 검색 개선 이슈의 HTTP 측정을 가져온 것이다. 출처는 #2430에서 확인한다. 운영 센터 자체의 새 성능 측정 결과로 해석하지 않는다.
수집 설정
일반 운영 지표는 기본 활성화다. 수집 비용 비교나 수집 중지가 필요하면 서버 실행 인수에 --operations-metrics=false를 지정한다. UI에서 프로세스 실행 설정을 바꾸지는 않는다.
빌드·인스턴스 정보는 .env.sample의 BARON_INSTANCE_ID, BARON_RELEASE_VERSION, BARON_RELEASE_GIT_COMMIT을 사용한다. 빌드 정보가 없으면 unknown으로 표시한다. 여러 인스턴스에 같은 ID를 지정하지 않는다.
CPU·힙·스택 진단은 기본 비활성화입니다. 일반 빌드에서도 모든 환경에서 --operations-diagnostics로 켤 수 있습니다. 끄려면 플래그를 생략하거나 --operations-diagnostics=false를 지정하고 backend를 다시 시작하십시오. UI는 시작 플래그를 변경하지 않습니다. 기존 검색 구간 진단 --profile-search의 빌드·환경 제한은 별도로 유지합니다.
진단 artifact에는 함수명과 실행 경로 같은 내부 정보가 포함될 수 있다. 해당 작업을 조사하는 관리자에게만 전달하고 공개 이슈에 원본을 첨부하지 않는다.
요청 지연의 위치 좁히기
기본 정렬은 누적 소요 시간 내림차순입니다. 오류 열 제목을 누르면 오류 횟수 내림차순으로 바뀝니다. HTTP와 Ory 표는 정렬 선택을 각각 유지합니다. 등록 endpoint에 도달하지 않은 요청은 unmatched로 집계하며 실제 요청 URL은 표시하지 않습니다. 기존 / 또는 /api/v1 미들웨어 경로로 집계되던 미등록 요청도 여기에 포함됩니다.
의존 서비스 화면의 요청 통계에서 같은 인스턴스에 반복되는 HTTP route의 횟수·오류 수·지연 분포를 확인한다. route는 등록된 경로 템플릿으로 집계하며 사용자 ID, 검색어, 토큰을 label에 넣지 않는다. 운영 센터 자체의 폴링은 이 통계에서 제외한다. HTTP series는 256개와 초과분 집계 1개로 제한한다.
Kratos·Keto·Hydra 통계는 서비스와 HTTP method 단위다. 해당 클라이언트의 요청 시작부터 응답 헤더 수신까지를 측정하며 본문 다운로드·JSON 해석 시간은 포함하지 않는다. 따라서 API 전체 지연과 동일하게 해석하지 않는다. 오류는 transport 실패 또는 HTTP 400 이상이다. histogram의 각 bin은 해당 구간의 누적 횟수이고, 모든 bin의 합이 요청 횟수다. 상위 경계까지의 누적 합 형식이 아니다.
예를 들어 API 응답이 느려졌는데 Ory 지연은 안정적이고 DB 대기가 늘었다면 DB 연결 경합을 우선 조사한다. Ory 지연이 같이 늘면 해당 의존 서비스와 네트워크 구간을 확인한다. 통계만으로 원인을 확정하지 말고 진단 artifact나 독립된 요청 기록과 대조한다.
작업과 진단
작업 화면의 읽기 전용 점검은 DB와 Redis에 실제 연결 확인을 수행한다. 점검에 성공하면 succeeded, 실패하면 failed로 끝난다. 업무 데이터나 권한 관계는 수정하지 않는다.
작업은 이 요청을 받은 인스턴스에서 실행된다. 취소 버튼은 협력적 취소 요청을 보낸다. 작업이 canceled로 끝났는지 다시 확인한다. 이미 끝난 작업은 취소할 수 없다. 프로세스 자체나 임의의 goroutine을 강제로 종료하는 기능이 아니다.
진단을 허용한 인스턴스에서는 스택을 확인하거나 비동기 진단 작업을 시작할 수 있다. CPU 수집 시간은 기본 5초이며 1~30초다. 같은 인스턴스에서는 진단 작업 하나만 동시에 수행한다. 완료된 작업에서 ZIP을 내려받으면 전후 goroutine 스택과 manifest, 선택한 CPU·힙 profile을 확인할 수 있다.
# 내려받은 ZIP을 별도 작업 디렉터리에 푼 뒤 실행
go tool pprof -top cpu.pprof
go tool pprof -top -sample_index=inuse_space heap.pprof
# 누적 할당량을 조사할 때
go tool pprof -top -sample_index=alloc_space heap.pprof
스택에서는 오래 대기하는 함수와 반복되는 호출 경로를 확인한다. CPU profile에서는 CPU를 소비한 함수를 확인한다. Heap의 inuse_space는 수집된 프로파일 기준으로 살아 있는 객체의 샘플링된 메모리이고 alloc_space는 누적 할당량이다. 둘을 메모리 누수 크기로 단정하지 않는다. 프로파일링 중 측정한 응답 시간을 정상 실행의 성능 비교에 넣지 않는다.
작업 목록과 artifact는 메모리에 보관된다. 최대 50개 작업, artifact 하나당 최대 16 MiB, 보관 artifact 총합 32 MiB로 제한한다. artifact는 30분 후 만료되며 용량이 부족하면 먼저 제거될 수 있다. 작업 기록은 1시간 후 제거될 수 있고 재시작하면 모두 사라진다. 여러 인스턴스 사이에서 작업과 다운로드를 공유하지 않으므로 같은 인스턴스로 접근해야 한다.
로드밸런서 뒤에 여러 backend가 있다면 운영용 AdminFront의 API_PROXY_TARGET을 조사할 단일 backend 주소로 지정해 실행한다. AdminFront 서버는 이 값을 API 프록시 대상으로 사용한다. 접속 후 시스템 상태를 두 번 새로 고쳐 인스턴스 ID가 같은지 확인한 뒤 작업을 시작한다. 작업 완료·취소·다운로드까지 같은 AdminFront와 프록시 대상을 유지한다. 이 기능 자체가 로드밸런서의 세션 고정이나 인스턴스 선택을 제공하지는 않는다.
큐의 실패 항목 처리
큐 화면에서 대기·실패 수와 해당 상태 항목의 가장 오래된 생성 시각을 확인한다. 이 시각은 마지막 실패나 재시도 시각과 다르다. 작업·큐 탭은 화면이 보이는 동안 10초마다 갱신하며, 재시도 후에는 새로고침 버튼으로 즉시 확인할 수 있다. 실패 목록은 큐별 최대 20개만 표시하므로 표시된 행 수가 전체 실패 수와 같지 않을 수 있다.
실패 원인은 timeout, 의존 서비스 연결 실패, 권한 거부, 요청 제한, 기타 relay 실패로 분류한다. 오류 문자열을 고정 범주로 분류한 조사 단서이며 원인을 확정하는 진단은 아니다. 개별 요청의 payload나 외부 서비스 오류 원문은 표시하지 않는다. 정확한 원인은 해당 outbox ID로 내부 로그를 조회해 확인한다.
Keto 실패 항목은 원인을 해결한 뒤 해당 행의 재시도를 선택한다. 서버는 기존 권한 변경과 같은 subject 잠금 안에서 최신 generation과 상태를 다시 확인한 후 failed를 pending으로 바꾼다. 이미 대기 중인 항목의 반복 요청은 중복 작업을 만들지 않는다. 이후 실제 relay가 완료하는지는 큐 상태를 새로 조회해 확인한다. 재시도 수락은 외부 반영 완료가 아니다.
오래된 generation이나 더 이상 재시도할 수 없는 항목은 거부한다. 선행 작업이 끝나지 않았거나 의존 서비스 장애가 남아 있으면 대기가 계속될 수 있다. WORKS 복구는 WORKS 연동 Runbook의 해당 작업 흐름을 따릅니다.
진단 탭의 큐 재시도 관리 버튼으로 작업·큐 탭을 여십시오. Keto와 WORKS의 대기·실패 항목에서 재시도 중단을 선택하고 확인하십시오. 중단한 항목은 기록과 선행 관계를 유지하며 자동·수동 재시도에서 제외됩니다. 중단 수는 별도로 표시합니다. 이미 처리 중이거나 완료된 작업은 중단할 수 없습니다. 선행 작업을 중단하면 후속 작업이 계속 대기할 수 있습니다.
중단을 성공 처리로 간주하지 않습니다. 이 화면은 중단 해제나 전체 큐 삭제를 제공하지 않습니다.