Files
web-page-backend/CHECK_POINT.md
gahusb 83113ab50c docs(check-point): mark #10 already-applied, #11 denied, #12 deferred
#10 NAS LLM 호출 → Windows AI 통일 — 확인 결과 이미 적용. NAS .env가
LLM_PROVIDER=claude + OLLAMA_URL=192.168.45.59:11435. NAS Celeron에서
LLM 추론 안 함. 코드 변경 불필요.

#11 컨테이너 리소스 제한 (cpus 0.5 등) — 박재오 진행 금지. J4025 2C
환경에서 오히려 throughput 손해라는 판단.

#12 NAS 하드웨어 업그레이드 — 박재오 보류 결정.

또한 web-ai V1(:8000)+V2(:8001)+launcher 총 4개 process 종료. NAS API
polling 부담 즉각 감소.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 11:00:04 +09:00

8.0 KiB
Raw Blame History

web-backend CHECK_POINT

NAS Docker 11 컨테이너(9 백엔드 + frontend + deployer). Synology Celeron J4025 (2C 2.0GHz) 18GB. 2026-05-18 작성 — uvicorn CPU 폭주 진단 결과 정리.

🔴 즉시 (오늘, 총 1시간 5분)

1. 09:00 cron 5분 스태거링 가장 큰 효과

파일: agent-office/app/scheduler.py:72-76

# 변경 전 — 09:00 동시 실행 (CPU 폭주 원인 #1)
scheduler.add_job(_run_insta_trends_collect, "cron", hour=9, minute=0)
scheduler.add_job(_run_lotto_schedule, "cron", day_of_week="mon", hour=9, minute=0)
scheduler.add_job(_run_youtube_research, "cron", hour=9, minute=0)

# 변경 후 — 5분 스태거링
scheduler.add_job(_run_insta_trends_collect, "cron", hour=9, minute=0,  id="insta_trends")
scheduler.add_job(_run_lotto_schedule,       "cron", day_of_week="mon", hour=9, minute=5, id="lotto_curate")
scheduler.add_job(_run_youtube_research,     "cron", hour=9, minute=10, id="youtube_research")

파일: realestate-lab/app/main.py:51

# 변경 전
scheduler.add_job(scheduled_collect, "cron", hour=9, minute=0, id="collect")

# 변경 후
scheduler.add_job(scheduled_collect, "cron", hour=9, minute=15, id="collect")
  • agent-office scheduler.py 수정 (2026-05-18)
  • realestate-lab main.py 수정 (2026-05-18)
  • git commit + push (Gitea Webhook 자동 빌드)

2. insta-lab Playwright Semaphore(1)

파일: insta-lab/app/main.py (모듈 레벨 추가)

import asyncio

# 모듈 레벨에 한 번만 선언
RENDER_SEMAPHORE = asyncio.Semaphore(1)  # Chromium 동시 실행 1개로 제한

# 카드 렌더 백그라운드 함수에 감싸기
async def _bg_render(task_id: str, slate_id: int):
    async with RENDER_SEMAPHORE:
        await card_renderer.render_slate(slate_id, ...)
  • card_renderer.render_slate를 Semaphore(1)로 감쌈 (2026-05-18, lazy init)
  • 동시 2개 요청 테스트 (curl 동시 2회 → 순차 처리되는지 확인)

3. healthcheck interval 60s

파일: docker-compose.yml (모든 9 컨테이너)

# 변경 전
healthcheck:
  interval: 30s

# 변경 후
healthcheck:
  interval: 60s
  • docker-compose.yml 10개 healthcheck 일괄 변경 (9 백엔드 + frontend, 2026-05-18)
  • docker compose up -d 재기동
  • docker stats 로 CPU 5% 정도 감소 확인

4. uvicorn --workers 1 명시

모든 Dockerfile CMD:

CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000", "--workers", "1"]

영향 9 파일 (모두 2026-05-18 적용):

  • lotto/Dockerfile
  • stock/Dockerfile
  • music-lab/Dockerfile
  • insta-lab/Dockerfile
  • realestate-lab/Dockerfile
  • agent-office/Dockerfile
  • personal/Dockerfile
  • packs-lab/Dockerfile
  • travel-proxy/Dockerfile

docker compose build --no-cache 후 재기동.


5. lotto Monte Carlo 08:05 → 08:30

파일: lotto/app/main.py:86

# 변경 전 — stock 08:00과 5분 차이로 겹침
scheduler.add_job(_run_simulation_job, "cron", hour="0,4,8,12,16,20", minute=5)

# 변경 후 — 25분 분리
scheduler.add_job(_run_simulation_job, "cron", hour="0,4,8,12,16,20", minute=30)
  • lotto/app/main.py 수정 (2026-05-18)

🟡 중기 (1~2주)

6. Chromium Browser Pool 재설계 (insta-lab) 2026-05-18

  • 매번 launch X → 1개 인스턴스 재사용
  • 카드 10장 렌더 시간 30% 단축 기대
  • card_renderer.py 내부에 모듈 레벨 _PLAYWRIGHT/_BROWSER + init_browser/shutdown_browser 함수 (별도 모듈 분리 안 함, 같은 파일에 인접 배치)
  • _render_slate_locked 본체에서 _get_browser() 재사용 (crashed 시 lazy 재초기화)
  • main.py startup hook에서 init_browser(), shutdown hook에서 shutdown_browser()

