Skip to content

Commit 501eacb

Browse files
authored
Merge pull request #35 from JaD1ng/mock
同步之前代码
2 parents 1bb9994 + 27320a9 commit 501eacb

File tree

13 files changed

+403
-155
lines changed

13 files changed

+403
-155
lines changed

mock/s3/README.md

Lines changed: 61 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -73,18 +73,28 @@
7373

7474
#### 网络架构
7575
```
76-
Docker网络:172.20.0.0/16
77-
├─ 基础设施层:172.20.0.10-29
76+
Docker网络:172.20.0.0/16 (支持动态多实例扩容)
77+
├─ 基础设施层:固定IP (172.20.0.10-29)
7878
│ ├─ consul: 172.20.0.10
7979
│ ├─ postgres: 172.20.0.11
8080
│ ├─ redis: 172.20.0.12
8181
│ └─ 监控组件: 172.20.0.20-24
82-
└─ 业务服务层:172.20.0.30-39
83-
├─ metadata-service: 172.20.0.31
84-
├─ storage-service: 172.20.0.32
85-
├─ queue-service: 172.20.0.33
86-
├─ third-party-service: 172.20.0.34
87-
└─ mock-error-service: 172.20.0.35
82+
└─ 业务服务层:动态分配IP (支持多实例)
83+
├─ metadata-service: 可扩容到多个实例
84+
├─ storage-service: 可扩容到多个实例
85+
├─ queue-service: 可扩容到多个实例
86+
├─ third-party-service: 可扩容到多个实例
87+
└─ mock-error-service: 可扩容到多个实例
88+
89+
服务发现:
90+
• 每个服务实例使用UUID生成唯一ServiceID
91+
• Consul自动负载均衡到健康实例
92+
• 端口范围映射支持多实例访问
93+
94+
技术实现:
95+
• ServiceID格式: {service-name}-{uuid}
96+
• 支持动态扩缩容: docker-compose up -d --scale service=N
97+
• 无状态设计: 实例间无依赖,可随意增减
8898
```
8999

90100
---
@@ -111,16 +121,56 @@ Docker网络:172.20.0.0/16
111121
docker --version && docker-compose --version
112122
```
113123

114-
### 第二步:一键启动
115-
```bash
124+
### 第二步:启动服务栈
116125

117-
# 启动完整服务栈
126+
#### 单实例模式
127+
```bash
128+
# 启动完整服务栈(每个服务1个实例)
118129
docker-compose up --build -d
119130

120131
# 等待服务就绪
121132
docker-compose ps
122133
```
123134

