// ===================================================== // 資料庫連線管理中間件 // ===================================================== import { NextRequest, NextResponse } from 'next/server'; import { db } from './database'; import { dbMonitor } from './database-monitor'; // 連線池狀態追蹤 let connectionCount = 0; const maxConnections = 3; // 與資料庫配置保持一致 export function withDatabaseConnection( handler: (...args: T) => Promise ) { return async (...args: T): Promise => { // 檢查連線池狀態 if (connectionCount >= maxConnections) { console.warn(`⚠️ 連線池已滿 (${connectionCount}/${maxConnections}),等待可用連線...`); // 等待一段時間後重試 await new Promise(resolve => setTimeout(resolve, 100)); if (connectionCount >= maxConnections) { return NextResponse.json( { success: false, error: '資料庫連線池已滿,請稍後再試', retryAfter: 5 // 建議5秒後重試 }, { status: 503 } ); } } connectionCount++; try { const result = await handler(...args); return result; } catch (error) { console.error('資料庫操作錯誤:', error); // 根據錯誤類型返回適當的響應 if (error instanceof Error) { if (error.message.includes('ER_CON_COUNT_ERROR')) { return NextResponse.json( { success: false, error: '資料庫連線數已達上限,請稍後再試', retryAfter: 10 }, { status: 503 } ); } else if (error.message.includes('ECONNRESET') || error.message.includes('PROTOCOL_CONNECTION_LOST')) { return NextResponse.json( { success: false, error: '資料庫連線中斷,請重試', retryAfter: 3 }, { status: 503 } ); } } return NextResponse.json( { success: false, error: '資料庫操作失敗', details: error instanceof Error ? error.message : '未知錯誤' }, { status: 500 } ); } finally { connectionCount--; } }; } // 連線池健康檢查 export async function checkConnectionHealth(): Promise<{ isHealthy: boolean; connectionCount: number; maxConnections: number; usagePercentage: number; }> { try { const stats = dbMonitor.getConnectionStats(); return { isHealthy: stats.usagePercentage < 80, connectionCount: stats.currentConnections, maxConnections: stats.maxConnections, usagePercentage: stats.usagePercentage }; } catch (error) { console.error('連線健康檢查失敗:', error); return { isHealthy: false, connectionCount: 0, maxConnections: 0, usagePercentage: 100 }; } } // 自動釋放空閒連線 export async function autoReleaseIdleConnections(): Promise { try { const health = await checkConnectionHealth(); if (health.usagePercentage > 70) { console.log('🔄 連線使用率過高,嘗試釋放空閒連線...'); return await dbMonitor.releaseIdleConnections(); } return true; } catch (error) { console.error('自動釋放連線失敗:', error); return false; } } // 連線池監控 export function startConnectionMonitoring() { // 每30秒檢查一次連線狀態 dbMonitor.startMonitoring(30000); // 每5分鐘嘗試釋放空閒連線 setInterval(async () => { await autoReleaseIdleConnections(); }, 5 * 60 * 1000); console.log('🔍 資料庫連線監控已啟動'); } // 優雅的關閉 export async function gracefulShutdown() { console.log('🔄 正在優雅關閉資料庫連線...'); try { dbMonitor.stopMonitoring(); await db.close(); console.log('✅ 資料庫連線已關閉'); } catch (error) { console.error('❌ 關閉資料庫連線時發生錯誤:', error); } } // 處理程序退出事件 if (typeof process !== 'undefined') { process.on('SIGINT', gracefulShutdown); process.on('SIGTERM', gracefulShutdown); process.on('exit', gracefulShutdown); }