code-abyss 1.6.16 → 1.7.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.
Files changed (97) hide show
  1. package/README.md +8 -6
  2. package/bin/install.js +59 -163
  3. package/bin/lib/ccline.js +82 -0
  4. package/bin/lib/utils.js +61 -0
  5. package/package.json +5 -2
  6. package/skills/SKILL.md +24 -16
  7. package/skills/domains/ai/SKILL.md +2 -2
  8. package/skills/domains/ai/prompt-and-eval.md +279 -0
  9. package/skills/domains/architecture/SKILL.md +2 -3
  10. package/skills/domains/architecture/security-arch.md +87 -0
  11. package/skills/domains/data-engineering/SKILL.md +188 -26
  12. package/skills/domains/development/SKILL.md +1 -4
  13. package/skills/domains/devops/SKILL.md +3 -5
  14. package/skills/domains/devops/performance.md +63 -0
  15. package/skills/domains/devops/testing.md +97 -0
  16. package/skills/domains/frontend-design/SKILL.md +12 -3
  17. package/skills/domains/frontend-design/claymorphism/SKILL.md +117 -0
  18. package/skills/domains/frontend-design/claymorphism/references/tokens.css +52 -0
  19. package/skills/domains/frontend-design/engineering.md +287 -0
  20. package/skills/domains/frontend-design/glassmorphism/SKILL.md +138 -0
  21. package/skills/domains/frontend-design/glassmorphism/references/tokens.css +32 -0
  22. package/skills/domains/frontend-design/liquid-glass/SKILL.md +135 -0
  23. package/skills/domains/frontend-design/liquid-glass/references/tokens.css +81 -0
  24. package/skills/domains/frontend-design/neubrutalism/SKILL.md +141 -0
  25. package/skills/domains/frontend-design/neubrutalism/references/tokens.css +44 -0
  26. package/skills/domains/infrastructure/SKILL.md +174 -34
  27. package/skills/domains/mobile/SKILL.md +211 -21
  28. package/skills/domains/orchestration/SKILL.md +1 -0
  29. package/skills/domains/security/SKILL.md +4 -6
  30. package/skills/domains/security/blue-team.md +57 -0
  31. package/skills/domains/security/red-team.md +54 -0
  32. package/skills/domains/security/threat-intel.md +50 -0
  33. package/skills/orchestration/multi-agent/SKILL.md +195 -46
  34. package/skills/run_skill.js +139 -0
  35. package/skills/tools/gen-docs/SKILL.md +6 -4
  36. package/skills/tools/gen-docs/scripts/doc_generator.js +363 -0
  37. package/skills/tools/lib/shared.js +98 -0
  38. package/skills/tools/verify-change/SKILL.md +8 -6
  39. package/skills/tools/verify-change/scripts/change_analyzer.js +289 -0
  40. package/skills/tools/verify-module/SKILL.md +6 -4
  41. package/skills/tools/verify-module/scripts/module_scanner.js +171 -0
  42. package/skills/tools/verify-quality/SKILL.md +5 -3
  43. package/skills/tools/verify-quality/scripts/quality_checker.js +337 -0
  44. package/skills/tools/verify-security/SKILL.md +7 -5
  45. package/skills/tools/verify-security/scripts/security_scanner.js +283 -0
  46. package/skills/__pycache__/run_skill.cpython-312.pyc +0 -0
  47. package/skills/domains/COVERAGE_PLAN.md +0 -232
  48. package/skills/domains/ai/model-evaluation.md +0 -790
  49. package/skills/domains/ai/prompt-engineering.md +0 -703
  50. package/skills/domains/architecture/compliance.md +0 -299
  51. package/skills/domains/architecture/data-security.md +0 -184
  52. package/skills/domains/data-engineering/data-pipeline.md +0 -762
  53. package/skills/domains/data-engineering/data-quality.md +0 -894
  54. package/skills/domains/data-engineering/stream-processing.md +0 -791
  55. package/skills/domains/development/dart.md +0 -963
  56. package/skills/domains/development/kotlin.md +0 -834
  57. package/skills/domains/development/php.md +0 -659
  58. package/skills/domains/development/swift.md +0 -755
  59. package/skills/domains/devops/e2e-testing.md +0 -914
  60. package/skills/domains/devops/performance-testing.md +0 -734
  61. package/skills/domains/devops/testing-strategy.md +0 -667
  62. package/skills/domains/frontend-design/build-tools.md +0 -743
  63. package/skills/domains/frontend-design/performance.md +0 -734
  64. package/skills/domains/frontend-design/testing.md +0 -699
  65. package/skills/domains/infrastructure/gitops.md +0 -735
  66. package/skills/domains/infrastructure/iac.md +0 -855
  67. package/skills/domains/infrastructure/kubernetes.md +0 -1018
  68. package/skills/domains/mobile/android-dev.md +0 -979
  69. package/skills/domains/mobile/cross-platform.md +0 -795
  70. package/skills/domains/mobile/ios-dev.md +0 -931
  71. package/skills/domains/security/secrets-management.md +0 -834
  72. package/skills/domains/security/supply-chain.md +0 -931
  73. package/skills/domains/security/threat-modeling.md +0 -828
  74. package/skills/run_skill.py +0 -153
  75. package/skills/tests/README.md +0 -225
  76. package/skills/tests/SUMMARY.md +0 -362
  77. package/skills/tests/__init__.py +0 -3
  78. package/skills/tests/__pycache__/test_change_analyzer.cpython-312.pyc +0 -0
  79. package/skills/tests/__pycache__/test_doc_generator.cpython-312.pyc +0 -0
  80. package/skills/tests/__pycache__/test_module_scanner.cpython-312.pyc +0 -0
  81. package/skills/tests/__pycache__/test_quality_checker.cpython-312.pyc +0 -0
  82. package/skills/tests/__pycache__/test_security_scanner.cpython-312.pyc +0 -0
  83. package/skills/tests/test_change_analyzer.py +0 -558
  84. package/skills/tests/test_doc_generator.py +0 -538
  85. package/skills/tests/test_module_scanner.py +0 -376
  86. package/skills/tests/test_quality_checker.py +0 -516
  87. package/skills/tests/test_security_scanner.py +0 -426
  88. package/skills/tools/gen-docs/scripts/__pycache__/doc_generator.cpython-312.pyc +0 -0
  89. package/skills/tools/gen-docs/scripts/doc_generator.py +0 -520
  90. package/skills/tools/verify-change/scripts/__pycache__/change_analyzer.cpython-312.pyc +0 -0
  91. package/skills/tools/verify-change/scripts/change_analyzer.py +0 -529
  92. package/skills/tools/verify-module/scripts/__pycache__/module_scanner.cpython-312.pyc +0 -0
  93. package/skills/tools/verify-module/scripts/module_scanner.py +0 -321
  94. package/skills/tools/verify-quality/scripts/__pycache__/quality_checker.cpython-312.pyc +0 -0
  95. package/skills/tools/verify-quality/scripts/quality_checker.py +0 -481
  96. package/skills/tools/verify-security/scripts/__pycache__/security_scanner.cpython-312.pyc +0 -0
  97. package/skills/tools/verify-security/scripts/security_scanner.py +0 -374