135+
#### 多实例模式
136+
137+
**一次性构建**
138+
```bash
139+
# 启动多实例服务栈
140+
docker-compose up --build -d \
141+
--scale metadata-service=3 \
142+
--scale storage-service=2 \
143+
--scale queue-service=2 \
144+
--scale third-party-service=2 \
145+
--scale mock-error-service=1
146+
```
147+
148+
**分批构建**
149+
```bash
150+
# 第一步:启动基础设施服务
151+
docker-compose up -d consul postgres redis elasticsearch prometheus grafana kibana otel-collector
152+
153+
# 第二步:分别构建各个服务镜像
154+
docker-compose build metadata-service
155+
docker-compose build storage-service
156+
docker-compose build queue-service
157+
docker-compose build third-party-service
158+
docker-compose build mock-error-service
159+
160+
# 第三步:分批启动业务服务
161+
docker-compose up -d --scale metadata-service=3 metadata-service
162+
docker-compose up -d --scale storage-service=2 storage-service
163+
docker-compose up -d --scale queue-service=2 queue-service
164+
docker-compose up -d --scale third-party-service=2 third-party-service
165+
docker-compose up -d --scale mock-error-service=1 mock-error-service
166+
167+
# 验证所有实例运行状态
168+
docker-compose ps
169+
170+
# 查看Consul服务发现状态
171+
curl -s "http://localhost:8500/v1/catalog/services" | jq .
172+
```
173+
124174
### 第三步:故障注入体验
125175
```bash
126176
# 创建CPU峰值异常 - 持续2分钟

mock/s3/deployments/observability/grafana/dashboards/mock-s3-services-metrics.json

Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,20 @@
2828
"text": "All",
2929
"value": "$__all"
3030
}
31+
},
32+
{
33+
"name": "instance",
34+
"type": "query",
35+
"query": "label_values(system_cpu_usage_percent_percent{service=~\"$service\"}, instance)",
36+
"refresh": 1,
37+
"includeAll": true,
38+
"allValue": ".*",
39+
"multi": true,
40+
"current": {
41+
"selected": true,
42+
"text": "All",
43+
"value": "$__all"
44+
}
3145
}
3246
]
3347
},
@@ -38,8 +52,8 @@
3852
"type": "timeseries",
3953
"targets": [
4054
{
41-
"expr": "system_cpu_usage_percent_percent{service=~\"$service\"}",
42-
"legendFormat": "{{service}} CPU",
55+
"expr": "system_cpu_usage_percent_percent{service=~\"$service\",instance=~\"$instance\"}",
56+
"legendFormat": "{{service}} {{instance}} CPU",
4357
"refId": "A"
4458
}
4559
],
@@ -74,8 +88,8 @@
7488
"type": "timeseries",
7589
"targets": [
7690
{
77-
"expr": "system_memory_usage_percent_percent{service=~\"$service\"}",
78-
"legendFormat": "{{service}} Memory",
91+
"expr": "system_memory_usage_percent_percent{service=~\"$service\",instance=~\"$instance\"}",
92+
"legendFormat": "{{service}} {{instance}} Memory",
7993
"refId": "A"
8094
}
8195
],
@@ -110,7 +124,7 @@
110124
"type": "stat",
111125
"targets": [
112126
{
113-
"expr": "system_cpu_usage_percent_percent{service=~\"$service\"}",
127+
"expr": "system_cpu_usage_percent_percent{service=~\"$service\",instance=~\"$instance\"}",
114128
"legendFormat": "{{service}}",
115129
"refId": "A"
116130
}
@@ -158,7 +172,7 @@
158172
"type": "stat",
159173
"targets": [
160174
{
161-
"expr": "system_memory_usage_percent_percent{service=~\"$service\"}",
175+
"expr": "system_memory_usage_percent_percent{service=~\"$service\",instance=~\"$instance\"}",
162176
"legendFormat": "{{service}}",
163177
"refId": "A"
164178
}
@@ -206,8 +220,8 @@
206220
"type": "timeseries",
207221
"targets": [
208222
{
209-
"expr": "system_network_qps_per_second{service=~\"$service\"}",
210-
"legendFormat": "{{service}} QPS",
223+
"expr": "system_network_qps_per_second{service=~\"$service\",instance=~\"$instance\"}",
224+
"legendFormat": "{{service}} {{instance}} QPS",
211225
"refId": "A"
212226
}
213227
],
@@ -241,7 +255,7 @@
241255
"type": "stat",
242256
"targets": [
243257
{
244-
"expr": "system_machine_online_status{service=~\"$service\"}",
258+
"expr": "system_machine_online_status{service=~\"$service\",instance=~\"$instance\"}",
245259
"legendFormat": "{{service}}",
246260
"refId": "A"
247261
}
@@ -351,28 +365,28 @@
351365
"type": "table",
352366
"targets": [
353367
{
354-
"expr": "system_cpu_usage_percent_percent{service=~\"$service\"}",
368+
"expr": "system_cpu_usage_percent_percent{service=~\"$service\",instance=~\"$instance\"}",
355369
"legendFormat": "",
356370
"refId": "A",
357371
"instant": true,
358372
"format": "table"
359373
},
360374
{
361-
"expr": "system_memory_usage_percent_percent{service=~\"$service\"}",
375+
"expr": "system_memory_usage_percent_percent{service=~\"$service\",instance=~\"$instance\"}",
362376
"legendFormat": "",
363377
"refId": "B",
364378
"instant": true,
365379
"format": "table"
366380
},
367381
{
368-
"expr": "system_network_qps_per_second{service=~\"$service\"}",
382+
"expr": "system_network_qps_per_second{service=~\"$service\",instance=~\"$instance\"}",
369383
"legendFormat": "",
370384
"refId": "C",
371385
"instant": true,
372386
"format": "table"
373387
},
374388
{
375-
"expr": "system_machine_online_status{service=~\"$service\"}",
389+
"expr": "system_machine_online_status{service=~\"$service\",instance=~\"$instance\"}",
376390
"legendFormat": "",
377391
"refId": "D",
378392
"instant": true,
@@ -389,14 +403,14 @@
389403
"options": {
390404
"excludeByName": {
391405
"Time": true,
392-
"instance": true,
393406
"job": true,
394407
"node": true,
395408
"otel_scope_name": true,
396409
"__name__": true
397410
},
398411
"renameByName": {
399412
"service": "Service",
413+
"instance": "Instance",
400414
"Value #A": "CPU (%)",
401415
"Value #B": "Memory (%)",
402416
"Value #C": "Network QPS",
@@ -494,8 +508,8 @@
494508
"type": "piechart",
495509
"targets": [
496510
{
497-
"expr": "topk(5, system_cpu_usage_percent_percent{service=~\"$service\"})",
498-
"legendFormat": "{{service}}",
511+
"expr": "topk(5, system_cpu_usage_percent_percent{service=~\"$service\",instance=~\"$instance\"})",
512+
"legendFormat": "{{service}} {{instance}}",
499513
"refId": "A"
500514
}
501515
],
@@ -534,8 +548,8 @@
534548
"type": "heatmap",
535549
"targets": [
536550
{
537-
"expr": "avg_over_time(system_cpu_usage_percent_percent{service=~\"$service\"}[5m])",
538-
"legendFormat": "{{service}}",
551+
"expr": "avg_over_time(system_cpu_usage_percent_percent{service=~\"$service\",instance=~\"$instance\"}[5m])",
552+
"legendFormat": "{{service}} {{instance}}",
539553
"refId": "A"
540554
}
541555
],
@@ -560,4 +574,4 @@
560574
},
561575
"schemaVersion": 36,
562576
"version": 1
563-
}
577+
}

mock/s3/deployments/observability/prometheus.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,9 @@ scrape_configs:
3333
relabel_configs:
3434
- source_labels: [__meta_consul_service]
3535
target_label: service
36+
- source_labels: [__meta_consul_service_id]
37+
target_label: service_id
3638
- source_labels: [__meta_consul_node]
3739
target_label: node
3840

39-
# 存储配置 - 命令行参数将在docker-compose中配置
41+
# 存储配置 - 命令行参数将在docker-compose中配置

mock/s3/docker-compose.yml

Lines changed: 10 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
version: '3.8'
2-
31
networks:
42
mock-s3-network:
53
driver: bridge
@@ -244,13 +242,11 @@ services:
244242
context: .
245243
dockerfile: services/metadata/Dockerfile
246244
image: mock-s3/metadata-service:latest
247-
container_name: mock-s3-metadata-service
248245
hostname: metadata-service
249246
networks:
250-
mock-s3-network:
251-
ipv4_address: 172.20.0.31
247+
- mock-s3-network
252248
ports:
253-
- "8081:8081"
249+
- "8081-8090:8081"
254250
environment:
255251
- SERVICE_NAME=metadata-service
256252
- CONSUL_ADDR=consul:8500
@@ -280,13 +276,11 @@ services:
280276
context: .
281277
dockerfile: services/storage/Dockerfile
282278
image: mock-s3/storage-service:latest
283-
container_name: mock-s3-storage-service
284279
hostname: storage-service
285280
networks:
286-
mock-s3-network:
287-
ipv4_address: 172.20.0.32
281+
- mock-s3-network
288282
ports:
289-
- "8082:8082"
283+
- "8082-8092:8082"
290284
volumes:
291285
- storage-data:/app/data/storage
292286
environment:
@@ -311,13 +305,11 @@ services:
311305
context: .
312306
dockerfile: services/queue/Dockerfile
313307
image: mock-s3/queue-service:latest
314-
container_name: mock-s3-queue-service
315308
hostname: queue-service
316309
networks:
317-
mock-s3-network:
318-
ipv4_address: 172.20.0.33
310+
- mock-s3-network
319311
ports:
320-
- "8083:8083"
312+
- "8083-8093:8083"
321313
environment:
322314
- SERVICE_NAME=queue-service
323315
- CONSUL_ADDR=consul:8500
@@ -343,13 +335,11 @@ services:
343335
context: .
344336
dockerfile: services/third-party/Dockerfile
345337
image: mock-s3/third-party-service:latest
346-
container_name: mock-s3-third-party-service
347338
hostname: third-party-service
348339
networks:
349-
mock-s3-network:
350-
ipv4_address: 172.20.0.34
340+
- mock-s3-network
351341
ports:
352-
- "8084:8084"
342+
- "8084-8094:8084"
353343
environment:
354344
- SERVICE_NAME=third-party-service
355345
- CONSUL_ADDR=consul:8500
@@ -372,13 +362,11 @@ services:
372362
context: .
373363
dockerfile: services/mock-error/Dockerfile
374364
image: mock-s3/mock-error-service:latest
375-
container_name: mock-s3-mock-error-service
376365
hostname: mock-error-service
377366
networks:
378-
mock-s3-network:
379-
ipv4_address: 172.20.0.35
367+
- mock-s3-network
380368
ports:
381-
- "8085:8085"
369+
- "8085-8095:8085"
382370
volumes:
383371
- mock-error-data:/app/data
384372
environment:

mock/s3/services/mock-error/internal/handler/mock_error_handler.go

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -85,26 +85,28 @@ func (h *MockErrorHandler) deleteMetricAnomaly(c *gin.Context) {
8585

8686
// checkMetricInjection 检查是否应该注入指标异常
8787
func (h *MockErrorHandler) checkMetricInjection(c *gin.Context) {
88-
ctx := c.Request.Context()
88+
ctx := c.Request.Context()
8989

90-
var request struct {
91-
Service string `json:"service" binding:"required"`
92-
MetricName string `json:"metric_name" binding:"required"`
93-
}
90+
var request struct {
91+
Service string `json:"service" binding:"required"`
92+
MetricName string `json:"metric_name" binding:"required"`
93+
Instance string `json:"instance"`
94+
}
9495

9596
if err := c.ShouldBindJSON(&request); err != nil {
9697
h.logger.Error(ctx, "Failed to bind metric injection check request", observability.Error(err))
9798
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
9899
return
99100
}
100101

101-
anomaly, shouldInject := h.errorService.ShouldInjectError(ctx, request.Service, request.MetricName)
102+
anomaly, shouldInject := h.errorService.ShouldInjectError(ctx, request.Service, request.MetricName, request.Instance)
102103

103-
response := gin.H{
104-
"should_inject": shouldInject,
105-
"service": request.Service,
106-
"metric_name": request.MetricName,
107-
}
104+
response := gin.H{
105+
"should_inject": shouldInject,
106+
"service": request.Service,
107+
"metric_name": request.MetricName,
108+
"instance": request.Instance,
109+
}
108110

109111
if shouldInject {
110112
response["anomaly"] = anomaly

0 commit comments

Comments
 (0)