7. stock 뉴스 스크랩 비동기화 — ⚠️ 보류 2026-05-18

  • 재진단: stock은 BackgroundScheduler 사용 중 → main loop 블로킹 없음 (이미 별도 thread)
  • fetch_market_news의 4개 동기 requests.get은 network I/O wait라 CPU 거의 사용 안 함
  • to_thread로 wrap해도 BackgroundScheduler 환경에서 사실상 의미 없음
  • 진짜 효과를 보려면 AsyncIOScheduler 전환 + scraper.py 4개 fetch를 aiohttp 병렬로 — 큰 리팩토링 vs 효과 불명확
  • 박재오 판단: 큰 리팩토링 진행 여부

8. realestate 수집 병렬화 2026-05-18

  • 파일: realestate-lab/app/main.py:scheduled_collect
  • collect_all() + delete_old_completed_announcements() 병렬
  • BackgroundScheduler 환경이라 asyncio.gather 대신 ThreadPoolExecutor(max_workers=2) 사용 (효과 동일)
  • 매칭은 순차 유지 (DB 일관성)
  • ThreadPoolExecutor 적용

9. lotto Monte Carlo 시뮬레이션 빈도 검토

  • 현재 6회/일 (00·04·08·12·16·20)
  • 실제 필요 빈도 박재오 결정 — 3회/일(아침·점심·저녁)로 줄이면 CPU 50% 감소
  • 박재오 의사결정 후 cron 변경

🟢 장기 (1개월+)

10. 무거운 작업 Windows AI 서버로 이전 이미 적용 상태 (2026-05-18 확인)

  • 확인 결과: NAS .env가 이미 LLM_PROVIDER=claude + OLLAMA_URL=http://192.168.45.59:11435로 설정됨
  • 실 운영은 Anthropic Claude (원격 API) — NAS Celeron에서 LLM 추론 안 함
  • Ollama fallback 사용 시에도 Windows AI 서버로 통일
  • stock 외 다른 컨테이너에 ollama/qwen 호출 코드 없음
  • 결론: 코드/설정 변경 불필요

11. 컨테이너 리소스 제한 — 진행 금지 (박재오 명시 2026-05-18)

  • J4025 2C 환경에서 cpus 0.5 제한은 오히려 throughput 손해
  • 향후 작업자 무심코 도입하지 말 것

12. NAS 업그레이드 검토 — ⏸️ 보류 (박재오 명시 2026-05-18)

  • 현재: Celeron J4025 (2C 2.0GHz)
  • 대안: Ryzen N5105 (4C 2.0GHz) NAS — 4코어로 병렬성 2배
  • 자금·우선순위 결정 대기

최근 완료 (참고)

  • 2026-05-15: insta-lab 신설 (포트 18700, Jinja2 + Playwright + Claude Sonnet)
  • 2026-05-16: insta-lab Playwright 1080×1350 PNG 렌더 완성
  • 2026-05-17: agent-office random idle 제거, ADMIN_API_KEY 강화 (stock)
  • 2026-05-17: insta-lab minimal theme + design_importer 추가
  • 2026-05-17: blog-lab 트랙 완전 폐기 (docker-compose에 없음, 위키 정정 완료)
  • 2026-05-18: 🔴 즉시 5건 일괄 적용 — 09:00 cron 스태거링(insta/lotto/youtube/realestate), lotto Monte Carlo 08:30, insta-lab Semaphore(1), healthcheck 60s, uvicorn --workers 1 명시 (사용자 push + NAS deployer 재기동 대기)
  • 2026-05-18: 🟡 중기 2건 적용 — #6 insta-lab Chromium Browser Pool (lifecycle hook), #8 realestate ThreadPoolExecutor 병렬 (collect/delete). #7 stock async는 BackgroundScheduler 사용 중이라 재진단 후 보류 (효과 미미). #9 Monte Carlo 빈도는 박재오 결정 대기.
  • 2026-05-18: 🟢 장기 진단·결정 — #10은 이미 적용 상태 확인 (LLM_PROVIDER=claude, OLLAMA_URL=Windows AI). #11 컨테이너 리소스 제한 박재오 진행 금지. #12 NAS 업그레이드 보류. web-ai V1(:8000)+V2(:8001) 4개 process 종료 — NAS API polling 부담 즉시 감소.

🔧 진단 커맨드 (NAS bash)

# 실시간 CPU 사용 (상위 15)
top -b -n 1 | head -25

# 프로세스별 CPU 정렬
ps aux --sort=-%cpu | head -15

# uvicorn·chromium·python 프로세스만
ps aux | grep -E "uvicorn|chromium|python" | grep -v grep

# 스케줄러 실행 로그 (최근 50)
docker logs agent-office 2>&1 | grep -E "APScheduler|executing" | tail -50

# insta-lab Chromium 프로세스 개수
docker exec insta-lab ps aux | grep chromium | wc -l

# 컨테이너별 CPU/메모리 실시간
docker stats --no-stream

📚 참고

  • 진단 풀 보고서: C:\Users\jaeoh\Documents\Obsidian Vault\raw\2026-05-18-NAS-uvicorn-CPU-진단-개선안.md
  • 위키 페이지: 사업-개인-웹-플랫폼 (CPU 부하 진단 섹션 + 컨테이너 표)
  • docker-compose.yml: 본 디렉토리 루트

변경 이력

  • 2026-05-18: 페이지 신설. 즉시 5건 + 중기 4건 + 장기 3건. 진단 커맨드.