// ===================================================== // 資料庫連線管理中間件 // ===================================================== import { NextRequest, NextResponse } from 'next/server'; import { db } from './database'; import { dbMonitor } from './database-monitor'; import { dbShutdownManager } from './database-shutdown-manager'; import { connectionMonitor } from './connection-monitor'; // 連線池狀態追蹤 let connectionCount = 0; const maxConnections = 20; // 與資料庫配置保持一致 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 = await connectionMonitor.getConnectionStats(); return { isHealthy: stats.isHealthy, connectionCount: stats.activeConnections, 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('🔄 使用資料庫關閉管理器進行優雅關閉...'); await dbShutdownManager.gracefulShutdown(); } // 強制關閉 export function forceShutdown() { console.log('🚨 強制關閉資料庫連線...'); dbShutdownManager.forceShutdown(); } // 獲取關閉狀態 export function getShutdownStatus() { return dbShutdownManager.getShutdownStatus(); } // 測試關閉機制 export async function testShutdown() { return await dbShutdownManager.testShutdown(); }