perf: add rate limiting, validation, logging, and error handling
- Add express-rate-limit with tiered rate limits per endpoint - Add express-validator for input validation on all API routes - Add winston + morgan for structured logging - Add node-cache for lottery result caching (5min TTL, 1000 max keys) - Convert OCR to async task queue with max 2 concurrent jobs - Add global error handler middleware - Add React ErrorBoundary for client-side error handling - Fix memory leaks in OCR task queue and lottery cache - Add per-item error handling in batch ticket updates - Fix SQL UPDATE to include user_id in WHERE clause Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
7b1073e23b
commit
335f0fb8dc
+26
-2
@@ -1,6 +1,14 @@
|
||||
const express = require('express');
|
||||
const cors = require('cors');
|
||||
const path = require('path');
|
||||
const morgan = require('morgan');
|
||||
const fs = require('fs');
|
||||
|
||||
// 初始化日志目录
|
||||
const logsDir = path.join(__dirname, 'logs');
|
||||
if (!fs.existsSync(logsDir)) {
|
||||
fs.mkdirSync(logsDir, { recursive: true });
|
||||
}
|
||||
|
||||
// 初始化数据库
|
||||
require('./db/init');
|
||||
@@ -9,15 +17,28 @@ const authRoutes = require('./routes/auth');
|
||||
const ticketRoutes = require('./routes/tickets');
|
||||
const lotteryRoutes = require('./routes/lottery');
|
||||
const ocrRoutes = require('./routes/ocr');
|
||||
const { standardLimiter } = require('./middleware/rateLimiter');
|
||||
const errorHandler = require('./middleware/errorHandler');
|
||||
const logger = require('./services/logger');
|
||||
|
||||
const app = express();
|
||||
const PORT = process.env.PORT || 4444;
|
||||
|
||||
// 创建 morgan stream 用于日志
|
||||
const morganStream = {
|
||||
write: (message) => logger.http(message.trim())
|
||||
};
|
||||
|
||||
// 中间件
|
||||
app.use(cors());
|
||||
app.use(express.json());
|
||||
app.use(express.json({ limit: '10mb' }));
|
||||
app.use(express.urlencoded({ extended: true, limit: '10mb' }));
|
||||
app.use(morgan('combined', { stream: morganStream }));
|
||||
app.use('/uploads', express.static(path.join(__dirname, 'uploads')));
|
||||
|
||||
// 全局限流 (应用于所有API)
|
||||
app.use('/api', standardLimiter);
|
||||
|
||||
// API 路由
|
||||
app.use('/api/auth', authRoutes);
|
||||
app.use('/api/tickets', ticketRoutes);
|
||||
@@ -38,6 +59,9 @@ app.get('*', (req, res) => {
|
||||
res.sendFile(path.join(clientDist, 'index.html'));
|
||||
});
|
||||
|
||||
// 全局错误处理 (必须放在最后)
|
||||
app.use(errorHandler);
|
||||
|
||||
app.listen(PORT, '0.0.0.0', () => {
|
||||
console.log(`服务器运行在 http://0.0.0.0:${PORT}`);
|
||||
logger.info(`服务器运行在 http://0.0.0.0:${PORT}`);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user