@@ -1,734 +0,0 @@
1
- ---
2
- name: performance-testing
3
- description: 性能测试。k6、JMeter、Gatling、负载测试、压力测试、浸泡测试、性能指标分析。当用户提到性能测试、k6、JMeter、负载测试、压力测试、基准测试时使用。
4
- ---
5
-
6
- # ⚡ 性能测试 · Performance Testing
7
-
8
- ## 性能测试类型
9
-
10
- ```
11
- 负载测试 (Load Testing)
12
- └─ 验证系统在预期负载下的表现
13
-
14
- 压力测试 (Stress Testing)
15
- └─ 找到系统的极限和崩溃点
16
-
17
- 浸泡测试 (Soak Testing)
18
- └─ 长时间运行检测内存泄漏
19
-
20
- 峰值测试 (Spike Testing)
21
- └─ 突发流量下的系统表现
22
-
23
- 容量测试 (Capacity Testing)
24
- └─ 确定系统最大容量
25
- ```
26
-
27
- ### 测试场景对比
28
- | 类型 | 用户数 | 持续时间 | 目标 |
29
- |------|--------|----------|------|
30
- | 负载测试 | 预期峰值 | 30分钟-2小时 | 验证性能指标 |
31
- | 压力测试 | 超出峰值 | 1-3小时 | 找到崩溃点 |
32
- | 浸泡测试 | 正常负载 | 8-72小时 | 检测内存泄漏 |
33
- | 峰值测试 | 瞬间激增 | 短时间 | 测试弹性 |
34
-
35
- ## k6 基础
36
-
37
- ### 安装
38
- ```bash
39
- # macOS
40
- brew install k6
41
-
42
- # Linux
43
- sudo gpg -k
44
- sudo gpg --no-default-keyring --keyring /usr/share/keyrings/k6-archive-keyring.gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys C5AD17C747E3415A3642D57D77C6C491D6AC1D69
45
- echo "deb [signed-by=/usr/share/keyrings/k6-archive-keyring.gpg] https://dl.k6.io/deb stable main" | sudo tee /etc/apt/sources.list.d/k6.list
46
- sudo apt-get update
47
- sudo apt-get install k6
48
-
49
- # Docker
50
- docker run --rm -i grafana/k6 run - <script.js
51
- ```
52
-
53
- ### 基础脚本
54
- ```javascript
55
- import http from 'k6/http';
56
- import { check, sleep } from 'k6';
57
-
58
- export const options = {
59
- vus: 10, // 虚拟用户数
60
- duration: '30s', // 持续时间
61
- };
62
-
63
- export default function () {
64
- const res = http.get('https://api.example.com/users');
65
-
66
- check(res, {
67
- 'status is 200': (r) => r.status === 200,
68
- 'response time < 500ms': (r) => r.timings.duration < 500,
69
- });
70
-
71
- sleep(1);
72
- }
73
- ```
74
-
75
- ### 运行测试
76
- ```bash
77
- # 基础运行
78
- k6 run script.js
79
-
80
- # 指定参数
81
- k6 run --vus 100 --duration 5m script.js
82
-
83
- # 输出结果
84
- k6 run --out json=results.json script.js
85
- k6 run --out influxdb=http://localhost:8086/k6 script.js
86
- ```
87
-
88
- ## k6 高级场景
89
-
90
- ### 阶梯式负载
91
- ```javascript
92
- export const options = {
93
- stages: [
94
- { duration: '2m', target: 100 }, // 2分钟爬升到100用户
95
- { duration: '5m', target: 100 }, // 保持100用户5分钟
96
- { duration: '2m', target: 200 }, // 爬升到200用户
97
- { duration: '5m', target: 200 }, // 保持200用户
98
- { duration: '2m', target: 0 }, // 降到0
99
- ],
100
- thresholds: {
101
- http_req_duration: ['p(95)<500'], // 95%请求<500ms
102
- http_req_failed: ['rate<0.01'], // 错误率<1%
103
- },
104
- };
105
- ```
106
-
107
- ### 压力测试
108
- ```javascript
109
- export const options = {
110
- stages: [
111
- { duration: '5m', target: 100 },
112
- { duration: '10m', target: 100 },
113
- { duration: '5m', target: 200 },
114
- { duration: '10m', target: 200 },
115
- { duration: '5m', target: 300 },
116
- { duration: '10m', target: 300 },
117
- { duration: '5m', target: 400 },
118
- { duration: '10m', target: 400 },
119
- { duration: '5m', target: 0 },
120
- ],
121
- };
122
- ```
123
-
124
- ### 峰值测试
125
- ```javascript
126
- export const options = {
127
- stages: [
128
- { duration: '10s', target: 100 }, // 正常负载
129
- { duration: '1m', target: 100 },
130
- { duration: '10s', target: 1400 }, // 突然激增
131
- { duration: '3m', target: 1400 },
132
- { duration: '10s', target: 100 }, // 恢复正常
133
- { duration: '3m', target: 100 },
134
- { duration: '10s', target: 0 },
135
- ],
136
- };
137
- ```
138
-
139
- ### 浸泡测试
140
- ```javascript
141
- export const options = {
142
- stages: [
143
- { duration: '5m', target: 100 }, // 爬升
144
- { duration: '8h', target: 100 }, // 保持8小时
145
- { duration: '5m', target: 0 }, // 降低
146
- ],
147
- };
148
- ```
149
-
150
- ## k6 实战示例
151
-
152
- ### 登录流程测试
153
- ```javascript
154
- import http from 'k6/http';
155
- import { check, group, sleep } from 'k6';
156
-
157
- export const options = {
158
- vus: 50,
159
- duration: '5m',
160
- thresholds: {
161
- 'http_req_duration{name:login}': ['p(95)<1000'],
162
- 'http_req_duration{name:dashboard}': ['p(95)<500'],
163
- },
164
- };
165
-
166
- export default function () {
167
- group('用户登录流程', () => {
168
- // 1. 访问登录页
169
- let res = http.get('https://example.com/login');
170
- check(res, { 'login page loaded': (r) => r.status === 200 });
171
-
172
- // 2. 提交登录
173
- res = http.post('https://example.com/api/login', {
174
- username: 'testuser',
175
- password: 'password123',
176
- }, {
177
- tags: { name: 'login' },
178
- });
179
-
180
- check(res, {
181
- 'login successful': (r) => r.status === 200,
182
- 'token received': (r) => r.json('token') !== undefined,
183
- });
184
-
185
- const token = res.json('token');
186
-
187
- // 3. 访问受保护页面
188
- res = http.get('https://example.com/dashboard', {
189
- headers: { Authorization: `Bearer ${token}` },
190
- tags: { name: 'dashboard' },
191
- });
192
-
193
- check(res, { 'dashboard loaded': (r) => r.status === 200 });
194
-
195
- sleep(1);
196
- });
197
- }
198
- ```
199
-
200
- ### API 批量测试
201
- ```javascript
202
- import http from 'k6/http';
203
- import { check } from 'k6';
204
-
205
- export default function () {
206
- const requests = [
207
- ['GET', 'https://api.example.com/users'],
208
- ['GET', 'https://api.example.com/products'],
209
- ['GET', 'https://api.example.com/orders'],
210
- ];
211
-
212
- const responses = http.batch(requests.map(([method, url]) => ({
213
- method,
214
- url,
215
- })));
216
-
217
- responses.forEach((res, i) => {
218
- check(res, {
219
- [`${requests[i][1]} status 200`]: (r) => r.status === 200,
220
- });
221
- });
222
- }
223
- ```
224
-
225
- ### 文件上传测试
226
- ```javascript
227
- import http from 'k6/http';
228
- import { check } from 'k6';
229
-
230
- const binFile = open('./test-file.pdf', 'b');
231
-
232
- export default function () {
233
- const data = {
234
- file: http.file(binFile, 'test-file.pdf'),
235
- description: 'Test upload',
236
- };
237
-
238
- const res = http.post('https://api.example.com/upload', data);
239
-
240
- check(res, {
241
- 'upload successful': (r) => r.status === 201,
242
- });
243
- }
244
- ```
245
-
246
- ### WebSocket 测试
247
- ```javascript
248
- import ws from 'k6/ws';
249
- import { check } from 'k6';
250
-
251
- export default function () {
252
- const url = 'ws://example.com/ws';
253
-
254
- const res = ws.connect(url, {}, function (socket) {
255
- socket.on('open', () => {
256
- console.log('connected');
257
- socket.send(JSON.stringify({ type: 'subscribe', channel: 'updates' }));
258
- });
259
-
260
- socket.on('message', (data) => {
261
- console.log('Message received:', data);
262
- });
263
-
264
- socket.on('close', () => console.log('disconnected'));
265
-
266
- socket.setTimeout(() => {
267
- socket.close();
268
- }, 10000);
269
- });
270
-
271
- check(res, { 'status is 101': (r) => r && r.status === 101 });
272
- }
273
- ```
274
-
275
- ## JMeter 基础
276
-
277
- ### 安装
278
- ```bash
279
- # 下载
280
- wget https://dlcdn.apache.org//jmeter/binaries/apache-jmeter-5.6.2.tgz
281
- tar -xzf apache-jmeter-5.6.2.tgz
282
-
283
- # 运行 GUI
284
- ./apache-jmeter-5.6.2/bin/jmeter
285
-
286
- # 命令行运行
287
- ./apache-jmeter-5.6.2/bin/jmeter -n -t test.jmx -l results.jtl
288
- ```
289
-
290
- ### 测试计划结构
291
- ```
292
- Test Plan
293
- ├── Thread Group (线程组)
294
- │ ├── HTTP Request (HTTP请求)
295
- │ ├── HTTP Header Manager (请求头)
296
- │ ├── Assertions (断言)
297
- │ └── Listeners (监听器)
298
- ├── CSV Data Set Config (CSV数据)
299
- └── Summary Report (汇总报告)
300
- ```
301
-
302
- ### HTTP 请求配置
303
- ```xml
304
- <!-- JMeter 测试计划示例 -->
305
- <HTTPSamplerProxy>
306
- <elementProp name="HTTPsampler.Arguments">
307
- <collectionProp name="Arguments.arguments">
308
- <elementProp name="username" elementType="HTTPArgument">
309
- <stringProp name="Argument.value">testuser</stringProp>
310
- </elementProp>
311
- </collectionProp>
312
- </elementProp>
313
- <stringProp name="HTTPSampler.domain">api.example.com</stringProp>
314
- <stringProp name="HTTPSampler.port">443</stringProp>
315
- <stringProp name="HTTPSampler.protocol">https</stringProp>
316
- <stringProp name="HTTPSampler.path">/api/login</stringProp>
317
- <stringProp name="HTTPSampler.method">POST</stringProp>
318
- </HTTPSamplerProxy>
319
- ```
320
-
321
- ### 线程组配置
322
- ```
323
- Number of Threads (users): 100
324
- Ramp-up period (seconds): 60
325
- Loop Count: 10
326
-
327
- 实际含义:
328
- - 100个并发用户
329
- - 60秒内逐步启动
330
- - 每个用户执行10次
331
- - 总请求数:100 * 10 = 1000
332
- ```
333
-
334
- ### 断言配置
335
- ```xml
336
- <ResponseAssertion>
337
- <collectionProp name="Asserion.test_strings">
338
- <stringProp name="49586">200</stringProp>
339
- </collectionProp>
340
- <stringProp name="Assertion.test_field">Assertion.response_code</stringProp>
341
- <stringProp name="Assertion.assume_success">false</stringProp>
342
- <intProp name="Assertion.test_type">8</intProp>
343
- </ResponseAssertion>
344
- ```
345
-
346
- ## JMeter 高级功能
347
-
348
- ### CSV 参数化
349
- ```csv
350
- # users.csv
351
- username,password
352
- user1,pass1
353
- user2,pass2
354
- user3,pass3
355
- ```
356
-
357
- ```xml
358
- <CSVDataSet>
359
- <stringProp name="filename">users.csv</stringProp>
360
- <stringProp name="variableNames">username,password</stringProp>
361
- <boolProp name="recycle">true</boolProp>
362
- <boolProp name="stopThread">false</boolProp>
363
- </CSVDataSet>
364
-
365
- <!-- 使用变量 -->
366
- <stringProp name="Argument.value">${username}</stringProp>
367
- ```
368
-
369
- ### 正则提取器
370
- ```xml
371
- <RegexExtractor>
372
- <stringProp name="RegexExtractor.refname">token</stringProp>
373
- <stringProp name="RegexExtractor.regex">"token":"([^"]+)"</stringProp>
374
- <stringProp name="RegexExtractor.template">$1$</stringProp>
375
- <stringProp name="RegexExtractor.default">NOT_FOUND</stringProp>
376
- <intProp name="RegexExtractor.match_number">1</intProp>
377
- </RegexExtractor>
378
-
379
- <!-- 后续请求使用 -->
380
- <stringProp name="Header.value">Bearer ${token}</stringProp>
381
- ```
382
-
383
- ### BeanShell 脚本
384
- ```java
385
- // 前置处理器
386
- import java.util.Date;
387
- import java.text.SimpleDateFormat;
388
-
389
- SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
390
- String timestamp = sdf.format(new Date());
391
- vars.put("timestamp", timestamp);
392
-
393
- // 后置处理器
394
- String response = prev.getResponseDataAsString();
395
- log.info("Response: " + response);
396
-
397
- if (prev.getResponseCode().equals("200")) {
398
- vars.put("status", "success");
399
- } else {
400
- vars.put("status", "failed");
401
- }
402
- ```
403
-
404
- ## 性能指标分析
405
-
406
- ### 关键指标
407
- ```
408
- 响应时间 (Response Time)
409
- ├── 平均响应时间 (Average)
410
- ├── 中位数 (Median/P50)
411
- ├── 90分位 (P90)
412
- ├── 95分位 (P95)
413
- └── 99分位 (P99)
414
-
415
- 吞吐量 (Throughput)
416
- ├── 请求/秒 (RPS)
417
- ├── 事务/秒 (TPS)
418
- └── 数据传输速率 (MB/s)
419
-
420
- 错误率 (Error Rate)
421
- ├── HTTP错误 (4xx/5xx)
422
- ├── 超时错误
423
- └── 连接错误
424
-
425
- 并发用户数 (Concurrent Users)
426
- └── 活跃用户数
427
- ```
428
-
429
- ### 指标阈值示例
430
- ```javascript
431
- // k6 阈值配置
432
- export const options = {
433
- thresholds: {
434
- // 响应时间
435
- 'http_req_duration': ['p(95)<500', 'p(99)<1000'],
436
-
437
- // 错误率
438
- 'http_req_failed': ['rate<0.01'],
439
-
440
- // 吞吐量
441
- 'http_reqs': ['rate>100'],
442
-
443
- // 特定请求
444
- 'http_req_duration{name:login}': ['p(95)<1000'],
445
- 'http_req_duration{name:api}': ['p(95)<200'],
446
- },
447
- };
448
- ```
449
-
450
- ### 性能基准
451
- | 场景 | P95响应时间 | 错误率 | 吞吐量 |
452
- |------|-------------|--------|--------|
453
- | API查询 | <200ms | <0.1% | >1000 RPS |
454
- | API写入 | <500ms | <0.5% | >500 RPS |
455
- | 页面加载 | <2s | <1% | >100 RPS |
456
- | 文件上传 | <5s | <2% | >50 RPS |
457
-
458
- ## Gatling 示例
459
-
460
- ### 基础脚本
461
- ```scala
462
- import io.gatling.core.Predef._
463
- import io.gatling.http.Predef._
464
- import scala.concurrent.duration._
465
-
466
- class BasicSimulation extends Simulation {
467
-
468
- val httpProtocol = http
469
- .baseUrl("https://api.example.com")
470
- .acceptHeader("application/json")
471
- .userAgentHeader("Gatling")
472
-
473
- val scn = scenario("Basic Load Test")
474
- .exec(
475
- http("Get Users")
476
- .get("/users")
477
- .check(status.is(200))
478
- )
479
- .pause(1)
480
-
481
- setUp(
482
- scn.inject(
483
- rampUsers(100) during (60 seconds)
484
- )
485
- ).protocols(httpProtocol)
486
- }
487
- ```
488
-
489
- ### 复杂场景
490
- ```scala
491
- class AdvancedSimulation extends Simulation {
492
-
493
- val httpProtocol = http.baseUrl("https://api.example.com")
494
-
495
- val login = exec(
496
- http("Login")
497
- .post("/api/login")
498
- .body(StringBody("""{"username":"${username}","password":"${password}"}"""))
499
- .check(jsonPath("$.token").saveAs("token"))
500
- )
501
-
502
- val browse = exec(
503
- http("Get Dashboard")
504
- .get("/dashboard")
505
- .header("Authorization", "Bearer ${token}")
506
- )
507
-
508
- val scn = scenario("User Journey")
509
- .feed(csv("users.csv").circular)
510
- .exec(login)
511
- .pause(2)
512
- .exec(browse)
513
-
514
- setUp(
515
- scn.inject(
516
- atOnceUsers(10),
517
- rampUsers(50) during (30 seconds),
518
- constantUsersPerSec(20) during (1 minute)
519
- )
520
- ).protocols(httpProtocol)
521
- }
522
- ```
523
-
524
- ## 性能监控集成
525
-
526
- ### Prometheus + Grafana
527
- ```yaml
528
- # k6 输出到 Prometheus
529
- export const options = {
530
- ext: {
531
- loadimpact: {
532
- projectID: 123456,
533
- name: "Performance Test"
534
- }
535
- }
536
- };
537
-
538
- # 或使用 xk6-output-prometheus-remote
539
- K6_PROMETHEUS_REMOTE_URL=http://localhost:9090/api/v1/write k6 run script.js
540
- ```
541
-
542
- ### InfluxDB 集成
543
- ```bash
544
- # 启动 InfluxDB
545
- docker run -d -p 8086:8086 influxdb:1.8
546
-
547
- # k6 输出到 InfluxDB
548
- k6 run --out influxdb=http://localhost:8086/k6 script.js
549
- ```
550
-
551
- ### Grafana Dashboard
552
- ```json
553
- {
554
- "dashboard": {
555
- "title": "k6 Performance Dashboard",
556
- "panels": [
557
- {
558
- "title": "Response Time",
559
- "targets": [
560
- {
561
- "measurement": "http_req_duration",
562
- "select": [["value", "mean"]]
563
- }
564
- ]
565
- },
566
- {
567
- "title": "Throughput",
568
- "targets": [
569
- {
570
- "measurement": "http_reqs",
571
- "select": [["count", "sum"]]
572
- }
573
- ]
574
- }
575
- ]
576
- }
577
- }
578
- ```
579
-
580
- ## CI/CD 集成
581
-
582
- ### GitHub Actions
583
- ```yaml
584
- name: Performance Test
585
-
586
- on:
587
- schedule:
588
- - cron: '0 2 * * *' # 每天凌晨2点
589
- workflow_dispatch:
590
-
591
- jobs:
592
- performance:
593
- runs-on: ubuntu-latest
594
- steps:
595
- - uses: actions/checkout@v3
596
-
597
- - name: Run k6 test
598
- uses: grafana/k6-action@v0.3.0
599
- with:
600
- filename: tests/performance.js
601
- flags: --out json=results.json
602
-
603
- - name: Upload results
604
- uses: actions/upload-artifact@v3
605
- with:
606
- name: k6-results
607
- path: results.json
608
-
609
- - name: Check thresholds
610
- run: |
611
- if grep -q '"thresholds".*"failed":true' results.json; then
612
- echo "Performance thresholds failed"
613
- exit 1
614
- fi
615
- ```
616
-
617
- ### GitLab CI
618
- ```yaml
619
- performance:
620
- image: grafana/k6:latest
621
- stage: test
622
- script:
623
- - k6 run --out json=results.json tests/performance.js
624
- artifacts:
625
- paths:
626
- - results.json
627
- reports:
628
- performance: results.json
629
- only:
630
- - schedules
631
- ```
632
-
633
- ## 性能测试最佳实践
634
-
635
- ### 测试环境
636
- ```yaml
637
- 要求:
638
- - 独立环境,避免干扰
639
- - 配置与生产环境一致
640
- - 稳定的网络环境
641
- - 充足的资源(CPU/内存/带宽)
642
-
643
- 避免:
644
- - 在生产环境测试
645
- - 共享测试环境
646
- - 资源不足的环境
647
- ```
648
-
649
- ### 测试数据
650
- ```javascript
651
- // ✅ 使用真实数据分布
652
- const users = [
653
- { type: 'light', weight: 70 }, // 70%轻度用户
654
- { type: 'medium', weight: 20 }, // 20%中度用户
655
- { type: 'heavy', weight: 10 }, // 10%重度用户
656
- ];
657
-
658
- // ✅ 数据隔离
659
- const userId = `user_${__VU}_${__ITER}`;
660
-
661
- // ✅ 清理测试数据
662
- export function teardown(data) {
663
- // 清理逻辑
664
- }
665
- ```
666
-
667
- ### 渐进式测试
668
- ```
669
- 1. 基准测试 (Baseline)
670
- └─ 单用户,建立基准
671
-
672
- 2. 负载测试 (Load)
673
- └─ 预期负载,验证性能
674
-
675
- 3. 压力测试 (Stress)
676
- └─ 超出负载,找到极限
677
-
678
- 4. 浸泡测试 (Soak)
679
- └─ 长时间运行,检测泄漏
680
- ```
681
-
682
- ### 结果分析
683
- ```javascript
684
- // k6 自定义指标
685
- import { Trend, Counter } from 'k6/metrics';
686
-
687
- const loginDuration = new Trend('login_duration');
688
- const loginErrors = new Counter('login_errors');
689
-
690
- export default function () {
691
- const start = Date.now();
692
- const res = http.post('/login', payload);
693
- loginDuration.add(Date.now() - start);
694
-
695
- if (res.status !== 200) {
696
- loginErrors.add(1);
697
- }
698
- }
699
- ```
700
-
701
- ## 工具对比
702
-
703
- | 工具 | 语言 | 学习曲线 | 性能 | 云支持 | 开源 |
704
- |------|------|----------|------|--------|------|
705
- | k6 | JavaScript | 低 | 高 | ✅ | ✅ |
706
- | JMeter | Java/GUI | 中 | 中 | ⚠️ | ✅ |
707
- | Gatling | Scala | 高 | 高 | ✅ | ✅ |
708
- | Locust | Python | 低 | 中 | ⚠️ | ✅ |
709
- | Artillery | JavaScript | 低 | 中 | ✅ | ✅ |
710
-
711
- ### 选择建议
712
- ```
713
- k6:
714
- ✅ 现代化、易用、性能好
715
- ✅ 适合 DevOps 集成
716
- ✅ 云原生支持
717
-
718
- JMeter:
719
- ✅ 功能全面、插件丰富
720
- ✅ GUI 适合初学者
721
- ⚠️ 资源消耗较大
722
-
723
- Gatling:
724
- ✅ 高性能、DSL 优雅
725
- ⚠️ 学习曲线陡峭
726
- ✅ 适合大规模测试
727
-
728
- Locust:
729
- ✅ Python 生态
730
- ✅ 分布式支持
731
- ⚠️ 性能不如 k6/Gatling
732
- ```
733
-
734
- ---