@robiki/proxy 1.0.0 → 1.0.2
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.de.md +639 -0
- package/README.es.md +639 -0
- package/README.ja.md +639 -0
- package/README.md +55 -4
- package/README.pl.md +639 -0
- package/README.ru.md +639 -0
- package/README.zh.md +639 -0
- package/dist/config-CQ7zIaQt.d.ts +172 -0
- package/dist/config-CeJ1tf8T.d.ts +174 -0
- package/dist/index.d.ts +5 -5
- package/dist/index.js +79 -38
- package/dist/utils/config.d.ts +1 -1
- package/dist/utils/config.js +5 -16
- package/package.json +7 -3
- package/tests/README.md +293 -0
- package/tests/docker/README.md +303 -0
package/README.zh.md
ADDED
|
@@ -0,0 +1,639 @@
|
|
|
1
|
+
# 🚀 Robiki 代理
|
|
2
|
+
|
|
3
|
+
> 一个高性能、灵活的 HTTP/2 反向代理,支持 WebSocket、可配置路由、CORS 和请求验证。可作为 npm 包在 Node.js 应用程序中使用,也可作为独立的 Docker 容器使用。仅用作本地开发环境的域名代理。
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@robiki/proxy)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
|
|
8
|
+
## 🌍 语言 / Languages / Sprachen / 言語 / Języki / Idiomas / Языки
|
|
9
|
+
|
|
10
|
+
[English](README.md) | [Deutsch](README.de.md) | [中文](README.zh.md) | [日本語](README.ja.md) | [Polski](README.pl.md) | [Español](README.es.md) | [Русский](README.ru.md)
|
|
11
|
+
|
|
12
|
+
## ✨ 特性
|
|
13
|
+
|
|
14
|
+
- **🔒 HTTP/2 和 SSL/TLS 支持**:完整的 HTTP/2 协议支持,自动回退到 HTTP/1.1
|
|
15
|
+
- **🔌 WebSocket 代理**:无缝的 WebSocket 连接处理和代理
|
|
16
|
+
- **🌐 灵活路由**:按域名/主机配置路由,支持通配符
|
|
17
|
+
- **🛡️ CORS 管理**:全局和每个路由的 CORS 配置
|
|
18
|
+
- **✅ 请求验证**:用于身份验证、速率限制等的自定义验证逻辑
|
|
19
|
+
- **🔄 URL 重映射**:在转发到目标服务之前转换 URL
|
|
20
|
+
- **📦 双重用途**:可作为 npm 包或 Docker 容器使用
|
|
21
|
+
- **🎯 多端口支持**:同时监听多个端口
|
|
22
|
+
- **⚡ 高性能**:基于 Node.js 原生 HTTP/2 实现
|
|
23
|
+
|
|
24
|
+
## 📦 安装
|
|
25
|
+
|
|
26
|
+
### 作为 npm 包
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npm install @robiki/proxy
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
yarn add @robiki/proxy
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### 作为 Docker 容器
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
docker pull robiki/proxy:latest
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### 作为 Docker Compose 服务
|
|
43
|
+
|
|
44
|
+
```yaml
|
|
45
|
+
services:
|
|
46
|
+
proxy:
|
|
47
|
+
image: robiki/proxy:latest
|
|
48
|
+
container_name: robiki-proxy
|
|
49
|
+
restart: unless-stopped
|
|
50
|
+
ports:
|
|
51
|
+
- '443:443'
|
|
52
|
+
- '8080:8080'
|
|
53
|
+
- '9229:9229'
|
|
54
|
+
volumes:
|
|
55
|
+
- ./proxy.config.json:/app/proxy.config.json:ro
|
|
56
|
+
- ./certs:/app/certs:ro
|
|
57
|
+
networks:
|
|
58
|
+
- app-network
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## 注意事项
|
|
62
|
+
|
|
63
|
+
- 本地配置的主机应添加到本地 `hosts` 文件中。
|
|
64
|
+
- 如果您使用自定义证书,需要将证书文件添加到 `certs` 目录。
|
|
65
|
+
|
|
66
|
+
## 🚀 快速开始
|
|
67
|
+
|
|
68
|
+
### 作为 npm 包使用
|
|
69
|
+
|
|
70
|
+
```javascript
|
|
71
|
+
import { createProxy } from '@robiki/proxy';
|
|
72
|
+
|
|
73
|
+
const proxy = await createProxy({
|
|
74
|
+
ports: [443, 8080],
|
|
75
|
+
ssl: {
|
|
76
|
+
key: './certs/key.pem',
|
|
77
|
+
cert: './certs/cert.pem',
|
|
78
|
+
allowHTTP1: true,
|
|
79
|
+
},
|
|
80
|
+
routes: {
|
|
81
|
+
'api.example.com': {
|
|
82
|
+
target: 'localhost:3000',
|
|
83
|
+
ssl: true,
|
|
84
|
+
},
|
|
85
|
+
'example.com': {
|
|
86
|
+
target: 'localhost:8080',
|
|
87
|
+
ssl: false,
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
console.log('代理服务器正在运行!');
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### 使用 Docker
|
|
96
|
+
|
|
97
|
+
1. 创建 `proxy.config.json` 文件:
|
|
98
|
+
|
|
99
|
+
```json
|
|
100
|
+
{
|
|
101
|
+
"ports": [443, 8080],
|
|
102
|
+
"ssl": {
|
|
103
|
+
"key": "/app/certs/key.pem",
|
|
104
|
+
"cert": "/app/certs/cert.pem",
|
|
105
|
+
"allowHTTP1": true
|
|
106
|
+
},
|
|
107
|
+
"routes": {
|
|
108
|
+
"api.example.com": {
|
|
109
|
+
"target": "backend-service:3000",
|
|
110
|
+
"ssl": true
|
|
111
|
+
},
|
|
112
|
+
"example.com": {
|
|
113
|
+
"target": "frontend-service:8080",
|
|
114
|
+
"ssl": false
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
2. 创建 `docker-compose.yml`:
|
|
121
|
+
|
|
122
|
+
```yaml
|
|
123
|
+
version: '3.8'
|
|
124
|
+
|
|
125
|
+
services:
|
|
126
|
+
proxy:
|
|
127
|
+
image: robiki/proxy:latest
|
|
128
|
+
ports:
|
|
129
|
+
- '443:443'
|
|
130
|
+
- '8080:8080'
|
|
131
|
+
volumes:
|
|
132
|
+
- ./proxy.config.json:/app/proxy.config.json:ro
|
|
133
|
+
- ./certs:/app/certs:ro
|
|
134
|
+
environment:
|
|
135
|
+
- PROXY_CONFIG=/app/proxy.config.json
|
|
136
|
+
networks:
|
|
137
|
+
- app-network
|
|
138
|
+
|
|
139
|
+
backend-service:
|
|
140
|
+
image: your-backend-image
|
|
141
|
+
networks:
|
|
142
|
+
- app-network
|
|
143
|
+
|
|
144
|
+
frontend-service:
|
|
145
|
+
image: your-frontend-image
|
|
146
|
+
networks:
|
|
147
|
+
- app-network
|
|
148
|
+
|
|
149
|
+
networks:
|
|
150
|
+
app-network:
|
|
151
|
+
driver: bridge
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
3. 启动服务:
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
docker-compose up -d
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
## 📖 配置
|
|
161
|
+
|
|
162
|
+
### 配置文件
|
|
163
|
+
|
|
164
|
+
创建具有以下结构的 `proxy.config.json` 文件:
|
|
165
|
+
|
|
166
|
+
```json
|
|
167
|
+
{
|
|
168
|
+
"ports": [443, 8080],
|
|
169
|
+
"ssl": {
|
|
170
|
+
"key": "./certs/key.pem",
|
|
171
|
+
"cert": "./certs/cert.pem",
|
|
172
|
+
"ca": "./certs/ca.pem",
|
|
173
|
+
"allowHTTP1": true
|
|
174
|
+
},
|
|
175
|
+
"cors": {
|
|
176
|
+
"origin": "*",
|
|
177
|
+
"methods": ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
|
|
178
|
+
"allowedHeaders": ["Content-Type", "Authorization"],
|
|
179
|
+
"credentials": true,
|
|
180
|
+
"maxAge": 86400
|
|
181
|
+
},
|
|
182
|
+
"routes": {
|
|
183
|
+
"api.example.com": {
|
|
184
|
+
"target": "backend-service:3000",
|
|
185
|
+
"ssl": true,
|
|
186
|
+
"cors": {
|
|
187
|
+
"origin": ["https://example.com"],
|
|
188
|
+
"credentials": true
|
|
189
|
+
}
|
|
190
|
+
},
|
|
191
|
+
"*.example.com": {
|
|
192
|
+
"target": "wildcard-service:4000",
|
|
193
|
+
"ssl": true
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### 环境变量
|
|
200
|
+
|
|
201
|
+
您还可以使用环境变量配置代理:
|
|
202
|
+
|
|
203
|
+
```bash
|
|
204
|
+
# SSL 配置
|
|
205
|
+
SSL_KEY=/app/certs/key.pem
|
|
206
|
+
SSL_CERT=/app/certs/cert.pem
|
|
207
|
+
SSL_CA=/app/certs/ca.pem
|
|
208
|
+
SSL_ALLOW_HTTP1=true
|
|
209
|
+
|
|
210
|
+
# CORS 配置
|
|
211
|
+
CORS_ORIGIN=*
|
|
212
|
+
CORS_METHODS=GET,POST,PUT,DELETE,OPTIONS
|
|
213
|
+
CORS_HEADERS=Content-Type,Authorization
|
|
214
|
+
CORS_CREDENTIALS=true
|
|
215
|
+
|
|
216
|
+
# 调试模式
|
|
217
|
+
DEBUG=true # 启用代理连接和错误的详细日志记录
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
## 🎯 高级用法
|
|
221
|
+
|
|
222
|
+
### URL 重映射
|
|
223
|
+
|
|
224
|
+
在转发到目标服务之前转换 URL:
|
|
225
|
+
|
|
226
|
+
```javascript
|
|
227
|
+
const config = {
|
|
228
|
+
routes: {
|
|
229
|
+
'api.example.com': {
|
|
230
|
+
target: 'backend:3000',
|
|
231
|
+
ssl: true,
|
|
232
|
+
remap: (url) => {
|
|
233
|
+
// 删除 /api 前缀
|
|
234
|
+
return url.replace(/^\/api/, '');
|
|
235
|
+
},
|
|
236
|
+
},
|
|
237
|
+
},
|
|
238
|
+
};
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
### 请求验证
|
|
242
|
+
|
|
243
|
+
为身份验证、速率限制等添加自定义验证逻辑:
|
|
244
|
+
|
|
245
|
+
```javascript
|
|
246
|
+
const config = {
|
|
247
|
+
// 全局验证
|
|
248
|
+
validate: async (info) => {
|
|
249
|
+
if (!info.headers.authorization) {
|
|
250
|
+
return {
|
|
251
|
+
status: false,
|
|
252
|
+
code: 401,
|
|
253
|
+
message: '未授权',
|
|
254
|
+
headers: { 'www-authenticate': 'Bearer' },
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
return { status: true };
|
|
258
|
+
},
|
|
259
|
+
routes: {
|
|
260
|
+
'api.example.com': {
|
|
261
|
+
target: 'backend:3000',
|
|
262
|
+
ssl: true,
|
|
263
|
+
// 路由特定验证
|
|
264
|
+
validate: async (info) => {
|
|
265
|
+
const rateLimit = await checkRateLimit(info.remoteAddress);
|
|
266
|
+
if (!rateLimit.allowed) {
|
|
267
|
+
return {
|
|
268
|
+
status: false,
|
|
269
|
+
code: 429,
|
|
270
|
+
message: '请求过多',
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
return { status: true };
|
|
274
|
+
},
|
|
275
|
+
},
|
|
276
|
+
},
|
|
277
|
+
};
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
### 自定义 CORS 配置
|
|
281
|
+
|
|
282
|
+
全局或按路由配置 CORS:
|
|
283
|
+
|
|
284
|
+
```javascript
|
|
285
|
+
const config = {
|
|
286
|
+
// 全局 CORS
|
|
287
|
+
cors: {
|
|
288
|
+
origin: ['https://example.com', 'https://www.example.com'],
|
|
289
|
+
methods: ['GET', 'POST', 'PUT', 'DELETE'],
|
|
290
|
+
allowedHeaders: ['Content-Type', 'Authorization'],
|
|
291
|
+
credentials: true,
|
|
292
|
+
maxAge: 86400,
|
|
293
|
+
},
|
|
294
|
+
routes: {
|
|
295
|
+
'api.example.com': {
|
|
296
|
+
target: 'backend:3000',
|
|
297
|
+
ssl: true,
|
|
298
|
+
// 路由特定 CORS(覆盖全局)
|
|
299
|
+
cors: {
|
|
300
|
+
origin: '*',
|
|
301
|
+
credentials: false,
|
|
302
|
+
},
|
|
303
|
+
},
|
|
304
|
+
},
|
|
305
|
+
};
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
### 自定义处理程序
|
|
309
|
+
|
|
310
|
+
为高级用例创建自定义请求处理程序:
|
|
311
|
+
|
|
312
|
+
```javascript
|
|
313
|
+
import { createCustomProxy } from '@robiki/proxy';
|
|
314
|
+
|
|
315
|
+
const customRestHandler = async (req, res) => {
|
|
316
|
+
if (req.url === '/health') {
|
|
317
|
+
res.writeHead(200, { 'content-type': 'application/json' });
|
|
318
|
+
return res.end(JSON.stringify({ status: 'ok' }));
|
|
319
|
+
}
|
|
320
|
+
// 回退到默认代理行为
|
|
321
|
+
const { restAPIProxyHandler } = await import('@robiki/proxy/connections');
|
|
322
|
+
return restAPIProxyHandler(req, res);
|
|
323
|
+
};
|
|
324
|
+
|
|
325
|
+
const proxy = await createCustomProxy(config, {
|
|
326
|
+
rest: customRestHandler,
|
|
327
|
+
websocket: customWebSocketHandler,
|
|
328
|
+
stream: customStreamHandler,
|
|
329
|
+
});
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
## 🔧 API 参考
|
|
333
|
+
|
|
334
|
+
### `createProxy(config: ServerConfig): Promise<ProxyServer>`
|
|
335
|
+
|
|
336
|
+
使用给定配置创建并启动代理服务器。
|
|
337
|
+
|
|
338
|
+
**参数:**
|
|
339
|
+
|
|
340
|
+
- `config`:服务器配置对象
|
|
341
|
+
|
|
342
|
+
**返回:** 解析为 `ProxyServer` 实例的 Promise
|
|
343
|
+
|
|
344
|
+
### `ProxyServer`
|
|
345
|
+
|
|
346
|
+
**方法:**
|
|
347
|
+
|
|
348
|
+
- `start()`:启动代理服务器
|
|
349
|
+
- `stop()`:停止代理服务器
|
|
350
|
+
- `getConfig()`:获取当前配置
|
|
351
|
+
|
|
352
|
+
### 配置类型
|
|
353
|
+
|
|
354
|
+
#### `ServerConfig`
|
|
355
|
+
|
|
356
|
+
```typescript
|
|
357
|
+
interface ServerConfig {
|
|
358
|
+
ports?: number[];
|
|
359
|
+
ssl?: CertificateConfig;
|
|
360
|
+
routes: Record<string, RouteConfig>;
|
|
361
|
+
cors?: CorsConfig;
|
|
362
|
+
validate?: (info: ConnectionInfo) => Promise<ForwardValidationResult>;
|
|
363
|
+
}
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
#### `RouteConfig`
|
|
367
|
+
|
|
368
|
+
```typescript
|
|
369
|
+
interface RouteConfig {
|
|
370
|
+
target: string;
|
|
371
|
+
ssl?: boolean;
|
|
372
|
+
remap?: (url: string) => string;
|
|
373
|
+
cors?: CorsConfig;
|
|
374
|
+
validate?: (info: ConnectionInfo) => Promise<ForwardValidationResult>;
|
|
375
|
+
}
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
#### `CorsConfig`
|
|
379
|
+
|
|
380
|
+
```typescript
|
|
381
|
+
interface CorsConfig {
|
|
382
|
+
origin?: string | string[];
|
|
383
|
+
methods?: string[];
|
|
384
|
+
allowedHeaders?: string[];
|
|
385
|
+
exposedHeaders?: string[];
|
|
386
|
+
credentials?: boolean;
|
|
387
|
+
maxAge?: number;
|
|
388
|
+
}
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
#### `ConnectionInfo`
|
|
392
|
+
|
|
393
|
+
```typescript
|
|
394
|
+
interface ConnectionInfo {
|
|
395
|
+
id: number;
|
|
396
|
+
method: string;
|
|
397
|
+
path: string;
|
|
398
|
+
remoteAddress: string;
|
|
399
|
+
scheme: string;
|
|
400
|
+
authority: string;
|
|
401
|
+
origin: string;
|
|
402
|
+
headers: IncomingHttpHeaders;
|
|
403
|
+
query: URLSearchParams;
|
|
404
|
+
type: RequestType;
|
|
405
|
+
}
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
## 🐳 Docker 使用
|
|
409
|
+
|
|
410
|
+
### 在另一个项目中使用
|
|
411
|
+
|
|
412
|
+
1. 将代理添加到您的 `docker-compose.yml`:
|
|
413
|
+
|
|
414
|
+
```yaml
|
|
415
|
+
services:
|
|
416
|
+
proxy:
|
|
417
|
+
image: robiki/proxy:latest
|
|
418
|
+
ports:
|
|
419
|
+
- '443:443'
|
|
420
|
+
- '8080:8080'
|
|
421
|
+
volumes:
|
|
422
|
+
- ./proxy.config.json:/app/proxy.config.json:ro
|
|
423
|
+
- ./certs:/app/certs:ro
|
|
424
|
+
networks:
|
|
425
|
+
- your-network
|
|
426
|
+
|
|
427
|
+
your-service:
|
|
428
|
+
image: your-service-image
|
|
429
|
+
networks:
|
|
430
|
+
- your-network
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
2. 在 `proxy.config.json` 中配置路由以指向您的服务
|
|
434
|
+
|
|
435
|
+
3. 启动您的堆栈:
|
|
436
|
+
|
|
437
|
+
```bash
|
|
438
|
+
docker-compose up -d
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
### 构建自定义镜像
|
|
442
|
+
|
|
443
|
+
创建自定义 Dockerfile:
|
|
444
|
+
|
|
445
|
+
```dockerfile
|
|
446
|
+
FROM robiki/proxy:latest
|
|
447
|
+
|
|
448
|
+
# 复制您的配置
|
|
449
|
+
COPY proxy.config.json /app/proxy.config.json
|
|
450
|
+
COPY certs /app/certs
|
|
451
|
+
|
|
452
|
+
# 设置环境变量
|
|
453
|
+
ENV PROXY_CONFIG=/app/proxy.config.json
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
## 📚 示例
|
|
457
|
+
|
|
458
|
+
查看 `examples/` 目录以获取更多使用示例:
|
|
459
|
+
|
|
460
|
+
- `basic-usage.js` - 简单的代理设置
|
|
461
|
+
- `advanced-usage.js` - 高级功能(验证、CORS、重映射)
|
|
462
|
+
- `custom-handlers.js` - 自定义请求处理程序
|
|
463
|
+
- `docker-compose.example.yml` - 完整的 Docker 设置
|
|
464
|
+
|
|
465
|
+
## 🔐 SSL/TLS 证书
|
|
466
|
+
|
|
467
|
+
### 生成自签名证书
|
|
468
|
+
|
|
469
|
+
用于开发:
|
|
470
|
+
|
|
471
|
+
```bash
|
|
472
|
+
mkdir -p certs
|
|
473
|
+
openssl req -x509 -newkey rsa:4096 -keyout certs/key.pem -out certs/cert.pem -days 365 -nodes
|
|
474
|
+
```
|
|
475
|
+
|
|
476
|
+
### 使用 Let's Encrypt
|
|
477
|
+
|
|
478
|
+
用于生产,使用 Let's Encrypt 证书:
|
|
479
|
+
|
|
480
|
+
```bash
|
|
481
|
+
certbot certonly --standalone -d example.com
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
然后在您的配置中引用它们:
|
|
485
|
+
|
|
486
|
+
```json
|
|
487
|
+
{
|
|
488
|
+
"ssl": {
|
|
489
|
+
"key": "/etc/letsencrypt/live/example.com/privkey.pem",
|
|
490
|
+
"cert": "/etc/letsencrypt/live/example.com/fullchain.pem"
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
## 🤝 贡献
|
|
496
|
+
|
|
497
|
+
欢迎贡献!请随时提交 Pull Request。
|
|
498
|
+
|
|
499
|
+
## 📄 许可证
|
|
500
|
+
|
|
501
|
+
MIT © Robiki sp. z o.o.
|
|
502
|
+
|
|
503
|
+
## 🔗 链接
|
|
504
|
+
|
|
505
|
+
- [GitHub 仓库](https://github.com/robiki-ai/robiki-proxy)
|
|
506
|
+
- [npm 包](https://www.npmjs.com/package/@robiki/proxy)
|
|
507
|
+
- [问题跟踪器](https://github.com/robiki-ai/robiki-proxy/issues)
|
|
508
|
+
|
|
509
|
+
## 💡 用例
|
|
510
|
+
|
|
511
|
+
- **微服务架构**:根据域名/路径将请求路由到不同的服务
|
|
512
|
+
- **开发环境**:用于测试多个服务的本地代理
|
|
513
|
+
- **API 网关**:具有身份验证和速率限制的集中入口点
|
|
514
|
+
- **SSL 终止**:在代理级别处理 SSL/TLS
|
|
515
|
+
- **CORS 管理**:集中式 CORS 配置
|
|
516
|
+
- **负载均衡**:在多个实例之间分配流量(使用自定义处理程序)
|
|
517
|
+
|
|
518
|
+
## 🛠️ 故障排除
|
|
519
|
+
|
|
520
|
+
### 调试模式
|
|
521
|
+
|
|
522
|
+
启用详细日志记录以排除连接问题:
|
|
523
|
+
|
|
524
|
+
```bash
|
|
525
|
+
# 启用调试模式
|
|
526
|
+
DEBUG=true node your-proxy-script.js
|
|
527
|
+
|
|
528
|
+
# 或使用 Docker
|
|
529
|
+
docker run -e DEBUG=true robiki/proxy:latest
|
|
530
|
+
|
|
531
|
+
# 或在 docker-compose.yml 中
|
|
532
|
+
services:
|
|
533
|
+
proxy:
|
|
534
|
+
image: robiki/proxy:latest
|
|
535
|
+
environment:
|
|
536
|
+
- DEBUG=true
|
|
537
|
+
```
|
|
538
|
+
|
|
539
|
+
当 `DEBUG=true` 时,代理将记录:
|
|
540
|
+
- 所有代理连接尝试(REST、WebSocket、HTTP/2 流)
|
|
541
|
+
- 请求和响应详细信息
|
|
542
|
+
- 连接错误和超时
|
|
543
|
+
- 代理错误和客户端错误
|
|
544
|
+
|
|
545
|
+
### 端口已被占用
|
|
546
|
+
|
|
547
|
+
代理将自动尝试终止配置端口上的进程。如果失败,请手动释放端口:
|
|
548
|
+
|
|
549
|
+
```bash
|
|
550
|
+
lsof -ti:443 | xargs kill -9
|
|
551
|
+
lsof -ti:8080 | xargs kill -9
|
|
552
|
+
```
|
|
553
|
+
|
|
554
|
+
### SSL 证书错误
|
|
555
|
+
|
|
556
|
+
确保您的证书文件可读并且格式正确(PEM)。对于开发,使用自签名证书。
|
|
557
|
+
|
|
558
|
+
### WebSocket 连接问题
|
|
559
|
+
|
|
560
|
+
确保您的 WebSocket 路由配置了正确的协议(ws/wss),并且目标服务支持 WebSocket 连接。
|
|
561
|
+
|
|
562
|
+
## 🧪 测试
|
|
563
|
+
|
|
564
|
+
Robiki Proxy 包含一个全面的测试套件,涵盖单元测试、集成测试和高级场景。
|
|
565
|
+
|
|
566
|
+
### 运行测试
|
|
567
|
+
|
|
568
|
+
```bash
|
|
569
|
+
# 运行所有测试
|
|
570
|
+
yarn test
|
|
571
|
+
|
|
572
|
+
# 在监视模式下运行测试
|
|
573
|
+
yarn test:watch
|
|
574
|
+
|
|
575
|
+
# 运行带覆盖率的测试
|
|
576
|
+
yarn test:coverage
|
|
577
|
+
|
|
578
|
+
# 使用 UI 运行测试
|
|
579
|
+
yarn test:ui
|
|
580
|
+
```
|
|
581
|
+
|
|
582
|
+
### 测试覆盖率
|
|
583
|
+
|
|
584
|
+
测试套件包括:
|
|
585
|
+
|
|
586
|
+
- **单元测试**:配置、实用程序、标头转换、CORS 处理
|
|
587
|
+
- **集成测试**:HTTP 代理、路由解析、验证、配置加载
|
|
588
|
+
- **高级测试**:WebSocket 代理、HTTP/2 流、并发连接
|
|
589
|
+
- **Docker 测试**:容器构建、配置加载、运行时行为
|
|
590
|
+
|
|
591
|
+
### Docker 测试
|
|
592
|
+
|
|
593
|
+
运行 Docker 集成测试:
|
|
594
|
+
|
|
595
|
+
```bash
|
|
596
|
+
# 完整的 Docker 集成测试
|
|
597
|
+
yarn test:docker
|
|
598
|
+
|
|
599
|
+
# 专门测试配置加载
|
|
600
|
+
yarn test:docker:config
|
|
601
|
+
|
|
602
|
+
# 运行所有测试(单元 + 集成 + Docker)
|
|
603
|
+
yarn test:all
|
|
604
|
+
```
|
|
605
|
+
|
|
606
|
+
或使用 Make:
|
|
607
|
+
|
|
608
|
+
```bash
|
|
609
|
+
# 快速 Docker 构建测试
|
|
610
|
+
make test-docker
|
|
611
|
+
|
|
612
|
+
# 完整的集成测试套件
|
|
613
|
+
make test-docker-full
|
|
614
|
+
|
|
615
|
+
# 配置加载测试
|
|
616
|
+
make test-docker-config
|
|
617
|
+
|
|
618
|
+
# Docker Compose 测试
|
|
619
|
+
make test-docker-compose
|
|
620
|
+
```
|
|
621
|
+
|
|
622
|
+
有关更多详细信息,请参阅 [Docker 测试 README](tests/docker/README.md)。
|
|
623
|
+
|
|
624
|
+
## 📊 性能
|
|
625
|
+
|
|
626
|
+
该代理基于 Node.js 原生 HTTP/2 实现,专为高性能而设计:
|
|
627
|
+
|
|
628
|
+
- 高效的流处理
|
|
629
|
+
- 最小的开销
|
|
630
|
+
- 连接池
|
|
631
|
+
- 自动 HTTP/1.1 回退
|
|
632
|
+
|
|
633
|
+
对于生产部署,请考虑:
|
|
634
|
+
|
|
635
|
+
- 使用进程管理器(PM2、systemd)
|
|
636
|
+
- 为多核系统启用集群
|
|
637
|
+
- 使用健康检查进行监控
|
|
638
|
+
- 设置适当的日志记录
|
|
639
|
+
|