서킷브레이커 해제
증상
- 특정 파이프라인 작업이
circuit breaker OPEN에러로 실행 거부됨 - orchestrator_state.json 의
circuit_breakers에 OPEN 상태 항목 존재 - 장애 원인이 해소되었지만 서킷브레이커가 자동 복구(half-open)되지 않음
- 텔레그램에 "서킷브레이커 활성화" 알림 수신
원인
- 연속 실패 임계치 초과 — 특정 파이프라인이 N회 연속 실패하여 자동 차단
- 외부 의존 일시 장애 — DB, API, 네트워크 문제가 해소된 후에도 OPEN 상태 잔존
- half-open 전환 실패 — 타임아웃 설정이 너무 길어 자동 복구 지연
- 수동 차단 — 운영자가 의도적으로 OPEN 설정 후 해제를 잊음
해결 단계
1. 현재 서킷브레이커 상태 확인
python3 -c "
import json, os
state_path = os.path.expanduser('~/.openclaw/workspace/memory/orchestrator_state.json')
with open(state_path) as f:
state = json.load(f)
cbs = state.get('circuit_breakers', {})
if not cbs:
print('No circuit breakers configured')
else:
for name, cb in cbs.items():
status = cb.get('state', 'UNKNOWN')
failures = cb.get('failure_count', 0)
last_failure = cb.get('last_failure_at', 'N/A')
print(f' {name}: state={status}, failures={failures}, last_failure={last_failure}')
"
2. 근본 원인 해소 확인
서킷브레이커를 해제하기 전에 원인이 해소되었는지 확인하세요.
# DB 접근 확인
sqlite3 ~/.openclaw/data/ops_multiagent.db "SELECT 1;" && echo "DB OK" || echo "DB FAILED"
# 네트워크 확인
curl -s --max-time 5 https://openrouter.ai/api/v1/models > /dev/null && echo "Network OK" || echo "Network FAILED"
# 헬스체크
python3 ~/.openclaw/workspace/scripts/health_check.py
3. 특정 서킷브레이커 수동 해제
# 예: 'blog_monitor' 서킷브레이커 해제
python3 -c "
import json, os, tempfile
state_path = os.path.expanduser('~/.openclaw/workspace/memory/orchestrator_state.json')
with open(state_path) as f:
state = json.load(f)
target = 'blog_monitor' # 해제할 서킷브레이커 이름
cbs = state.get('circuit_breakers', {})
if target in cbs:
cbs[target]['state'] = 'CLOSED'
cbs[target]['failure_count'] = 0
cbs[target].pop('last_failure_at', None)
print(f'Circuit breaker \"{target}\" reset to CLOSED')
else:
print(f'Circuit breaker \"{target}\" not found')
print(f'Available: {list(cbs.keys())}')
tmp_fd, tmp_path = tempfile.mkstemp(dir=os.path.dirname(state_path))
with os.fdopen(tmp_fd, 'w') as tmp:
json.dump(state, tmp, indent=2, ensure_ascii=False)
os.replace(tmp_path, state_path)
print('State saved')
"
4. 전체 서킷브레이커 일괄 해제
주의: 근본 원인이 해소되지 않은 상태에서 일괄 해제하면 장애가 재발합니다.
python3 -c "
import json, os, tempfile
state_path = os.path.expanduser('~/.openclaw/workspace/memory/orchestrator_state.json')
with open(state_path) as f:
state = json.load(f)
cbs = state.get('circuit_breakers', {})
reset_count = 0
for name, cb in cbs.items():
if cb.get('state') != 'CLOSED':
cb['state'] = 'CLOSED'
cb['failure_count'] = 0
cb.pop('last_failure_at', None)
reset_count += 1
print(f' Reset: {name}')
tmp_fd, tmp_path = tempfile.mkstemp(dir=os.path.dirname(state_path))
with os.fdopen(tmp_fd, 'w') as tmp:
json.dump(state, tmp, indent=2, ensure_ascii=False)
os.replace(tmp_path, state_path)
print(f'Total reset: {reset_count} circuit breakers')
"
5. 해제 후 작업 수동 트리거 (선택)
# 해제한 파이프라인을 즉시 한 번 실행하여 정상 동작 확인
# 예: blog_monitor
python3 ~/.openclaw/workspace/scripts/pipeline/blog_monitor.py --once 2>&1 | tail -20
확인 방법
# 서킷브레이커 상태 재확인
python3 -c "
import json
with open('$HOME/.openclaw/workspace/memory/orchestrator_state.json') as f:
state = json.load(f)
cbs = state.get('circuit_breakers', {})
open_cbs = [n for n, cb in cbs.items() if cb.get('state') != 'CLOSED']
if open_cbs:
print(f'Still OPEN: {open_cbs}')
else:
print('All circuit breakers CLOSED')
"
# 전체 시스템 헬스체크
python3 ~/.openclaw/workspace/scripts/health_check.py
# ops DB 상태 확인
python3 ~/.openclaw/workspace/scripts/check_ops_db.py