728x90

devops 5

[ClickHouse] Langfuse 쿼리 스톨 오진단 24.10 타임아웃 슬롯 버그

부제: 그럴듯한 우회로 때우다 진짜 원인을 놓칠 뻔한 이야기관측용으로 Langfuse를 쓰고, 그 뒤에서 ClickHouse가 트레이스를 저장한다. 어느 날 이 ClickHouse가 12시간 동안 먹통이 됐다. 사고를 어떻게 잘못 짚었다가 바로잡았는지 적어둔다.증상프로세스는 살아 있었다. 크래시도 OOM도 아니었다. 그런데 모든 쿼리가 멈췄다. 헬스체크로 날리는 SELECT 1조차 응답을 못 했다. 타임아웃을 60초로 걸어 뒀는데, 그 한 줄짜리 쿼리가 로그상 75분 넘게 슬롯을 붙들고 있었다. 설정한 타임아웃이 그냥 무시된 거다. host swap도 9 GiB 가까이 올라 있었다.그럴듯했던 오답사고 직전에 서버가 PDF를 잔뜩 처리하던 참이었다. 그 과정에서 14MB짜리 base64 데이터가 트레이스에..

Infra 2026.07.01

[Prometheus] Docker 컨테이너 자원 cgroup v2 직독 cAdvisor 대체

컨테이너별 메모리·CPU를 모니터링하려고 했다. 보통은 cAdvisor 같은 익스포터를 붙이는데, 이 호스트에선 그게 잘 안 맞았다. 그래서 커널의 cgroup을 직접 읽기로 했다. 왜 cAdvisor를 안 썼나이 호스트는 컨테이너 이미지 저장에 containerd-snapshotter(overlayfs)를 쓴다. 이 조합에서 cAdvisor는 컨테이너를 제대로 못 봤다.도커 방식으로 조회하면 컨테이너를 0개로 인식했다.containerd 방식으로 조회하면 이름이 해시로 잡혀, compose 서비스 라벨이 사라졌다. 서비스 단위(api, postgres …)로 묶어 보는 대시보드를 만들 수가 없다.새 컨테이너(cAdvisor 등)를 여럿 띄우는 것도 부담이라, 작은 수집기 하나만 추가해서 cgroup을 ..

Infra 2026.06.25

[nginx] OpenResty 채택 이유 유효 API 키 rate-limit 면제

부제: 순정 nginx 대신 OpenResty를 쓰게 된 이유리버스 프록시로 순정 nginx를 쓰고 있었다. rate limit도 nginx 기본 기능(limit_req)으로 IP 기준으로 걸어 뒀다. 처음엔 충분했는데, 트래픽 구조 때문에 한 가지 문제가 생겼다.출발점백엔드(BE) 하나가 자기 IP·API 키 하나로 여러 end-user의 요청을 한데 모아 보낸다. 그러다 보니 동시성이 잠깐 치솟으면, 정상적인 BE 트래픽인데도 IP 기준 rate limit에 걸려 429가 났다. 진짜 과한 호출이 아니라 집약 구조 때문에 생긴 false positive였다.그래서 방향을 정했다. 유효한 API 키로 들어온 요청은 rate limit에서 면제하고, IP 제한은 그 외에만 적용하자.왜 순정 nginx로는..

Infra 2026.06.25

[Docker] bind-mount 설정 미반영 원인 force-recreate

배포 스크립트가 새 태그를 체크아웃하고 docker compose up -d nginx로 nginx를 올린다. 호스트 디스크의 설정 파일은 분명히 새 내용으로 바뀌었는데, 실제 요청은 계속 404가 났다.무슨 일이 있었나설정은 bind-mount로 컨테이너에 연결돼 있었다. 디스크의 파일을 바꾸면 컨테이너 안에서도 같은 파일이 보이니, 당연히 반영될 거라고 생각했다.그런데 docker compose up -d는 컨테이너 spec이 바뀌었을 때만 재생성한다. bind-mount된 파일의 내용이 바뀐 것은 spec 변경이 아니다. 이미지 태그도, 환경변수도, 볼륨 정의도 그대로니까 compose 입장에선 "바뀐 게 없는" 컨테이너다. 그래서 재기동을 건너뛰고, 실행 중이던 nginx 워커는 처음 켜질 때 읽..

Infra 2026.06.25

[Grafana] 무트래픽 구간 spanNulls 보간 제거 rate 0 채움

개인 프로젝트라 트래픽이 거의 없다. 채팅 API가 하루 20건도 안 들어온다. 이런 환경에서 모니터링 대시보드를 만들다 보면 한 가지 문제에 부딪힌다.요청이 없는 구간에서 그래프가 어떻게 보여야 하나?문제Grafana에서 rate() 패널을 그리면, 호출이 없는 구간은 데이터가 없어서 선이 끊긴다. 끊긴 게 보기 싫어서 spanNulls(점 사이 잇기)를 켜면 끊긴 점들이 비스듬한 직선으로 이어진다.그런데 이 선은 실제와 다르다. 요청이 0건이던 구간이 트래픽이 조금씩 흐른 것처럼 보이게 된다. 측정값이 없던 구간을 그래프가 채워 넣는 셈이다.끊긴 그래프가 답인가꼭 그렇지도 않다. 메트릭 종류마다 "데이터 없음"의 의미가 다르기 때문이다.rate (req/s): 호출이 없으면 값은 0이다. 0으로 채우..

Infra 2026.06.25
728x90