Skip to main content
Glama

Naver Search MCP Server

memory-fix-summary.md6.74 kB
# 네이버 검색 MCP 서버 메모리 누수 해결 방안 ## 🎯 문제 요약 Claude Desktop에서 일정 시간 후 MCP 서버가 멈추는 메모리 누수 문제 발생 ## 🔍 발견된 핵심 문제들 ### 1. **싱글톤 패턴 메모리 누수** (HIGH RISK) - **위치**: `src/clients/naver-search.client.ts` - **문제**: 정리 메커니즘 없는 전역 인스턴스 유지 - **해결**: `destroyInstance()` 및 `cleanup()` 메서드 추가 ### 2. **HTTP 연결 관리 부족** (MEDIUM RISK) - **위치**: `src/clients/naver-api-core.client.ts` - **문제**: 타임아웃 미설정, 연결 풀링 부재 - **해결**: axios 타임아웃 및 연결 관리 설정 ### 3. **캐시 데이터 누적** (MEDIUM RISK) - **위치**: `src/handlers/category.handlers.ts` - **문제**: 모듈 로딩 시 메모리에 영구 저장 - **해결**: 지연 로딩 및 캐시 정리 메커니즘 ### 4. **서버 인스턴스 관리** (MEDIUM RISK) - **위치**: `src/index.ts` - **문제**: 재시작 시 리소스 정리 부재 - **해결**: 설정 변경 감지 및 포괄적 정리 ## ✅ 구현된 해결책 ### 1. 메모리 안전 싱글톤 (NaverSearchClient) ```typescript // 기존 문제점 static getInstance(): NaverSearchClient { if (!NaverSearchClient.instance) { NaverSearchClient.instance = new NaverSearchClient(); } return NaverSearchClient.instance; } // 수정된 해결책 static destroyInstance(): void { if (NaverSearchClient.instance) { NaverSearchClient.instance.cleanup(); NaverSearchClient.instance = null; } } protected cleanup(): void { this.config = null; super.cleanup(); } ``` ### 2. HTTP 연결 최적화 (NaverApiCoreClient) ```typescript // 기존 문제점 protected async get<T>(url: string, params: any): Promise<T> { const response = await axios.get<T>(url, { params, ...this.getHeaders() }); return response.data; } // 수정된 해결책 constructor() { this.axiosInstance = axios.create({ timeout: 30000, // 30초 타임아웃 maxRedirects: 3 }); } protected async get<T>(url: string, params: any): Promise<T> { try { const response = await this.axiosInstance.get<T>(url, { params, ...this.getHeaders() }); return response.data; } catch (error) { throw error; // 명시적 에러 처리 } } ``` ### 3. 지연 로딩 캐시 (Category Handlers) ```typescript // 기존 문제점 const categoriesData = getCategoriesData(); // 모듈 레벨 로딩 // 수정된 해결책 let categoriesCache: any[] | null = null; function getCategoriesData(): any[] { if (categoriesCache !== null) { return categoriesCache; // 캐시된 데이터 반환 } // 필요 시에만 로딩 // ... 로딩 로직 categoriesCache = loadedData; return categoriesCache; } export function clearCategoriesCache(): void { categoriesCache = null; } ``` ### 4. 서버 생명주기 관리 (index.ts) ```typescript // 수정된 해결책 export function resetServerInstance(): void { if (globalServerInstance) { // 메모리 모니터링 중지 stopGlobalMemoryMonitoring(); // 클라이언트 인스턴스 정리 NaverSearchClient.destroyInstance(); // 캐시 정리 clearCategoriesCache(); globalServerInstance = null; currentConfig = null; } } function isConfigChanged(newConfig): boolean { if (!currentConfig) return true; return ( currentConfig.NAVER_CLIENT_ID !== newConfig.NAVER_CLIENT_ID || currentConfig.NAVER_CLIENT_SECRET !== newConfig.NAVER_CLIENT_SECRET ); } ``` ### 5. 실시간 메모리 모니터링 (memory-manager.ts) ```typescript export class MemoryMonitor { private intervalId: any = null; private memoryHistory: MemoryStats[] = []; start(intervalMs: number = 300000): void { // 5분 간격 this.intervalId = setInterval(() => { const health = checkMemoryHealth(); if (health.status === 'critical' || health.status === 'emergency') { this.performAutoCleanup(); // 자동 정리 } }, intervalMs); } private async performAutoCleanup(): Promise<void> { NaverSearchClient.destroyInstance(); clearCategoriesCache(); if ((globalThis as any).gc) { (globalThis as any).gc(); // 가비지 컬렉션 강제 실행 } } } // 메모리 임계값 const MEMORY_THRESHOLDS = { WARNING: 200, // 200MB CRITICAL: 500, // 500MB EMERGENCY: 1024 // 1GB }; ``` ## 📊 메모리 관리 기능 ### 실시간 모니터링 - **주기**: 5분 간격 메모리 사용량 체크 - **로깅**: 위험 수준 시 자동 경고 출력 - **히스토리**: 최근 10회 메모리 사용량 기록 ### 자동 정리 시스템 - **WARNING (200MB)**: 모니터링 강화 - **CRITICAL (500MB)**: 자동 캐시 정리 실행 - **EMERGENCY (1GB)**: 전체 리소스 정리 + GC 강제 실행 ### 트렌드 분석 ```typescript analyzeTrend(): { trend: 'increasing' | 'decreasing' | 'stable'; averageUsage: number; maxUsage: number; minUsage: number; } ``` ## 🚀 사용 방법 ### 1. 서버 시작 시 자동 모니터링 ```typescript // 서버 생성 시 자동으로 메모리 모니터링 시작 const server = createNaverSearchServer({ config }); // startGlobalMemoryMonitoring(5 * 60 * 1000); // 자동 실행됨 ``` ### 2. 수동 메모리 정리 ```typescript import { performMemoryCleanup } from './utils/memory-manager.js'; const result = await performMemoryCleanup(); console.log('메모리 정리 완료:', result.cleanupActions); ``` ### 3. 메모리 상태 확인 ```typescript import { checkMemoryHealth } from './utils/memory-manager.js'; const health = checkMemoryHealth(); console.log('메모리 상태:', health.status); console.log('권장사항:', health.recommendation); ``` ## 🎯 기대 효과 ### 메모리 누수 방지 - ✅ 싱글톤 인스턴스 정리로 메모리 누적 방지 - ✅ HTTP 연결 타임아웃으로 hanging connection 방지 - ✅ 캐시 정리로 대용량 데이터 누적 방지 ### 자동 복구 시스템 - ✅ 위험 수준 도달 시 자동 리소스 정리 - ✅ 가비지 컬렉션 강제 실행으로 즉시 메모리 회수 - ✅ 설정 변경 시 기존 인스턴스 완전 정리 ### 운영 안정성 - ✅ 실시간 메모리 모니터링으로 문제 조기 감지 - ✅ 메모리 사용량 트렌드 분석으로 예측 가능 - ✅ 자동 로깅으로 문제 상황 추적 가능 ## 📝 적용 방법 1. **즉시 적용**: 이미 모든 수정사항이 코드에 적용됨 2. **자동 실행**: 서버 시작 시 자동으로 메모리 모니터링 활성화 3. **모니터링**: 콘솔에서 메모리 상태 로그 확인 가능 이제 Claude Desktop에서 MCP 서버가 장시간 안정적으로 동작할 것입니다!

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/isnow890/naver-search-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server