Initial commit
This commit is contained in:
285
API_SAFE_OPERATION.md
Normal file
285
API_SAFE_OPERATION.md
Normal file
@@ -0,0 +1,285 @@
|
||||
# 모의투자 API 안전 운영 가이드
|
||||
|
||||
한국투자증권 모의투자 API를 안전하고 안정적으로 운영하기 위한 재시도 및 쓰로틀링 전략이 적용되어 있습니다.
|
||||
|
||||
## 주요 기능
|
||||
|
||||
### 1. 안전한 재시도 전략 (Exponential Backoff)
|
||||
|
||||
- **재시도 횟수 제한**: 최대 3회 (설정 가능)
|
||||
- **점진적 백오프**: 재시도 간격이 지수적으로 증가 (1.5초 → 3초 → 6초)
|
||||
- **오류 유형 분별**:
|
||||
- 429 (Rate Limit), 5xx (서버 오류): 재시도 실행
|
||||
- 4xx (클라이언트 오류, 인증 실패): 즉시 종료
|
||||
- **타임아웃 처리**: 30초 타임아웃 + 재시도 로직
|
||||
|
||||
### 2. 쓰로틀링 전략
|
||||
|
||||
- **초당 호출 제한**: 기본 0.5초 간격 (초당 2회 권장)
|
||||
- **동시 요청 제한**: 최대 2건의 동시 요청 (세마포어 사용)
|
||||
- **자동 간격 조절**: 마지막 요청 시간 기반 자동 대기
|
||||
|
||||
### 3. 모니터링 & 경고
|
||||
|
||||
- **실시간 통계 수집**: 총 호출 수, 오류율, 재시도 횟수, 평균 응답 시간
|
||||
- **오류율 경고**: 30% 초과 시 자동 경고
|
||||
- **API 상태 체크 엔드포인트**: `/api/v1/monitoring/api-stats`
|
||||
|
||||
---
|
||||
|
||||
## 환경 변수 설정
|
||||
|
||||
`.env` 파일에 다음 설정을 추가하여 조절할 수 있습니다:
|
||||
|
||||
```bash
|
||||
# API 재시도 설정
|
||||
API_MAX_RETRIES=3 # 최대 재시도 횟수 (기본: 3)
|
||||
API_RETRY_DELAY=1.5 # 초기 재시도 대기 시간(초) (기본: 1.5)
|
||||
API_RETRY_BACKOFF=2.0 # 지수 백오프 배율 (기본: 2.0)
|
||||
|
||||
# API 쓰로틀링 설정
|
||||
API_MIN_REQUEST_INTERVAL=0.5 # 최소 요청 간격(초) - 초당 2회 (기본: 0.5)
|
||||
API_MAX_CONCURRENT_REQUESTS=2 # 동시 최대 요청 수 (기본: 2)
|
||||
API_TIMEOUT=30.0 # API 타임아웃(초) (기본: 30.0)
|
||||
|
||||
# 모니터링 설정
|
||||
API_ERROR_THRESHOLD=0.3 # 오류율 경고 임계값 (기본: 30%)
|
||||
API_MONITORING_WINDOW=100 # 모니터링 윈도우 크기 (기본: 100개 요청)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## API 사용 예시
|
||||
|
||||
### 기본 사용 (자동 재시도 + 쓰로틀링)
|
||||
|
||||
```python
|
||||
from app.services.korea_investment_api import korea_investment_api
|
||||
|
||||
# 현재가 조회 (자동 재시도 및 쓰로틀링 적용)
|
||||
result = await korea_investment_api.get_current_price("005930")
|
||||
|
||||
# 일봉 데이터 조회
|
||||
chart = await korea_investment_api.get_daily_chart("005930")
|
||||
|
||||
# 종목 리스트 조회
|
||||
stocks = await korea_investment_api.get_stock_list("J") # KOSPI
|
||||
```
|
||||
|
||||
### 통계 조회
|
||||
|
||||
```python
|
||||
# API 호출 통계 확인
|
||||
stats = korea_investment_api.get_monitor_stats()
|
||||
print(f"총 호출: {stats['total_calls']}건")
|
||||
print(f"오류율: {stats['error_rate']:.1%}")
|
||||
print(f"평균 응답 시간: {stats['avg_duration']:.2f}초")
|
||||
|
||||
# 로그에 통계 출력
|
||||
korea_investment_api.log_monitor_stats()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 모니터링 API 엔드포인트
|
||||
|
||||
### 1. API 통계 조회
|
||||
|
||||
```bash
|
||||
GET http://localhost:8000/api/v1/monitoring/api-stats
|
||||
```
|
||||
|
||||
**응답 예시:**
|
||||
```json
|
||||
{
|
||||
"status": "healthy",
|
||||
"stats": {
|
||||
"total_calls": 150,
|
||||
"total_errors": 5,
|
||||
"total_retries": 8,
|
||||
"error_rate": 0.033,
|
||||
"avg_duration": 1.25,
|
||||
"recent_calls": 100
|
||||
},
|
||||
"message": "오류율: 3.3%, 평균 응답: 1.25초"
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 헬스체크
|
||||
|
||||
```bash
|
||||
GET http://localhost:8000/api/v1/monitoring/health
|
||||
```
|
||||
|
||||
**응답 예시:**
|
||||
```json
|
||||
{
|
||||
"status": "healthy",
|
||||
"error_rate": 0.033,
|
||||
"total_calls": 150,
|
||||
"timestamp": "2025-11-10T09:30:00"
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 통계 로깅
|
||||
|
||||
```bash
|
||||
POST http://localhost:8000/api/v1/monitoring/log-stats
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 배치 스크립트 실행
|
||||
|
||||
매일 아침 9시 전체 종목 분석을 실행하는 배치 스크립트:
|
||||
|
||||
### 테스트 실행 (10개 종목만)
|
||||
|
||||
```bash
|
||||
cd backend
|
||||
python batch_daily_analysis.py --test
|
||||
```
|
||||
|
||||
### 제한된 수 실행
|
||||
|
||||
```bash
|
||||
python batch_daily_analysis.py --limit 50
|
||||
```
|
||||
|
||||
### 전체 실행
|
||||
|
||||
```bash
|
||||
python batch_daily_analysis.py
|
||||
```
|
||||
|
||||
### Cron 스케줄 설정 (매일 평일 오전 9시)
|
||||
|
||||
```bash
|
||||
crontab -e
|
||||
```
|
||||
|
||||
다음 라인 추가:
|
||||
```bash
|
||||
0 9 * * 1-5 cd /path/to/auto-stock/backend && /path/to/python batch_daily_analysis.py >> /path/to/logs/batch.log 2>&1
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 로그 확인
|
||||
|
||||
배치 스크립트 실행 시 다음과 같은 상세 로그를 확인할 수 있습니다:
|
||||
|
||||
```
|
||||
2025-11-10 09:00:00 - INFO - 🚀 Starting daily batch analysis for 2025-11-10
|
||||
2025-11-10 09:00:00 - INFO - ⚙️ Rate Limiting: 0.5초 간격, 최대 재시도 3회
|
||||
2025-11-10 09:00:05 - INFO - ✅ Found 30 KOSPI stocks
|
||||
2025-11-10 09:00:10 - INFO - ✅ Found 30 KOSDAQ stocks
|
||||
2025-11-10 09:00:10 - INFO - 📊 Total tradable stocks: 60
|
||||
2025-11-10 09:00:15 - INFO - [1/60] Analyzing 005930 (삼성전자)...
|
||||
2025-11-10 09:00:16 - INFO - ✅ Saved analysis for 005930 (삼성전자): score=5
|
||||
...
|
||||
2025-11-10 09:02:30 - INFO - ============================================================
|
||||
2025-11-10 09:02:30 - INFO - ✅ Batch analysis completed!
|
||||
2025-11-10 09:02:30 - INFO - 📊 Success: 58 / Total: 60
|
||||
2025-11-10 09:02:30 - INFO - ❌ Failed: 2
|
||||
2025-11-10 09:02:30 - INFO - ⏱️ Duration: 145.2 seconds (2.4 minutes)
|
||||
2025-11-10 09:02:30 - INFO - 📡 API 통계:
|
||||
2025-11-10 09:02:30 - INFO - - 총 호출: 122건
|
||||
2025-11-10 09:02:30 - INFO - - 오류: 3건 (2.5%)
|
||||
2025-11-10 09:02:30 - INFO - - 재시도: 5건
|
||||
2025-11-10 09:02:30 - INFO - - 평균 응답 시간: 1.18초
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 문제 해결
|
||||
|
||||
### 1. 오류율이 높을 때 (30% 이상)
|
||||
|
||||
- **원인**: API 서버 불안정 또는 네트워크 문제
|
||||
- **해결책**:
|
||||
- `API_RETRY_DELAY`를 2~3초로 증가
|
||||
- `API_MAX_RETRIES`를 5회로 증가
|
||||
- `API_MIN_REQUEST_INTERVAL`을 1초로 증가 (호출 빈도 낮춤)
|
||||
|
||||
```bash
|
||||
# .env 파일 수정
|
||||
API_RETRY_DELAY=2.5
|
||||
API_MAX_RETRIES=5
|
||||
API_MIN_REQUEST_INTERVAL=1.0
|
||||
```
|
||||
|
||||
### 2. 타임아웃 빈발
|
||||
|
||||
- **원인**: 네트워크 지연 또는 API 응답 느림
|
||||
- **해결책**: 타임아웃 시간 증가
|
||||
|
||||
```bash
|
||||
API_TIMEOUT=60.0
|
||||
```
|
||||
|
||||
### 3. Rate Limit 초과 (429 에러)
|
||||
|
||||
- **원인**: 요청 간격이 너무 짧음
|
||||
- **해결책**: 요청 간격 증가
|
||||
|
||||
```bash
|
||||
API_MIN_REQUEST_INTERVAL=1.0 # 초당 1회로 제한
|
||||
API_MAX_CONCURRENT_REQUESTS=1 # 동시 요청 1건으로 제한
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 성능 튜닝 팁
|
||||
|
||||
### 안정성 우선 (추천)
|
||||
|
||||
```bash
|
||||
API_MIN_REQUEST_INTERVAL=0.5
|
||||
API_MAX_CONCURRENT_REQUESTS=2
|
||||
API_MAX_RETRIES=3
|
||||
API_RETRY_DELAY=1.5
|
||||
```
|
||||
|
||||
### 속도 우선 (주의)
|
||||
|
||||
```bash
|
||||
API_MIN_REQUEST_INTERVAL=0.3
|
||||
API_MAX_CONCURRENT_REQUESTS=3
|
||||
API_MAX_RETRIES=2
|
||||
API_RETRY_DELAY=1.0
|
||||
```
|
||||
|
||||
### 대규모 배치용 (안전 중시)
|
||||
|
||||
```bash
|
||||
API_MIN_REQUEST_INTERVAL=1.0
|
||||
API_MAX_CONCURRENT_REQUESTS=1
|
||||
API_MAX_RETRIES=5
|
||||
API_RETRY_DELAY=2.0
|
||||
API_RETRY_BACKOFF=3.0
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 추가 모니터링
|
||||
|
||||
### Prometheus + Grafana 연동 (선택 사항)
|
||||
|
||||
API 통계를 Prometheus 형식으로 내보내려면 `/api/v1/monitoring/metrics` 엔드포인트를 추가 구현할 수 있습니다.
|
||||
|
||||
### 알림 설정 (선택 사항)
|
||||
|
||||
오류율이 임계값을 초과할 때 Slack/Email 알림을 보내도록 확장 가능합니다.
|
||||
|
||||
---
|
||||
|
||||
## 참고 자료
|
||||
|
||||
- [한국투자증권 Open API 문서](https://apiportal.koreainvestment.com/)
|
||||
- [FastAPI 공식 문서](https://fastapi.tiangolo.com/)
|
||||
- [httpx 재시도 전략](https://www.python-httpx.org/)
|
||||
|
||||
---
|
||||
|
||||
**문의 및 피드백**: 시스템 운영 중 문제가 발생하면 로그 파일과 API 통계를 함께 확인하세요.
|
||||
Reference in New Issue
Block a user