728x90

전체 글 428

[디버깅] google-genai SDK TypeError 마스킹 APIError 노출

부제: 에러 메시지가 진짜 원인을 가리고 있을 때LLM 호출이 가끔 실패하는데, 로그에는 이런 메시지만 남았다.'ClientResponse' object is not subscriptable이 메시지로는 아무것도 알 수 없었다. 쿼터가 초과된 건지(429), 서버가 죽은 건지(503), 타임아웃인지(504), 모델 글리치인지 판별이 안 됐다. 진짜 원인이 이 메시지 뒤에 가려져 있었다.증상추적해 보니 SDK 안에서 일어난 일이었다.google-genai의 응답 객체에는 본문을 파싱하는 json 프로퍼티가 있는데, 스트리밍 경로에서 내부 값이 리스트가 아닐 때 [0] 인덱싱을 시도하다 TypeError를 던졌다. 문제는 이 TypeError가 터지는 위치다.상위 라이브러리(langchain)는 에러 응답을..

AI 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

[Prompt] OOC, Temporal Blindness

LangGraph 기반 서비스를 운영하며 만난 두 가지 행동 문제와, 그것을 해결한 과정을 정리한다. 둘 다 처음엔 "프롬프트를 고치면 되겠지"로 접근했지만 정답은 정반대였다.현상1. OOC: 캐릭터 밖으로 새는 메타 발언a2ui(인터랙티브 버튼)를 생성하는 턴에서, 응답 본문에 이런 것들이 섞여 나왔다.// 훈련 추가/재요청 버튼 생성*(시스템상 버튼을 다시 생성합니다)* 버튼 자체는 정상 렌더됐다. 문제는 텍스트였다. 모델이 도구 태그()와 "시스템상 버튼을 다시 생성합니다" 같은 시스템 내레이션을 유저에게 그대로 노출했다. 트리거는 유저의 "1,2,3이 모두 없어졌는데"였다 — 이전 UI가 사라졌다고 메커니즘을 대화 주제로 꺼내자, 모델이 그걸 받아 "다시 생성합니다"라고 자기 동작을 해설한 것이다..

AI 2026.06.16

[Langfuse] Self-Hosted v3: ClickHouse 서버 리소스 최적화

TL;DRLangfuse v3 셀프호스팅 환경에서 ClickHouse의 시스템 로그 테이블이 무한 증가하며 CPU 107%, 메모리 OOM, 디스크 I/O 폭증을 유발했다. Langfuse 공식 문서와 AWS Terraform 옵션을 참고하여 시스템 로그 비활성화, 백그라운드 스레드 축소, 메모리 제한 조정으로 CPU를 107%에서 5%로 낮췄다. 환경GCP Compute Engine: 8 vCPU, 8GB RAM, 100GB DiskLangfuse v3 (Docker Compose, 단일 노드)ClickHouse 24.10.2 (clickhouse/clickhouse-server:24-alpine)PostgreSQL 17 + pgvector, Redis 7, MinIO, Nginx1. 증상: 서버가 반..

Infra 2026.02.09

[Proxmox] 랜섬웨어 방어 및 재해 복구(DR) 전략

이 글은 proxmox 구축 전 상태에서 Gemini와 검토한 자료입니다. 추후 테스트 후 업데이트 예정입니다.1. 아키텍처 개요 (Architecture)목표운영/개발 서버(Proxmox)가 랜섬웨어에 의해 모든 데이터가 암호화되더라도 서비스 정상화.백업 서버(PBS) 자체가 공격당해도 시놀로지 계층에서 방어.구성도Source: Proxmox VE (운영/개발 VM + 호스트 설정)Backup Server: Synology NAS VMM(Virtual Machine Manager) 위에 설치된 Proxmox Backup Server (PBS)Last Line of Defense: Synology Snapshot Replication (PBS VM 이미지를 보호) Proxmox는 PBS에 백업을 Push..

Infra 2025.11.29

[Proxmox] ZFS RAID 복구 시나리오

이 글은 아직 Proxmox 구축 전 단계에서 Gemini와 대화하며 구성된 자료입니다. 추후 테스트 후 수정 예정입니다.준비 사항서버 상태: Proxmox가 SSD 2개에 ZFS RAID 1(Mirror)로 설치되어 있어야 합니다.마음가짐: "나는 지금 이 서버를 고장 낼 것이다."1단계: 정상 상태 확인 (Baseline)먼저 서버가 건강한지 확인하고, 디스크의 시리얼 넘버나 ID를 기록해둡니다.상태 확인:state: ONLINE 확인.rpool 아래에 두 개의 디스크가 보일 것입니다.zpool status -v디스크 ID 확인 (중요):어떤 게 sda이고 sdb인지, 실제 모델명과 시리얼 번호를 메모해둡니다.ls -l /dev/disk/by-id/2단계: 장애 발생 시뮬레이션 (물리적 제거)가장 확..

Infra 2025.11.29
728x90