mm_os 3.2.9 → 3.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +47 -1
- package/core/base/mqtt/index.js +1109 -1106
- package/core/base/web/index.js +245 -156
- package/core/com/event/README.md +4 -4
- package/core/com/event/com.json +3 -3
- package/core/com/event/config.tpl.json +18 -18
- package/core/com/event/drive.js +132 -132
- package/core/com/event/index.js +344 -344
- package/core/com/event/script.js +25 -25
- package/core/com/middleware/com.js +152 -151
- package/core/com/socket/config.tpl.json +2 -2
- package/core/com/socket/drive.js +2 -2
- package/core/com/socket/index.js +1 -1
- package/core/com/sql/drive.js +7 -7
- package/core/com/static/index.js +1 -1
- package/index.js +34 -5
- package/middleware/cors/index.js +112 -96
- package/middleware/cors/middleware.json +18 -7
- package/middleware/csrf/index.js +202 -0
- package/middleware/csrf/middleware.json +24 -0
- package/middleware/ip_firewall/index.js +476 -0
- package/middleware/ip_firewall/middleware.json +109 -0
- package/middleware/mqtt_base/middleware.json +2 -1
- package/middleware/security_audit/index.js +543 -0
- package/middleware/security_audit/middleware.json +48 -0
- package/middleware/waf/index.js +273 -7
- package/middleware/waf/middleware.json +2 -1
- package/middleware/waf_ddos/index.js +520 -0
- package/middleware/waf_ddos/middleware.json +38 -0
- package/middleware/waf_xss/index.js +269 -0
- package/middleware/waf_xss/middleware.json +18 -0
- package/middleware/web_after/middleware.json +2 -1
- package/middleware/web_base/middleware.json +2 -1
- package/middleware/web_before/middleware.json +3 -2
- package/middleware/web_check/middleware.json +2 -1
- package/middleware/web_main/middleware.json +2 -1
- package/middleware/web_proxy/middleware.json +2 -1
- package/middleware/web_render/middleware.json +2 -1
- package/middleware/web_socket/middleware.json +4 -3
- package/middleware/web_static/middleware.json +2 -1
- package/package.json +28 -15
- package/middleware/log/index.js +0 -32
- package/middleware/log/middleware.json +0 -9
- package/middleware/performance/index.js +0 -143
- package/middleware/performance/middleware.json +0 -16
- package/middleware/rate_limit/index.js +0 -112
- package/middleware/rate_limit/middleware.json +0 -10
- package/middleware/waf_ip/index.js +0 -168
- package/middleware/waf_ip/middleware.json +0 -10
- package/nodemon.json +0 -31
- package/package.txt +0 -1
- package/rps.bat +0 -3
- package/test.js +0 -10
- package/tps.bat +0 -3
- package/update.bat +0 -1
- package//347/263/273/347/273/237/346/236/266/346/236/204/350/257/204/344/274/260/344/270/216/344/274/230/345/214/226/345/273/272/350/256/256.md +0 -599
|
@@ -1,599 +0,0 @@
|
|
|
1
|
-
# mm_os系统架构评估与优化建议
|
|
2
|
-
|
|
3
|
-
## 系统架构概述
|
|
4
|
-
|
|
5
|
-
mm_os是一个基于Koa的服务端框架,设计用于快速构建网站、游戏、小程序、AIoT服务端等应用。系统采用模块化、中间件式架构,具备热拔插能力,支持分布式部署。
|
|
6
|
-
|
|
7
|
-
### 核心架构组件
|
|
8
|
-
|
|
9
|
-
1. **OS类**:系统核心类,负责配置加载、模块初始化和服务启动
|
|
10
|
-
2. **中间件系统**:由Middleware类管理,支持按顺序加载和执行各种功能模块
|
|
11
|
-
3. **双服务模式**:同时支持Web服务(基于Koa)和MQTT服务
|
|
12
|
-
4. **插件机制**:支持热拔插,可快速扩展功能
|
|
13
|
-
5. **应用管理**:通过应用管理器统一管理业务逻辑
|
|
14
|
-
|
|
15
|
-
## 已完成的优化工作
|
|
16
|
-
|
|
17
|
-
### 1. 中间件异步错误捕获机制
|
|
18
|
-
|
|
19
|
-
已为以下13个中间件添加了完善的异步错误捕获机制:
|
|
20
|
-
- rate_limit:API速率限制中间件
|
|
21
|
-
- web_render:Web渲染中间件
|
|
22
|
-
- log:请求日志中间件
|
|
23
|
-
- web_after:请求后处理中间件
|
|
24
|
-
- web_main:请求主要处理中间件
|
|
25
|
-
- web_check:请求验证中间件
|
|
26
|
-
- waf_ip:IP防火墙中间件
|
|
27
|
-
- cors:跨域请求处理中间件
|
|
28
|
-
- waf:Web应用防火墙中间件
|
|
29
|
-
- web_base:Web基本功能中间件
|
|
30
|
-
- web_proxy:Web代理服务中间件
|
|
31
|
-
- web_socket:WebSocket通讯中间件
|
|
32
|
-
- web_static:静态文件处理中间件
|
|
33
|
-
|
|
34
|
-
每个中间件均采用外层整体捕获+内层特定操作捕获的策略,确保:
|
|
35
|
-
1. 错误发生时能被正确捕获并记录详细日志
|
|
36
|
-
2. Web请求错误时调用`next()`确保请求继续处理
|
|
37
|
-
3. WebSocket错误时妥善关闭连接
|
|
38
|
-
|
|
39
|
-
## 系统架构可优化点
|
|
40
|
-
|
|
41
|
-
### 1. 全局错误处理机制
|
|
42
|
-
|
|
43
|
-
**当前问题**:
|
|
44
|
-
- 虽然各中间件已添加错误捕获,但系统缺乏统一的全局错误处理机制
|
|
45
|
-
- 错误日志分散在各中间件中,不利于集中管理和分析
|
|
46
|
-
|
|
47
|
-
**优化建议**:
|
|
48
|
-
```javascript
|
|
49
|
-
// 在OS类中添加全局错误处理
|
|
50
|
-
OS.prototype.initErrorHandler = function() {
|
|
51
|
-
// 全局未捕获异常处理
|
|
52
|
-
process.on('uncaughtException', (error) => {
|
|
53
|
-
$.log.error('全局未捕获异常:', error);
|
|
54
|
-
// 可添加告警通知机制
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
// 全局未处理Promise拒绝处理
|
|
58
|
-
process.on('unhandledRejection', (reason, promise) => {
|
|
59
|
-
$.log.error('全局未处理Promise拒绝:', reason);
|
|
60
|
-
// 可添加告警通知机制
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
// 为Web服务添加统一错误处理中间件
|
|
64
|
-
if (this.web && this.web.server) {
|
|
65
|
-
this.web.server.on('error', (error) => {
|
|
66
|
-
$.log.error('Web服务器错误:', error);
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
// 添加全局错误处理中间件(应在所有中间件之前注册)
|
|
70
|
-
this.web.server.use(async (ctx, next) => {
|
|
71
|
-
try {
|
|
72
|
-
await next();
|
|
73
|
-
// 处理404错误
|
|
74
|
-
if (ctx.status === 404 && !ctx.body) {
|
|
75
|
-
ctx.status = 404;
|
|
76
|
-
ctx.body = { code: 404, message: 'Not Found' };
|
|
77
|
-
}
|
|
78
|
-
} catch (error) {
|
|
79
|
-
// 统一错误处理逻辑
|
|
80
|
-
const status = error.status || 500;
|
|
81
|
-
const message = error.message || 'Internal Server Error';
|
|
82
|
-
|
|
83
|
-
// 根据环境决定是否返回详细错误信息
|
|
84
|
-
const errorInfo = process.env.NODE_ENV === 'production'
|
|
85
|
-
? { message }
|
|
86
|
-
: { message, stack: error.stack };
|
|
87
|
-
|
|
88
|
-
ctx.status = status;
|
|
89
|
-
ctx.body = { code: status, ...errorInfo };
|
|
90
|
-
|
|
91
|
-
$.log.error(`请求错误 [${ctx.method} ${ctx.path}]:`, error);
|
|
92
|
-
}
|
|
93
|
-
});
|
|
94
|
-
}
|
|
95
|
-
};
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
### 2. 日志系统优化
|
|
99
|
-
|
|
100
|
-
**当前问题**:
|
|
101
|
-
- 日志功能分散,缺乏统一配置
|
|
102
|
-
- 日志级别控制不灵活
|
|
103
|
-
- 没有日志轮转和归档机制
|
|
104
|
-
|
|
105
|
-
**优化建议**:
|
|
106
|
-
```javascript
|
|
107
|
-
// 创建统一的日志配置和管理模块
|
|
108
|
-
// core/com/log/index.js
|
|
109
|
-
class LogManager {
|
|
110
|
-
constructor() {
|
|
111
|
-
this.config = {
|
|
112
|
-
level: process.env.NODE_ENV === 'production' ? 'info' : 'debug',
|
|
113
|
-
path: './logs',
|
|
114
|
-
maxSize: '100m',
|
|
115
|
-
maxFiles: '7d'
|
|
116
|
-
};
|
|
117
|
-
this.init();
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
init() {
|
|
121
|
-
const fs = require('fs');
|
|
122
|
-
const path = require('path');
|
|
123
|
-
const winston = require('winston');
|
|
124
|
-
const DailyRotateFile = require('winston-daily-rotate-file');
|
|
125
|
-
|
|
126
|
-
// 确保日志目录存在
|
|
127
|
-
const logDir = path.resolve($.runPath, this.config.path);
|
|
128
|
-
if (!fs.existsSync(logDir)) {
|
|
129
|
-
fs.mkdirSync(logDir, { recursive: true });
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
// 创建logger实例
|
|
133
|
-
this.logger = winston.createLogger({
|
|
134
|
-
level: this.config.level,
|
|
135
|
-
format: winston.format.combine(
|
|
136
|
-
winston.format.timestamp({
|
|
137
|
-
format: 'YYYY-MM-DD HH:mm:ss'
|
|
138
|
-
}),
|
|
139
|
-
winston.format.printf(info => `[${info.timestamp}] [${info.level.toUpperCase()}] ${info.message}`)
|
|
140
|
-
),
|
|
141
|
-
transports: [
|
|
142
|
-
new winston.transports.Console(),
|
|
143
|
-
new DailyRotateFile({
|
|
144
|
-
filename: path.join(logDir, 'app-%DATE%.log'),
|
|
145
|
-
datePattern: 'YYYY-MM-DD',
|
|
146
|
-
zippedArchive: true,
|
|
147
|
-
maxSize: this.config.maxSize,
|
|
148
|
-
maxFiles: this.config.maxFiles
|
|
149
|
-
}),
|
|
150
|
-
new DailyRotateFile({
|
|
151
|
-
filename: path.join(logDir, 'error-%DATE%.log'),
|
|
152
|
-
datePattern: 'YYYY-MM-DD',
|
|
153
|
-
zippedArchive: true,
|
|
154
|
-
maxSize: this.config.maxSize,
|
|
155
|
-
maxFiles: this.config.maxFiles,
|
|
156
|
-
level: 'error'
|
|
157
|
-
})
|
|
158
|
-
]
|
|
159
|
-
});
|
|
160
|
-
|
|
161
|
-
// 暴露日志方法到全局
|
|
162
|
-
$.log = {
|
|
163
|
-
debug: (msg, meta) => this.logger.debug(msg, meta),
|
|
164
|
-
info: (msg, meta) => this.logger.info(msg, meta),
|
|
165
|
-
warn: (msg, meta) => this.logger.warn(msg, meta),
|
|
166
|
-
error: (msg, meta) => this.logger.error(msg, meta)
|
|
167
|
-
};
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
if (!$.logManager) {
|
|
172
|
-
$.logManager = new LogManager();
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
module.exports = LogManager;
|
|
176
|
-
```
|
|
177
|
-
|
|
178
|
-
### 3. 配置管理系统优化
|
|
179
|
-
|
|
180
|
-
**当前问题**:
|
|
181
|
-
- 配置文件结构简单,缺乏环境区分能力
|
|
182
|
-
- 配置加载机制不够灵活
|
|
183
|
-
- 没有配置验证和默认值处理
|
|
184
|
-
|
|
185
|
-
**优化建议**:
|
|
186
|
-
```javascript
|
|
187
|
-
// 优化配置管理模块
|
|
188
|
-
// core/com/config/index.js
|
|
189
|
-
class ConfigManager {
|
|
190
|
-
constructor() {
|
|
191
|
-
this.config = {};
|
|
192
|
-
this.env = process.env.NODE_ENV || 'development';
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
load(baseConfig = {}) {
|
|
196
|
-
// 基础配置
|
|
197
|
-
this.config = { ...baseConfig };
|
|
198
|
-
|
|
199
|
-
// 加载默认配置
|
|
200
|
-
const defaultConfig = this.loadConfigFile('./conf.default.json');
|
|
201
|
-
if (defaultConfig) {
|
|
202
|
-
this.config = { ...this.config, ...defaultConfig };
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
// 加载环境特定配置
|
|
206
|
-
const envConfig = this.loadConfigFile(`./conf.${this.env}.json`);
|
|
207
|
-
if (envConfig) {
|
|
208
|
-
this.config = { ...this.config, ...envConfig };
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
// 加载本地配置(通常不纳入版本控制)
|
|
212
|
-
const localConfig = this.loadConfigFile('./conf.local.json');
|
|
213
|
-
if (localConfig) {
|
|
214
|
-
this.config = { ...this.config, ...localConfig };
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
// 验证配置
|
|
218
|
-
this.validateConfig();
|
|
219
|
-
|
|
220
|
-
return this.config;
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
loadConfigFile(filePath) {
|
|
224
|
-
try {
|
|
225
|
-
const fullPath = path.resolve($.runPath, filePath);
|
|
226
|
-
if (fs.existsSync(fullPath)) {
|
|
227
|
-
return require(fullPath);
|
|
228
|
-
}
|
|
229
|
-
} catch (error) {
|
|
230
|
-
console.error(`加载配置文件失败 ${filePath}:`, error);
|
|
231
|
-
}
|
|
232
|
-
return null;
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
validateConfig() {
|
|
236
|
-
// 配置验证逻辑
|
|
237
|
-
const { web, mqtt, mysql, redis } = this.config;
|
|
238
|
-
|
|
239
|
-
// 例如:验证端口号范围
|
|
240
|
-
if (web && typeof web.port === 'number' && (web.port < 1 || web.port > 65535)) {
|
|
241
|
-
throw new Error(`Web端口号${web.port}超出有效范围`);
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
// 更多配置验证...
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
get(key, defaultValue = null) {
|
|
248
|
-
// 支持点号分隔的嵌套属性访问
|
|
249
|
-
const keys = key.split('.');
|
|
250
|
-
let value = this.config;
|
|
251
|
-
|
|
252
|
-
for (const k of keys) {
|
|
253
|
-
if (value === undefined || value === null) {
|
|
254
|
-
return defaultValue;
|
|
255
|
-
}
|
|
256
|
-
value = value[k];
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
return value === undefined ? defaultValue : value;
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
module.exports = ConfigManager;
|
|
264
|
-
```
|
|
265
|
-
|
|
266
|
-
### 4. 中间件加载机制优化
|
|
267
|
-
|
|
268
|
-
**当前问题**:
|
|
269
|
-
- 中间件加载逻辑较为简单,缺乏依赖管理
|
|
270
|
-
- 无法根据条件动态启用/禁用中间件
|
|
271
|
-
- 没有中间件分组和优先级精细控制
|
|
272
|
-
|
|
273
|
-
**优化建议**:
|
|
274
|
-
```javascript
|
|
275
|
-
// 优化中间件管理模块
|
|
276
|
-
// 扩展Middleware类
|
|
277
|
-
Middleware.prototype.loadWithDependencies = async function() {
|
|
278
|
-
// 先加载所有中间件配置
|
|
279
|
-
this.update_config();
|
|
280
|
-
|
|
281
|
-
// 创建依赖图
|
|
282
|
-
const dependencyGraph = new Map();
|
|
283
|
-
const loadedMiddlewares = new Set();
|
|
284
|
-
|
|
285
|
-
// 分析依赖关系
|
|
286
|
-
for (const middleware of this.list) {
|
|
287
|
-
dependencyGraph.set(middleware.name, {
|
|
288
|
-
middleware,
|
|
289
|
-
dependencies: middleware.dependencies || [],
|
|
290
|
-
loaded: false
|
|
291
|
-
});
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
// 按依赖顺序加载中间件
|
|
295
|
-
for (const [name, item] of dependencyGraph.entries()) {
|
|
296
|
-
await this.loadMiddlewareWithDependencies(name, dependencyGraph, loadedMiddlewares);
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
return this.list;
|
|
300
|
-
};
|
|
301
|
-
|
|
302
|
-
Middleware.prototype.loadMiddlewareWithDependencies = async function(name, dependencyGraph, loadedMiddlewares) {
|
|
303
|
-
if (loadedMiddlewares.has(name)) {
|
|
304
|
-
return true;
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
const item = dependencyGraph.get(name);
|
|
308
|
-
if (!item) {
|
|
309
|
-
$.log.error(`依赖的中间件不存在: ${name}`);
|
|
310
|
-
return false;
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
// 先加载依赖
|
|
314
|
-
for (const depName of item.dependencies) {
|
|
315
|
-
if (!await this.loadMiddlewareWithDependencies(depName, dependencyGraph, loadedMiddlewares)) {
|
|
316
|
-
return false;
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
// 检查是否满足条件
|
|
321
|
-
if (item.middleware.condition && typeof item.middleware.condition === 'function') {
|
|
322
|
-
try {
|
|
323
|
-
const shouldLoad = await item.middleware.condition(this.config);
|
|
324
|
-
if (!shouldLoad) {
|
|
325
|
-
$.log.info(`中间件条件不满足,跳过加载: ${name}`);
|
|
326
|
-
return true;
|
|
327
|
-
}
|
|
328
|
-
} catch (error) {
|
|
329
|
-
$.log.error(`中间件条件检查失败: ${name}`, error);
|
|
330
|
-
return false;
|
|
331
|
-
}
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
// 加载中间件
|
|
335
|
-
try {
|
|
336
|
-
if (item.middleware.func_file && item.middleware.func_file.hasFile()) {
|
|
337
|
-
if (item.middleware.reload) {
|
|
338
|
-
item.middleware.func = this.reLoadJS(item.middleware.func_file);
|
|
339
|
-
} else {
|
|
340
|
-
item.middleware.func = require(item.middleware.func_file);
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
// 如果有初始化函数,调用它
|
|
344
|
-
if (item.middleware.func && typeof item.middleware.func.init === 'function') {
|
|
345
|
-
await item.middleware.func.init(this.config);
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
loadedMiddlewares.add(name);
|
|
349
|
-
item.loaded = true;
|
|
350
|
-
$.log.info(`中间件加载成功: ${name}`);
|
|
351
|
-
return true;
|
|
352
|
-
}
|
|
353
|
-
} catch (error) {
|
|
354
|
-
$.log.error(`中间件加载失败: ${name}`, error);
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
return false;
|
|
358
|
-
};
|
|
359
|
-
```
|
|
360
|
-
|
|
361
|
-
### 5. 性能优化
|
|
362
|
-
|
|
363
|
-
**当前问题**:
|
|
364
|
-
- 缺乏缓存策略,频繁访问数据库
|
|
365
|
-
- 没有请求响应时间监控
|
|
366
|
-
- 静态资源处理效率可提升
|
|
367
|
-
|
|
368
|
-
**优化建议**:
|
|
369
|
-
|
|
370
|
-
1. **添加请求性能监控中间件**:
|
|
371
|
-
```javascript
|
|
372
|
-
// middleware/performance/index.js
|
|
373
|
-
module.exports = function(server, config) {
|
|
374
|
-
server.use(async (ctx, next) => {
|
|
375
|
-
const start = Date.now();
|
|
376
|
-
const startTime = process.hrtime();
|
|
377
|
-
|
|
378
|
-
try {
|
|
379
|
-
await next();
|
|
380
|
-
} finally {
|
|
381
|
-
const ms = Date.now() - start;
|
|
382
|
-
const [seconds, nanoseconds] = process.hrtime(startTime);
|
|
383
|
-
const executionTime = seconds * 1000 + nanoseconds / 1000000;
|
|
384
|
-
|
|
385
|
-
// 记录响应时间
|
|
386
|
-
ctx.set('X-Response-Time', `${ms}ms`);
|
|
387
|
-
|
|
388
|
-
// 慢请求报警
|
|
389
|
-
if (ms > (config.slowThreshold || 1000)) {
|
|
390
|
-
$.log.warn(`慢请求: ${ctx.method} ${ctx.path} - ${ms}ms`);
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
// 可添加性能数据收集,用于分析
|
|
394
|
-
if ($.performanceMonitor) {
|
|
395
|
-
$.performanceMonitor.record(ctx.path, ms);
|
|
396
|
-
}
|
|
397
|
-
}
|
|
398
|
-
});
|
|
399
|
-
|
|
400
|
-
return server;
|
|
401
|
-
};
|
|
402
|
-
```
|
|
403
|
-
|
|
404
|
-
2. **优化静态资源处理**:
|
|
405
|
-
```javascript
|
|
406
|
-
// 增强web_static中间件,添加缓存控制和压缩
|
|
407
|
-
const staticCache = require('koa-static-cache');
|
|
408
|
-
const compress = require('koa-compress');
|
|
409
|
-
|
|
410
|
-
module.exports = function(server, config) {
|
|
411
|
-
const cg = Object.assign({
|
|
412
|
-
maxAge: 365 * 24 * 60 * 60, // 默认缓存一年
|
|
413
|
-
gzip: true,
|
|
414
|
-
brotli: true,
|
|
415
|
-
threshold: 1024 // 大于1KB的文件才压缩
|
|
416
|
-
}, config);
|
|
417
|
-
|
|
418
|
-
// 添加压缩中间件
|
|
419
|
-
server.use(compress({
|
|
420
|
-
filter: function(content_type) {
|
|
421
|
-
return /text|json|javascript|css|xml/.test(content_type);
|
|
422
|
-
},
|
|
423
|
-
threshold: cg.threshold,
|
|
424
|
-
gzip: { flush: require('zlib').constants.Z_SYNC_FLUSH },
|
|
425
|
-
brotli: { flush: require('zlib').constants.BROTLI_OPERATION_FLUSH }
|
|
426
|
-
}));
|
|
427
|
-
|
|
428
|
-
// 使用静态缓存代替简单的静态文件服务
|
|
429
|
-
if (cg.static_paths && Array.isArray(cg.static_paths)) {
|
|
430
|
-
cg.static_paths.forEach((pathConfig, index) => {
|
|
431
|
-
const options = Object.assign({}, cg, pathConfig.options);
|
|
432
|
-
server.use(staticCache(pathConfig.path, options));
|
|
433
|
-
});
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
// 保留原有静态文件处理
|
|
437
|
-
if ($.static && $.static.run) {
|
|
438
|
-
server.use(async (ctx, next) => {
|
|
439
|
-
try {
|
|
440
|
-
const handled = await $.static.run(ctx, cg);
|
|
441
|
-
if (!handled) {
|
|
442
|
-
await next();
|
|
443
|
-
}
|
|
444
|
-
} catch (error) {
|
|
445
|
-
$.log.error('静态文件服务错误:', error);
|
|
446
|
-
await next();
|
|
447
|
-
}
|
|
448
|
-
});
|
|
449
|
-
}
|
|
450
|
-
|
|
451
|
-
return server;
|
|
452
|
-
};
|
|
453
|
-
```
|
|
454
|
-
|
|
455
|
-
### 6. 安全性增强
|
|
456
|
-
|
|
457
|
-
**当前问题**:
|
|
458
|
-
- 缺乏完整的安全防护体系
|
|
459
|
-
- 没有请求数据验证机制
|
|
460
|
-
- 敏感信息可能未妥善处理
|
|
461
|
-
|
|
462
|
-
**优化建议**:
|
|
463
|
-
|
|
464
|
-
1. **添加请求数据验证中间件**:
|
|
465
|
-
```javascript
|
|
466
|
-
// middleware/validator/index.js
|
|
467
|
-
const Joi = require('@hapi/joi');
|
|
468
|
-
|
|
469
|
-
// 全局验证规则存储
|
|
470
|
-
const validationRules = new Map();
|
|
471
|
-
|
|
472
|
-
// 注册验证规则
|
|
473
|
-
function registerValidation(path, method, schema) {
|
|
474
|
-
const key = `${method.toUpperCase()}:${path}`;
|
|
475
|
-
validationRules.set(key, schema);
|
|
476
|
-
}
|
|
477
|
-
|
|
478
|
-
module.exports = function(server, config) {
|
|
479
|
-
server.use(async (ctx, next) => {
|
|
480
|
-
const key = `${ctx.method}:${ctx.path}`;
|
|
481
|
-
const schema = validationRules.get(key);
|
|
482
|
-
|
|
483
|
-
if (schema) {
|
|
484
|
-
try {
|
|
485
|
-
// 根据请求类型获取数据
|
|
486
|
-
let data;
|
|
487
|
-
if (ctx.method === 'GET') {
|
|
488
|
-
data = ctx.query;
|
|
489
|
-
} else {
|
|
490
|
-
data = ctx.request.body;
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
// 验证数据
|
|
494
|
-
const validatedData = await Joi.validate(data, schema, {
|
|
495
|
-
abortEarly: false,
|
|
496
|
-
allowUnknown: false
|
|
497
|
-
});
|
|
498
|
-
|
|
499
|
-
// 替换为验证后的数据
|
|
500
|
-
if (ctx.method === 'GET') {
|
|
501
|
-
ctx.query = validatedData;
|
|
502
|
-
} else {
|
|
503
|
-
ctx.request.body = validatedData;
|
|
504
|
-
}
|
|
505
|
-
|
|
506
|
-
} catch (error) {
|
|
507
|
-
ctx.status = 400;
|
|
508
|
-
ctx.body = {
|
|
509
|
-
code: 400,
|
|
510
|
-
message: '请求数据验证失败',
|
|
511
|
-
errors: error.details.map(detail => detail.message)
|
|
512
|
-
};
|
|
513
|
-
|
|
514
|
-
$.log.warn(`请求数据验证失败 [${key}]:`, error.details);
|
|
515
|
-
return;
|
|
516
|
-
}
|
|
517
|
-
}
|
|
518
|
-
|
|
519
|
-
await next();
|
|
520
|
-
});
|
|
521
|
-
|
|
522
|
-
// 暴露注册方法到全局
|
|
523
|
-
$.validator = {
|
|
524
|
-
register: registerValidation
|
|
525
|
-
};
|
|
526
|
-
|
|
527
|
-
return server;
|
|
528
|
-
};
|
|
529
|
-
```
|
|
530
|
-
|
|
531
|
-
2. **添加安全头部中间件**:
|
|
532
|
-
```javascript
|
|
533
|
-
// middleware/security_headers/index.js
|
|
534
|
-
module.exports = function(server, config) {
|
|
535
|
-
server.use(async (ctx, next) => {
|
|
536
|
-
// 设置HSTS头,强制使用HTTPS
|
|
537
|
-
ctx.set('Strict-Transport-Security', 'max-age=31536000; includeSubDomains');
|
|
538
|
-
|
|
539
|
-
// 防止XSS攻击
|
|
540
|
-
ctx.set('X-XSS-Protection', '1; mode=block');
|
|
541
|
-
|
|
542
|
-
// 防止MIME类型嗅探
|
|
543
|
-
ctx.set('X-Content-Type-Options', 'nosniff');
|
|
544
|
-
|
|
545
|
-
// 禁止iframe嵌入
|
|
546
|
-
ctx.set('X-Frame-Options', 'DENY');
|
|
547
|
-
|
|
548
|
-
// 设置内容安全策略
|
|
549
|
-
ctx.set('Content-Security-Policy', "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data:;");
|
|
550
|
-
|
|
551
|
-
// 引用策略
|
|
552
|
-
ctx.set('Referrer-Policy', 'no-referrer-when-downgrade');
|
|
553
|
-
|
|
554
|
-
// 特性策略
|
|
555
|
-
ctx.set('Feature-Policy', 'geolocation none; microphone none; camera none');
|
|
556
|
-
|
|
557
|
-
await next();
|
|
558
|
-
});
|
|
559
|
-
|
|
560
|
-
return server;
|
|
561
|
-
};
|
|
562
|
-
```
|
|
563
|
-
|
|
564
|
-
### 7. 代码规范和结构优化
|
|
565
|
-
|
|
566
|
-
**当前问题**:
|
|
567
|
-
- 代码风格不够统一
|
|
568
|
-
- 部分文件结构需要调整
|
|
569
|
-
- 缺乏完善的文档和注释
|
|
570
|
-
|
|
571
|
-
**优化建议**:
|
|
572
|
-
|
|
573
|
-
1. **引入代码规范工具**:
|
|
574
|
-
- 配置ESLint和Prettier统一代码风格
|
|
575
|
-
- 添加.editorconfig文件
|
|
576
|
-
- 配置Git钩子,在提交前检查代码规范
|
|
577
|
-
|
|
578
|
-
2. **完善项目结构**:
|
|
579
|
-
- 清晰区分核心模块和业务模块
|
|
580
|
-
- 优化目录结构,便于维护
|
|
581
|
-
- 为API、配置和中间件提供模板
|
|
582
|
-
|
|
583
|
-
3. **增强文档和注释**:
|
|
584
|
-
- 为核心模块和API添加JSDoc注释
|
|
585
|
-
- 创建API文档生成工具
|
|
586
|
-
- 完善README.md,添加更详细的使用说明
|
|
587
|
-
|
|
588
|
-
## 总结
|
|
589
|
-
|
|
590
|
-
mm_os系统采用灵活的中间件架构,已通过添加异步错误捕获机制大幅提升了系统的健壮性。通过实施上述优化建议,可以进一步提升系统的性能、安全性、可维护性和可扩展性,使其更适合用于构建高可用、高性能的服务端应用。
|
|
591
|
-
|
|
592
|
-
建议按照优化点的优先级逐步实施:
|
|
593
|
-
1. 全局错误处理机制(最高优先级)
|
|
594
|
-
2. 日志系统优化
|
|
595
|
-
3. 安全性增强
|
|
596
|
-
4. 性能优化
|
|
597
|
-
5. 中间件加载机制优化
|
|
598
|
-
6. 配置管理系统优化
|
|
599
|
-
7. 代码规范和结构优化
|