@umacloud/knowledge 1.0.14 → 1.0.16
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/00-governance/knowledge-map.md +1 -1
- package/agentic-delivery/01-standards/context-engineering-for-delivery.md +94 -0
- package/agentic-delivery/01-standards/eval-driven-delivery.md +90 -0
- package/agentic-delivery/01-standards/generated-code-failure-modes.md +91 -0
- package/agentic-delivery/01-standards/production-readiness-scorecard.md +79 -0
- package/agentic-delivery/01-standards/self-improving-memory-and-regression-sets.md +80 -0
- package/agentic-delivery/01-standards/spec-as-contract.md +88 -0
- package/agentic-delivery/01-standards/test-discipline-for-generated-code.md +94 -0
- package/agentic-delivery/01-standards/test-integrity-and-anti-gaming.md +92 -0
- package/agentic-delivery/01-standards/verifier-critic-pattern.md +89 -0
- package/ai/agent-evaluation-benchmark.md +1 -1
- package/ai/ai-agent-memory-context-management.md +1 -1
- package/ai/ai-cost-capacity-optimization-playbook.md +1 -1
- package/ai/ai-data-security-and-compliance-playbook.md +1 -1
- package/ai/ai-domain-index-and-checklist.md +1 -1
- package/ai/ai-governance-maturity-model.md +1 -1
- package/ai/ai-model-selection-and-routing-strategy.md +1 -1
- package/ai/ai-observability-and-oncall-runbook.md +1 -1
- package/ai/ai-rag-engineering-playbook.md +1 -1
- package/ai/ai-red-team-and-safety-evaluation.md +1 -1
- package/ai/ai-release-readiness-and-rollback-gate.md +1 -1
- package/ai/llm-agent-engineering-deep-dive.md +1 -1
- package/ai/prompt-and-tool-guardrails.md +1 -1
- package/api/01-standards/api-versioning-and-deprecation-policy.md +100 -0
- package/architecture/01-standards/configuration-and-environment-management.md +104 -0
- package/architecture/01-standards/domain-driven-design-complete.md +105 -0
- package/architecture/02-playbooks/migration-playbook.md +1 -1
- package/architecture/02-playbooks/system-design-playbook.md +1 -1
- package/architecture/adr-template-and-examples.md +1 -1
- package/architecture/configuration-management.md +95 -1158
- package/architecture/resilience-and-disaster-patterns.md +87 -27
- package/architecture/system-architecture-deep-dive.md +1 -1
- package/backend/01-standards/dependency-and-supply-chain-hygiene.md +90 -0
- package/backend/01-standards/error-handling-taxonomy.md +88 -0
- package/backend/01-standards/idempotency-and-safe-retries.md +101 -0
- package/backend/01-standards/message-queue-patterns.md +96 -374
- package/backend/01-standards/queue-and-consumer-reliability.md +98 -0
- package/backend/01-standards/resilience-and-fault-tolerance.md +101 -0
- package/backend/01-standards/transactions-and-concurrency-control.md +92 -0
- package/cicd/cicd-blueprint-deep-dive.md +1 -1
- package/cicd/release-readiness-gate.md +78 -27
- package/cloud-native/01-standards/container-security.md +1 -1
- package/cloud-native/01-standards/kubernetes-complete.md +1 -1
- package/cloud-native/02-playbooks/gitops-with-argocd.md +1 -1
- package/cloud-native/02-playbooks/k8s-troubleshooting-playbook.md +1 -1
- package/cloud-native/02-playbooks/multicloud-governance.md +1 -1
- package/cloud-native/02-playbooks/serverless-patterns.md +1 -1
- package/cloud-native/02-playbooks/service-mesh-playbook.md +1 -1
- package/cloud-native/03-checklists/container-security-checklist.md +1 -1
- package/cloud-native/03-checklists/k8s-production-readiness-checklist.md +1 -1
- package/cloud-native/04-antipatterns/container-antipatterns.md +1 -1
- package/cloud-native/04-antipatterns/k8s-antipatterns.md +1 -1
- package/cloud-native/05-cases/case-k8s-migration.md +1 -1
- package/cloud-native/05-cases/case-k8s-scaling.md +1 -1
- package/cloud-native/05-cases/case-k8s-security-incident.md +1 -1
- package/cloud-native/06-glossary/cloud-native-glossary.md +1 -1
- package/compliance/01-standards/audit-logging-and-evidence.md +111 -0
- package/compliance/01-standards/privacy-and-compliance-readiness.md +119 -0
- package/data/data-governance-and-modeling-deep-dive.md +1 -1
- package/design/ux-system-deep-dive.md +1 -1
- package/development/00-governance/document-template.md +1 -1
- package/development/01-standards/code-review-and-pr-hygiene.md +85 -0
- package/development/03-checklists/production-readiness-checklist.md +6 -6
- package/development/09-maturity/quarterly-audit-template.md +1 -1
- package/development/11-ui-excellence/ui-aesthetic-system.md +1 -1
- package/development/13-implementation-assets/knowledge-gates-execution.md +1 -1
- package/development/api-contract-and-versioning-guide.md +1 -1
- package/development/api-governance-complete.md +1 -1
- package/development/backend-engineering-complete.md +1 -1
- package/development/code-review-quality-complete.md +11 -34
- package/development/concurrency-reliability-complete.md +1 -1
- package/development/database-engineering-complete.md +1 -1
- package/development/engineering-effectiveness-complete.md +1 -1
- package/development/engineering-standards-deep-dive.md +1 -1
- package/development/frontend-engineering-complete.md +1 -1
- package/development/performance-capacity-complete.md +1 -1
- package/development/refactor-migration-complete.md +1 -1
- package/development/refactoring-and-techdebt-playbook.md +1 -1
- package/development/security-in-development-complete.md +1 -1
- package/experts/architect/contract-first-api-design.md +140 -0
- package/experts/product-manager/prd-template-and-structure.md +144 -0
- package/experts/product-manager/requirements-engineering-ears.md +133 -0
- package/experts/qa-lead/test-plan-template.md +127 -0
- package/frontend/01-standards/accessibility-acceptance-gate.md +91 -0
- package/frontend/01-standards/accessibility-complete.md +3 -3
- package/frontend/01-standards/ui-states-and-resilient-data-fetching.md +97 -0
- package/high-quality-engineering-playbook.md +1 -1
- package/incident/02-playbooks/chaos-engineering-playbook.md +1 -1
- package/incident/postmortem-and-response-deep-dive.md +1 -1
- package/mobile/01-standards/flutter-complete.md +5 -5
- package/mobile/01-standards/react-native-complete.md +5 -5
- package/mobile/02-playbooks/mobile-performance.md +6 -6
- package/mobile/03-checklists/mobile-release-checklist.md +2 -2
- package/mobile/04-antipatterns/mobile-antipatterns.md +2 -2
- package/observability/01-standards/observability-and-slo-operations.md +88 -0
- package/observability/01-standards/observability-standards.md +2 -0
- package/operations/01-standards/cost-and-finops-engineering.md +84 -0
- package/operations/01-standards/production-readiness-review.md +103 -0
- package/operations/aiops-anomaly-detection.md +1 -1
- package/operations/capacity-planning.md +1 -1
- package/operations/chaos-engineering.md +1 -1
- package/operations/incident-command-system.md +1 -1
- package/operations/observability-complete.md +1 -1
- package/operations/slo-sli-playbook.md +1 -1
- package/operations/sre-operations-deep-dive.md +1 -1
- package/package.json +1 -1
- package/performance/01-standards/performance-budgets-and-load-testing.md +91 -0
- package/product/feature-prioritization-framework.md +1 -1
- package/product/kpi-and-metric-tree.md +1 -1
- package/product/product-discovery-and-prd-deep-dive.md +1 -1
- package/release-engineering/01-standards/feature-flag-lifecycle.md +92 -0
- package/release-engineering/01-standards/progressive-delivery-and-release.md +92 -0
- package/release-engineering/02-playbooks/release-rollback-and-recovery-playbook.md +99 -0
- package/release-engineering/03-checklists/release-rollback-readiness-checklist.md +61 -0
- package/release-engineering/04-antipatterns/release-antipatterns.md +63 -0
- package/security/01-standards/authorization-and-access-control.md +94 -0
- package/security/02-playbooks/incident-response-security-playbook.md +1 -1
- package/security/02-playbooks/penetration-testing-playbook.md +1 -1
- package/security/security-architecture-deep-dive.md +1 -1
- package/security/threat-modeling-stride-playbook.md +1 -1
- package/testing/01-standards/ci-test-gates-and-coverage.md +93 -0
- package/testing/01-standards/contract-testing-and-api-contracts.md +102 -0
- package/testing/01-standards/test-data-and-ephemeral-environments.md +105 -0
- package/testing/02-playbooks/e2e-testing-playbook.md +1 -1
- package/testing/risk-based-test-matrix.md +1 -1
- package/testing/testing-strategy-deep-dive.md +1 -1
|
@@ -1,1162 +1,99 @@
|
|
|
1
1
|
---
|
|
2
2
|
id: configuration-management
|
|
3
|
-
title:
|
|
3
|
+
title: 配置中心选型规范(按规模/生态/能力选配置中心,商业级必读)
|
|
4
4
|
domain: architecture
|
|
5
|
-
category:
|
|
6
|
-
difficulty:
|
|
7
|
-
tags: [
|
|
8
|
-
quality_score:
|
|
9
|
-
last_updated: 2026-06-
|
|
5
|
+
category: architecture
|
|
6
|
+
difficulty: advanced
|
|
7
|
+
tags: [config-center, configuration-management, selection, nacos, apollo, consul, spring-cloud-config, etcd, kv-store, dynamic-config, config-push, high-availability, 配置中心, 选型, 动态配置, 高可用, 商业级]
|
|
8
|
+
quality_score: 95
|
|
9
|
+
last_updated: 2026-06-29
|
|
10
10
|
---
|
|
11
|
-
#
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
-
|
|
68
|
-
-
|
|
69
|
-
-
|
|
70
|
-
-
|
|
71
|
-
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
nacos:
|
|
101
|
-
image: nacos/nacos-server:latest
|
|
102
|
-
environment:
|
|
103
|
-
MODE: standalone
|
|
104
|
-
SPRING_DATASOURCE_PLATFORM: mysql
|
|
105
|
-
MYSQL_SERVICE_HOST: nacos-mysql
|
|
106
|
-
MYSQL_SERVICE_PORT: 3306
|
|
107
|
-
MYSQL_SERVICE_DB_NAME: nacos
|
|
108
|
-
MYSQL_SERVICE_USER: root
|
|
109
|
-
MYSQL_SERVICE_PASSWORD: root
|
|
110
|
-
ports:
|
|
111
|
-
- "8848:8848"
|
|
112
|
-
depends_on:
|
|
113
|
-
- nacos-mysql
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
##### 客户端集成
|
|
117
|
-
```xml
|
|
118
|
-
<!-- Maven依赖 -->
|
|
119
|
-
<dependency>
|
|
120
|
-
<groupId>com.alibaba.cloud</groupId>
|
|
121
|
-
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
|
|
122
|
-
</dependency>
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
```yaml
|
|
126
|
-
# bootstrap.yml
|
|
127
|
-
spring:
|
|
128
|
-
application:
|
|
129
|
-
name: order-service
|
|
130
|
-
profiles:
|
|
131
|
-
active: dev
|
|
132
|
-
cloud:
|
|
133
|
-
nacos:
|
|
134
|
-
config:
|
|
135
|
-
server-addr: localhost:8848
|
|
136
|
-
namespace: dev
|
|
137
|
-
group: DEFAULT_GROUP
|
|
138
|
-
file-extension: yaml
|
|
139
|
-
shared-configs:
|
|
140
|
-
- data-id: common.yaml
|
|
141
|
-
group: DEFAULT_GROUP
|
|
142
|
-
refresh: true
|
|
143
|
-
extension-configs:
|
|
144
|
-
- data-id: redis.yaml
|
|
145
|
-
group: DEFAULT_GROUP
|
|
146
|
-
refresh: true
|
|
147
|
-
- data-id: mysql.yaml
|
|
148
|
-
group: DEFAULT_GROUP
|
|
149
|
-
refresh: true
|
|
150
|
-
refresh-enabled: true
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
```java
|
|
154
|
-
// 配置类
|
|
155
|
-
@RefreshScope
|
|
156
|
-
@Configuration
|
|
157
|
-
public class OrderConfig {
|
|
158
|
-
@Value("${order.timeout:3000}")
|
|
159
|
-
private int timeout;
|
|
160
|
-
|
|
161
|
-
@Value("${order.max-retry:3}")
|
|
162
|
-
private int maxRetry;
|
|
163
|
-
|
|
164
|
-
// 配置变更时自动刷新
|
|
165
|
-
public int getTimeout() {
|
|
166
|
-
return timeout;
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
// 配置监听
|
|
171
|
-
@Component
|
|
172
|
-
public class ConfigListener {
|
|
173
|
-
@NacosConfigListener(dataId = "order-service.yaml", groupId = "DEFAULT_GROUP")
|
|
174
|
-
public void onConfigChange(String newConfig) {
|
|
175
|
-
log.info("配置变更: {}", newConfig);
|
|
176
|
-
// 自定义处理逻辑
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
```
|
|
180
|
-
|
|
181
|
-
### Apollo
|
|
182
|
-
|
|
183
|
-
#### 架构
|
|
184
|
-
```
|
|
185
|
-
核心组件:
|
|
186
|
-
- Config Service: 配置读取、推送
|
|
187
|
-
- Admin Service: 配置管理
|
|
188
|
-
- Meta Server: 服务注册发现
|
|
189
|
-
- Portal: 管理界面
|
|
190
|
-
- Client: SDK
|
|
191
|
-
|
|
192
|
-
数据存储:
|
|
193
|
-
- MySQL(配置、审计日志)
|
|
194
|
-
- Eureka(服务发现)
|
|
195
|
-
```
|
|
196
|
-
|
|
197
|
-
#### 核心特性
|
|
198
|
-
```
|
|
199
|
-
优点:
|
|
200
|
-
- 统一配置管理平台
|
|
201
|
-
- 多环境多集群
|
|
202
|
-
- 灰度发布
|
|
203
|
-
- 配置版本管理
|
|
204
|
-
- 权限管理
|
|
205
|
-
- 审计日志
|
|
206
|
-
- 高性能(支持10万+客户端)
|
|
207
|
-
-携程开源,大规模生产验证
|
|
208
|
-
|
|
209
|
-
缺点:
|
|
210
|
-
- 架构复杂,部署成本高
|
|
211
|
-
- 学习曲线陡峭
|
|
212
|
-
- 运维成本高
|
|
213
|
-
|
|
214
|
-
适用场景:
|
|
215
|
-
- 大规模微服务(100+服务)
|
|
216
|
-
- 需要完善管理界面
|
|
217
|
-
- 强审计需求
|
|
218
|
-
- 企业级应用
|
|
219
|
-
```
|
|
220
|
-
|
|
221
|
-
#### 实现示例
|
|
222
|
-
|
|
223
|
-
##### 服务端部署
|
|
224
|
-
```yaml
|
|
225
|
-
# docker-compose.yml
|
|
226
|
-
version: '3.8'
|
|
227
|
-
services:
|
|
228
|
-
apollo-mysql:
|
|
229
|
-
image: mysql:8.0
|
|
230
|
-
environment:
|
|
231
|
-
MYSQL_ROOT_PASSWORD: root
|
|
232
|
-
volumes:
|
|
233
|
-
- ./sql:/docker-entrypoint-initdb.d
|
|
234
|
-
- ./mysql-data:/var/lib/mysql
|
|
235
|
-
|
|
236
|
-
apollo-configservice:
|
|
237
|
-
image: apolloconfig/apollo-configservice:latest
|
|
238
|
-
environment:
|
|
239
|
-
SPRING_DATASOURCE_URL: jdbc:mysql://apollo-mysql:3306/ApolloConfigDB
|
|
240
|
-
SPRING_DATASOURCE_USERNAME: root
|
|
241
|
-
SPRING_DATASOURCE_PASSWORD: root
|
|
242
|
-
ports:
|
|
243
|
-
- "8080:8080"
|
|
244
|
-
depends_on:
|
|
245
|
-
- apollo-mysql
|
|
246
|
-
|
|
247
|
-
apollo-adminservice:
|
|
248
|
-
image: apolloconfig/apollo-adminservice:latest
|
|
249
|
-
environment:
|
|
250
|
-
SPRING_DATASOURCE_URL: jdbc:mysql://apollo-mysql:3306/ApolloConfigDB
|
|
251
|
-
SPRING_DATASOURCE_USERNAME: root
|
|
252
|
-
SPRING_DATASOURCE_PASSWORD: root
|
|
253
|
-
ports:
|
|
254
|
-
- "8090:8090"
|
|
255
|
-
depends_on:
|
|
256
|
-
- apollo-mysql
|
|
257
|
-
|
|
258
|
-
apollo-portal:
|
|
259
|
-
image: apolloconfig/apollo-portal:latest
|
|
260
|
-
environment:
|
|
261
|
-
SPRING_DATASOURCE_URL: jdbc:mysql://apollo-mysql:3306/ApolloPortalDB
|
|
262
|
-
SPRING_DATASOURCE_USERNAME: root
|
|
263
|
-
SPRING_DATASOURCE_PASSWORD: root
|
|
264
|
-
APOLLO_PORTAL_ENVS: dev,pro
|
|
265
|
-
DEV_META: http://apollo-configservice:8080
|
|
266
|
-
PRO_META: http://apollo-configservice-pro:8080
|
|
267
|
-
ports:
|
|
268
|
-
- "8070:8070"
|
|
269
|
-
depends_on:
|
|
270
|
-
- apollo-mysql
|
|
271
|
-
```
|
|
272
|
-
|
|
273
|
-
##### 客户端集成
|
|
274
|
-
```xml
|
|
275
|
-
<!-- Maven依赖 -->
|
|
276
|
-
<dependency>
|
|
277
|
-
<groupId>com.ctrip.framework.apollo</groupId>
|
|
278
|
-
<artifactId>apollo-client</artifactId>
|
|
279
|
-
<version>2.1.0</version>
|
|
280
|
-
</dependency>
|
|
281
|
-
```
|
|
282
|
-
|
|
283
|
-
```properties
|
|
284
|
-
# application.properties
|
|
285
|
-
app.id=order-service
|
|
286
|
-
apollo.meta=http://localhost:8080
|
|
287
|
-
apollo.bootstrap.enabled=true
|
|
288
|
-
apollo.bootstrap.namespaces=application
|
|
289
|
-
apollo.autoUpdateInjectedSpringProperties=true
|
|
290
|
-
```
|
|
291
|
-
|
|
292
|
-
```java
|
|
293
|
-
// 配置类
|
|
294
|
-
@Configuration
|
|
295
|
-
@EnableApolloConfig
|
|
296
|
-
public class AppConfig {
|
|
297
|
-
@Bean
|
|
298
|
-
@RefreshScope
|
|
299
|
-
public OrderConfig orderConfig() {
|
|
300
|
-
return new OrderConfig();
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
@Component
|
|
305
|
-
public class OrderConfig {
|
|
306
|
-
@Value("${order.timeout:3000}")
|
|
307
|
-
private int timeout;
|
|
308
|
-
|
|
309
|
-
@ApolloConfigChangeListener
|
|
310
|
-
public void onChange(ConfigChangeEvent changeEvent) {
|
|
311
|
-
// 配置变更监听
|
|
312
|
-
for (String key : changeEvent.changedKeys()) {
|
|
313
|
-
ConfigChange change = changeEvent.getChange(key);
|
|
314
|
-
log.info("配置变更 - Key: {}, Old: {}, New: {}",
|
|
315
|
-
key, change.getOldValue(), change.getNewValue());
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
// 手动获取配置
|
|
321
|
-
@Service
|
|
322
|
-
public class OrderService {
|
|
323
|
-
@ApolloConfig
|
|
324
|
-
private Config config;
|
|
325
|
-
|
|
326
|
-
public void processOrder() {
|
|
327
|
-
Integer timeout = config.getIntProperty("order.timeout", 3000);
|
|
328
|
-
// 使用配置
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
```
|
|
332
|
-
|
|
333
|
-
### Consul
|
|
334
|
-
|
|
335
|
-
#### 核心特性
|
|
336
|
-
```
|
|
337
|
-
优点:
|
|
338
|
-
- 配置管理+服务发现一体化
|
|
339
|
-
- KV存储简单易用
|
|
340
|
-
- 多数据中心支持
|
|
341
|
-
- DNS接口
|
|
342
|
-
- 健康检查
|
|
343
|
-
- Go实现,性能好
|
|
344
|
-
|
|
345
|
-
缺点:
|
|
346
|
-
- 配置管理功能相对简单
|
|
347
|
-
- 缺乏版本管理
|
|
348
|
-
- 无Web管理界面(需第三方)
|
|
349
|
-
|
|
350
|
-
适用场景:
|
|
351
|
-
- 异构技术栈
|
|
352
|
-
- 多数据中心
|
|
353
|
-
- 简单配置需求
|
|
354
|
-
```
|
|
355
|
-
|
|
356
|
-
#### 实现示例
|
|
357
|
-
|
|
358
|
-
##### 服务端部署
|
|
359
|
-
```yaml
|
|
360
|
-
# docker-compose.yml
|
|
361
|
-
version: '3.8'
|
|
362
|
-
services:
|
|
363
|
-
consul:
|
|
364
|
-
image: consul:latest
|
|
365
|
-
ports:
|
|
366
|
-
- "8500:8500" # HTTP API
|
|
367
|
-
- "8600:8600/udp" # DNS
|
|
368
|
-
command: agent -server -bootstrap-expect=1 -ui -client=0.0.0.0
|
|
369
|
-
```
|
|
370
|
-
|
|
371
|
-
##### 客户端集成
|
|
372
|
-
```xml
|
|
373
|
-
<!-- Maven依赖 -->
|
|
374
|
-
<dependency>
|
|
375
|
-
<groupId>org.springframework.cloud</groupId>
|
|
376
|
-
<artifactId>spring-cloud-starter-consul-config</artifactId>
|
|
377
|
-
</dependency>
|
|
378
|
-
```
|
|
379
|
-
|
|
380
|
-
```yaml
|
|
381
|
-
# bootstrap.yml
|
|
382
|
-
spring:
|
|
383
|
-
application:
|
|
384
|
-
name: order-service
|
|
385
|
-
cloud:
|
|
386
|
-
consul:
|
|
387
|
-
host: localhost
|
|
388
|
-
port: 8500
|
|
389
|
-
config:
|
|
390
|
-
enabled: true
|
|
391
|
-
format: YAML
|
|
392
|
-
prefix: config
|
|
393
|
-
default-context: application
|
|
394
|
-
profile-separator: ','
|
|
395
|
-
data-key: data
|
|
396
|
-
watch:
|
|
397
|
-
enabled: true
|
|
398
|
-
delay: 1000
|
|
399
|
-
```
|
|
400
|
-
|
|
401
|
-
```java
|
|
402
|
-
// 配置类
|
|
403
|
-
@RefreshScope
|
|
404
|
-
@Configuration
|
|
405
|
-
@ConfigurationProperties(prefix = "order")
|
|
406
|
-
public class OrderConfig {
|
|
407
|
-
private int timeout = 3000;
|
|
408
|
-
private int maxRetry = 3;
|
|
409
|
-
|
|
410
|
-
// getters and setters
|
|
411
|
-
}
|
|
412
|
-
```
|
|
413
|
-
|
|
414
|
-
### Spring Cloud Config
|
|
415
|
-
|
|
416
|
-
#### 核心特性
|
|
417
|
-
```
|
|
418
|
-
优点:
|
|
419
|
-
- Spring Cloud原生
|
|
420
|
-
- Git版本管理
|
|
421
|
-
- 简单易用
|
|
422
|
-
- 与Spring生态无缝集成
|
|
423
|
-
|
|
424
|
-
缺点:
|
|
425
|
-
- 需要重启应用才能刷新配置(需配合Bus)
|
|
426
|
-
- 无管理界面
|
|
427
|
-
- 功能相对简单
|
|
428
|
-
|
|
429
|
-
适用场景:
|
|
430
|
-
- Spring Cloud生态
|
|
431
|
-
- 小型系统
|
|
432
|
-
- Git版本管理需求
|
|
433
|
-
```
|
|
434
|
-
|
|
435
|
-
#### 实现示例
|
|
436
|
-
|
|
437
|
-
##### 服务端
|
|
438
|
-
```xml
|
|
439
|
-
<!-- Maven依赖 -->
|
|
440
|
-
<dependency>
|
|
441
|
-
<groupId>org.springframework.cloud</groupId>
|
|
442
|
-
<artifactId>spring-cloud-config-server</artifactId>
|
|
443
|
-
</dependency>
|
|
444
|
-
```
|
|
445
|
-
|
|
446
|
-
```java
|
|
447
|
-
@SpringBootApplication
|
|
448
|
-
@EnableConfigServer
|
|
449
|
-
public class ConfigServerApplication {
|
|
450
|
-
public static void main(String[] args) {
|
|
451
|
-
SpringApplication.run(ConfigServerApplication.class, args);
|
|
452
|
-
}
|
|
453
|
-
}
|
|
454
|
-
```
|
|
455
|
-
|
|
456
|
-
```yaml
|
|
457
|
-
# application.yml
|
|
458
|
-
server:
|
|
459
|
-
port: 8888
|
|
460
|
-
|
|
461
|
-
spring:
|
|
462
|
-
cloud:
|
|
463
|
-
config:
|
|
464
|
-
server:
|
|
465
|
-
git:
|
|
466
|
-
uri: https://github.com/myorg/config-repo
|
|
467
|
-
search-paths:
|
|
468
|
-
- '{application}'
|
|
469
|
-
username: ${GIT_USERNAME}
|
|
470
|
-
password: ${GIT_PASSWORD}
|
|
471
|
-
encrypt:
|
|
472
|
-
enabled: true
|
|
473
|
-
```
|
|
474
|
-
|
|
475
|
-
##### 客户端
|
|
476
|
-
```xml
|
|
477
|
-
<!-- Maven依赖 -->
|
|
478
|
-
<dependency>
|
|
479
|
-
<groupId>org.springframework.cloud</groupId>
|
|
480
|
-
<artifactId>spring-cloud-starter-config</artifactId>
|
|
481
|
-
</dependency>
|
|
482
|
-
<dependency>
|
|
483
|
-
<groupId>org.springframework.cloud</groupId>
|
|
484
|
-
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
|
|
485
|
-
</dependency>
|
|
486
|
-
```
|
|
487
|
-
|
|
488
|
-
```yaml
|
|
489
|
-
# bootstrap.yml
|
|
490
|
-
spring:
|
|
491
|
-
application:
|
|
492
|
-
name: order-service
|
|
493
|
-
profiles:
|
|
494
|
-
active: dev
|
|
495
|
-
cloud:
|
|
496
|
-
config:
|
|
497
|
-
uri: http://localhost:8888
|
|
498
|
-
fail-fast: true
|
|
499
|
-
retry:
|
|
500
|
-
initial-interval: 1000
|
|
501
|
-
max-interval: 2000
|
|
502
|
-
max-attempts: 6
|
|
503
|
-
```
|
|
504
|
-
|
|
505
|
-
```java
|
|
506
|
-
@RefreshScope
|
|
507
|
-
@RestController
|
|
508
|
-
public class OrderController {
|
|
509
|
-
@Value("${order.timeout:3000}")
|
|
510
|
-
private int timeout;
|
|
511
|
-
|
|
512
|
-
@GetMapping("/timeout")
|
|
513
|
-
public int getTimeout() {
|
|
514
|
-
return timeout;
|
|
515
|
-
}
|
|
516
|
-
}
|
|
517
|
-
```
|
|
518
|
-
|
|
519
|
-
### Etcd
|
|
520
|
-
|
|
521
|
-
#### 核心特性
|
|
522
|
-
```
|
|
523
|
-
优点:
|
|
524
|
-
- 高性能KV存储
|
|
525
|
-
- 强一致性(Raft协议)
|
|
526
|
-
- Watch机制
|
|
527
|
-
- Kubernetes原生支持
|
|
528
|
-
- Go实现
|
|
529
|
-
|
|
530
|
-
缺点:
|
|
531
|
-
- 配置管理功能简单
|
|
532
|
-
- 无Web界面
|
|
533
|
-
- 需要自行实现高级功能
|
|
534
|
-
|
|
535
|
-
适用场景:
|
|
536
|
-
- Kubernetes环境
|
|
537
|
-
- Go技术栈
|
|
538
|
-
- 简单配置需求
|
|
539
|
-
```
|
|
540
|
-
|
|
541
|
-
#### 实现示例
|
|
542
|
-
|
|
543
|
-
```java
|
|
544
|
-
// Java客户端
|
|
545
|
-
public class EtcdConfigClient {
|
|
546
|
-
private final Client client;
|
|
547
|
-
|
|
548
|
-
public EtcdConfigClient(String endpoints) {
|
|
549
|
-
this.client = Client.builder()
|
|
550
|
-
.endpoints(endpoints.split(","))
|
|
551
|
-
.build();
|
|
552
|
-
}
|
|
553
|
-
|
|
554
|
-
public String getConfig(String key) throws Exception {
|
|
555
|
-
GetResponse response = client.getKVClient()
|
|
556
|
-
.get(ByteSequence.from(key, StandardCharsets.UTF_8))
|
|
557
|
-
.get();
|
|
558
|
-
|
|
559
|
-
if (response.getKvs().isEmpty()) {
|
|
560
|
-
return null;
|
|
561
|
-
}
|
|
562
|
-
|
|
563
|
-
return response.getKvs().get(0).getValue().toString(StandardCharsets.UTF_8);
|
|
564
|
-
}
|
|
565
|
-
|
|
566
|
-
public void watchConfig(String key, Consumer<String> listener) {
|
|
567
|
-
Watch.Watcher watcher = client.getWatchClient()
|
|
568
|
-
.watch(ByteSequence.from(key, StandardCharsets.UTF_8),
|
|
569
|
-
WatchOption.DEFAULT,
|
|
570
|
-
response -> {
|
|
571
|
-
for (WatchEvent event : response.getEvents()) {
|
|
572
|
-
String value = event.getKeyValue()
|
|
573
|
-
.getValue()
|
|
574
|
-
.toString(StandardCharsets.UTF_8);
|
|
575
|
-
listener.accept(value);
|
|
576
|
-
}
|
|
577
|
-
});
|
|
578
|
-
}
|
|
579
|
-
}
|
|
580
|
-
```
|
|
581
|
-
|
|
582
|
-
## 配置管理最佳实践
|
|
583
|
-
|
|
584
|
-
### 1. 配置分类
|
|
585
|
-
|
|
586
|
-
#### 按环境分类
|
|
587
|
-
```
|
|
588
|
-
开发环境(DEV):
|
|
589
|
-
- 本地开发配置
|
|
590
|
-
- 宽松的限流熔断
|
|
591
|
-
- 详细的日志
|
|
592
|
-
|
|
593
|
-
测试环境(TEST):
|
|
594
|
-
- 集成测试配置
|
|
595
|
-
- Mock外部服务
|
|
596
|
-
- 测试数据
|
|
597
|
-
|
|
598
|
-
预发环境(STAGING):
|
|
599
|
-
- 生产配置副本
|
|
600
|
-
- 真实外部服务(测试环境)
|
|
601
|
-
- 性能测试
|
|
602
|
-
|
|
603
|
-
生产环境(PROD):
|
|
604
|
-
- 生产配置
|
|
605
|
-
- 严格的限流熔断
|
|
606
|
-
- 关键日志
|
|
607
|
-
```
|
|
608
|
-
|
|
609
|
-
#### 按类型分类
|
|
610
|
-
```
|
|
611
|
-
基础设施配置:
|
|
612
|
-
- 数据库连接
|
|
613
|
-
- Redis连接
|
|
614
|
-
- 消息队列
|
|
615
|
-
- 日志配置
|
|
616
|
-
|
|
617
|
-
业务配置:
|
|
618
|
-
- 功能开关
|
|
619
|
-
- 业务规则
|
|
620
|
-
- 参数阈值
|
|
621
|
-
|
|
622
|
-
运营配置:
|
|
623
|
-
- 限流策略
|
|
624
|
-
- 熔断策略
|
|
625
|
-
- 降级策略
|
|
626
|
-
```
|
|
627
|
-
|
|
628
|
-
### 2. 配置结构设计
|
|
629
|
-
|
|
630
|
-
#### Nacos配置结构
|
|
631
|
-
```
|
|
632
|
-
命名空间(Namespace):
|
|
633
|
-
- dev: 开发环境
|
|
634
|
-
- test: 测试环境
|
|
635
|
-
- prod: 生产环境
|
|
636
|
-
|
|
637
|
-
分组(Group):
|
|
638
|
-
- DEFAULT_GROUP: 默认分组
|
|
639
|
-
- DATABASE_GROUP: 数据库配置
|
|
640
|
-
- REDIS_GROUP: Redis配置
|
|
641
|
-
- BUSINESS_GROUP: 业务配置
|
|
642
|
-
|
|
643
|
-
Data ID:
|
|
644
|
-
- order-service.yaml: 订单服务配置
|
|
645
|
-
- order-service-dev.yaml: 订单服务开发环境配置
|
|
646
|
-
- common.yaml: 公共配置
|
|
647
|
-
```
|
|
648
|
-
|
|
649
|
-
#### Apollo配置结构
|
|
650
|
-
```
|
|
651
|
-
AppId:
|
|
652
|
-
- order-service
|
|
653
|
-
- inventory-service
|
|
654
|
-
- payment-service
|
|
655
|
-
|
|
656
|
-
环境(Env):
|
|
657
|
-
- DEV
|
|
658
|
-
- UAT
|
|
659
|
-
- PRO
|
|
660
|
-
|
|
661
|
-
集群(Cluster):
|
|
662
|
-
- default: 默认集群
|
|
663
|
-
- shanghai: 上海集群
|
|
664
|
-
- beijing: 北京集群
|
|
665
|
-
|
|
666
|
-
命名空间(Namespace):
|
|
667
|
-
- application: 默认命名空间
|
|
668
|
-
- database.yaml: 数据库配置
|
|
669
|
-
- redis.yaml: Redis配置
|
|
670
|
-
```
|
|
671
|
-
|
|
672
|
-
### 3. 配置模板
|
|
673
|
-
|
|
674
|
-
#### application.yaml模板
|
|
675
|
-
```yaml
|
|
676
|
-
# 基础配置
|
|
677
|
-
server:
|
|
678
|
-
port: 8080
|
|
679
|
-
|
|
680
|
-
spring:
|
|
681
|
-
application:
|
|
682
|
-
name: ${APP_NAME}
|
|
683
|
-
profiles:
|
|
684
|
-
active: ${ACTIVE_PROFILE:dev}
|
|
685
|
-
|
|
686
|
-
# 日志配置
|
|
687
|
-
logging:
|
|
688
|
-
level:
|
|
689
|
-
root: INFO
|
|
690
|
-
com.example: DEBUG
|
|
691
|
-
file:
|
|
692
|
-
name: /var/log/${spring.application.name}/${spring.application.name}.log
|
|
693
|
-
pattern:
|
|
694
|
-
file: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"
|
|
695
|
-
|
|
696
|
-
# 监控配置
|
|
697
|
-
management:
|
|
698
|
-
endpoints:
|
|
699
|
-
web:
|
|
700
|
-
exposure:
|
|
701
|
-
include: health,info,metrics,prometheus
|
|
702
|
-
metrics:
|
|
703
|
-
tags:
|
|
704
|
-
application: ${spring.application.name}
|
|
705
|
-
environment: ${spring.profiles.active}
|
|
706
|
-
|
|
707
|
-
# 业务配置(从配置中心读取)
|
|
708
|
-
order:
|
|
709
|
-
timeout: ${ORDER_TIMEOUT:3000}
|
|
710
|
-
max-retry: ${ORDER_MAX_RETRY:3}
|
|
711
|
-
enable-cache: ${ORDER_ENABLE_CACHE:true}
|
|
712
|
-
```
|
|
713
|
-
|
|
714
|
-
#### database.yaml模板
|
|
715
|
-
```yaml
|
|
716
|
-
spring:
|
|
717
|
-
datasource:
|
|
718
|
-
url: jdbc:mysql://${DB_HOST:localhost}:${DB_PORT:3306}/${DB_NAME:order_db}?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
|
|
719
|
-
username: ${DB_USERNAME:root}
|
|
720
|
-
password: ${DB_PASSWORD:root}
|
|
721
|
-
driver-class-name: com.mysql.cj.jdbc.Driver
|
|
722
|
-
hikari:
|
|
723
|
-
minimum-idle: 5
|
|
724
|
-
maximum-pool-size: 20
|
|
725
|
-
idle-timeout: 600000
|
|
726
|
-
max-lifetime: 1800000
|
|
727
|
-
connection-timeout: 30000
|
|
728
|
-
pool-name: ${spring.application.name}-HikariCP
|
|
729
|
-
```
|
|
730
|
-
|
|
731
|
-
### 4. 敏感配置加密
|
|
732
|
-
|
|
733
|
-
#### Jasypt加密
|
|
734
|
-
```xml
|
|
735
|
-
<!-- Maven依赖 -->
|
|
736
|
-
<dependency>
|
|
737
|
-
<groupId>com.github.ulisesbocchio</groupId>
|
|
738
|
-
<artifactId>jasypt-spring-boot-starter</artifactId>
|
|
739
|
-
<version>3.0.5</version>
|
|
740
|
-
</dependency>
|
|
741
|
-
```
|
|
742
|
-
|
|
743
|
-
```yaml
|
|
744
|
-
# application.yml
|
|
745
|
-
jasypt:
|
|
746
|
-
encryptor:
|
|
747
|
-
password: ${JASYPT_ENCRYPTOR_PASSWORD}
|
|
748
|
-
algorithm: PBEWithMD5AndDES
|
|
749
|
-
|
|
750
|
-
spring:
|
|
751
|
-
datasource:
|
|
752
|
-
username: root
|
|
753
|
-
password: ENC(加密后的密码)
|
|
754
|
-
```
|
|
755
|
-
|
|
756
|
-
```java
|
|
757
|
-
// 使用
|
|
758
|
-
@SpringBootApplication
|
|
759
|
-
@EnableEncryptableProperties
|
|
760
|
-
public class Application {
|
|
761
|
-
public static void main(String[] args) {
|
|
762
|
-
SpringApplication.run(Application.class, args);
|
|
763
|
-
}
|
|
764
|
-
}
|
|
765
|
-
```
|
|
766
|
-
|
|
767
|
-
#### Nacos加密
|
|
768
|
-
```java
|
|
769
|
-
// 自定义配置解密
|
|
770
|
-
@Component
|
|
771
|
-
public class DecryptConfigListener {
|
|
772
|
-
@NacosConfigListener(dataId = "database.yaml")
|
|
773
|
-
public void onReceive(String config) {
|
|
774
|
-
String decrypted = decryptConfig(config);
|
|
775
|
-
// 更新配置
|
|
776
|
-
}
|
|
777
|
-
|
|
778
|
-
private String decryptConfig(String encrypted) {
|
|
779
|
-
// 解密逻辑
|
|
780
|
-
return AES.decrypt(encrypted, secretKey);
|
|
781
|
-
}
|
|
782
|
-
}
|
|
783
|
-
```
|
|
784
|
-
|
|
785
|
-
### 5. 配置热更新
|
|
786
|
-
|
|
787
|
-
#### @RefreshScope
|
|
788
|
-
```java
|
|
789
|
-
@RefreshScope
|
|
790
|
-
@Configuration
|
|
791
|
-
@ConfigurationProperties(prefix = "rate.limit")
|
|
792
|
-
public class RateLimitConfig {
|
|
793
|
-
private int qps = 100;
|
|
794
|
-
private int burst = 200;
|
|
795
|
-
|
|
796
|
-
// getters and setters
|
|
797
|
-
}
|
|
798
|
-
|
|
799
|
-
@RefreshScope
|
|
800
|
-
@Service
|
|
801
|
-
public class OrderService {
|
|
802
|
-
@Value("${order.timeout}")
|
|
803
|
-
private int timeout;
|
|
804
|
-
|
|
805
|
-
public void processOrder() {
|
|
806
|
-
// 使用最新配置
|
|
807
|
-
}
|
|
808
|
-
}
|
|
809
|
-
```
|
|
810
|
-
|
|
811
|
-
#### 配置变更监听
|
|
812
|
-
```java
|
|
813
|
-
@Component
|
|
814
|
-
@Slf4j
|
|
815
|
-
public class ConfigChangeHandler {
|
|
816
|
-
@ApolloConfigChangeListener
|
|
817
|
-
public void handleConfigChange(ConfigChangeEvent event) {
|
|
818
|
-
for (String key : event.changedKeys()) {
|
|
819
|
-
ConfigChange change = event.getChange(key);
|
|
820
|
-
|
|
821
|
-
log.info("配置变更: {} - {} -> {}",
|
|
822
|
-
key,
|
|
823
|
-
change.getOldValue(),
|
|
824
|
-
change.getNewValue());
|
|
825
|
-
|
|
826
|
-
// 根据配置类型处理
|
|
827
|
-
if (key.startsWith("rate.limit.")) {
|
|
828
|
-
handleRateLimitChange(key, change);
|
|
829
|
-
} else if (key.startsWith("feature.toggle.")) {
|
|
830
|
-
handleFeatureToggleChange(key, change);
|
|
831
|
-
}
|
|
832
|
-
}
|
|
833
|
-
}
|
|
834
|
-
|
|
835
|
-
private void handleRateLimitChange(String key, ConfigChange change) {
|
|
836
|
-
// 更新限流配置
|
|
837
|
-
rateLimiter.updateConfig(key, change.getNewValue());
|
|
838
|
-
}
|
|
839
|
-
|
|
840
|
-
private void handleFeatureToggleChange(String key, ConfigChange change) {
|
|
841
|
-
// 更新功能开关
|
|
842
|
-
featureToggle.update(key, Boolean.parseBoolean(change.getNewValue()));
|
|
843
|
-
}
|
|
844
|
-
}
|
|
845
|
-
```
|
|
846
|
-
|
|
847
|
-
### 6. 配置版本管理
|
|
848
|
-
|
|
849
|
-
#### Git集成(Spring Cloud Config)
|
|
850
|
-
```bash
|
|
851
|
-
# 配置仓库结构
|
|
852
|
-
config-repo/
|
|
853
|
-
├── application.yml # 公共配置
|
|
854
|
-
├── application-dev.yml # 开发环境
|
|
855
|
-
├── application-prod.yml # 生产环境
|
|
856
|
-
├── order-service.yml # 订单服务配置
|
|
857
|
-
├── order-service-dev.yml
|
|
858
|
-
├── order-service-prod.yml
|
|
859
|
-
└── database.yml # 数据库配置
|
|
860
|
-
```
|
|
861
|
-
|
|
862
|
-
#### Apollo版本管理
|
|
863
|
-
```sql
|
|
864
|
-
-- 查询配置历史
|
|
865
|
-
SELECT
|
|
866
|
-
NamespaceName,
|
|
867
|
-
Key,
|
|
868
|
-
Value,
|
|
869
|
-
Comment,
|
|
870
|
-
DataChange_CreatedBy,
|
|
871
|
-
DataChange_CreatedTime,
|
|
872
|
-
DataChange_LastModifiedBy,
|
|
873
|
-
DataChange_LastTime
|
|
874
|
-
FROM Item
|
|
875
|
-
WHERE AppId = 'order-service'
|
|
876
|
-
AND NamespaceName = 'application'
|
|
877
|
-
ORDER BY DataChange_LastTime DESC;
|
|
878
|
-
|
|
879
|
-
-- 回滚配置
|
|
880
|
-
-- 通过Portal界面操作
|
|
881
|
-
```
|
|
882
|
-
|
|
883
|
-
### 7. 灰度发布配置
|
|
884
|
-
|
|
885
|
-
#### Nacos灰度发布
|
|
886
|
-
```yaml
|
|
887
|
-
# order-service.yaml(主配置)
|
|
888
|
-
order:
|
|
889
|
-
feature:
|
|
890
|
-
new-algorithm: false
|
|
891
|
-
|
|
892
|
-
# order-service-gray.yaml(灰度配置)
|
|
893
|
-
order:
|
|
894
|
-
feature:
|
|
895
|
-
new-algorithm: true
|
|
896
|
-
|
|
897
|
-
# 应用配置
|
|
898
|
-
spring:
|
|
899
|
-
cloud:
|
|
900
|
-
nacos:
|
|
901
|
-
config:
|
|
902
|
-
shared-configs:
|
|
903
|
-
- data-id: order-service.yaml
|
|
904
|
-
- data-id: order-service-gray.yaml
|
|
905
|
-
refresh: true
|
|
906
|
-
```
|
|
907
|
-
|
|
908
|
-
#### Apollo灰度发布
|
|
909
|
-
```java
|
|
910
|
-
// 通过Apollo Portal配置灰度规则
|
|
911
|
-
// 1. 创建灰度配置
|
|
912
|
-
// 2. 配置灰度规则(IP、AppId、标签)
|
|
913
|
-
// 3. 发布灰度配置
|
|
914
|
-
// 4. 监控灰度效果
|
|
915
|
-
// 5. 全量发布或回滚
|
|
916
|
-
```
|
|
917
|
-
|
|
918
|
-
### 8. 配置审计
|
|
919
|
-
|
|
920
|
-
#### 审计日志
|
|
921
|
-
```java
|
|
922
|
-
@Component
|
|
923
|
-
public class ConfigAuditLogger {
|
|
924
|
-
@Autowired
|
|
925
|
-
private AuditLogRepository auditLogRepository;
|
|
926
|
-
|
|
927
|
-
@ApolloConfigChangeListener
|
|
928
|
-
public void auditConfigChange(ConfigChangeEvent event) {
|
|
929
|
-
for (String key : event.changedKeys()) {
|
|
930
|
-
ConfigChange change = event.getChange(key);
|
|
931
|
-
|
|
932
|
-
AuditLog log = new AuditLog();
|
|
933
|
-
log.setAppId("order-service");
|
|
934
|
-
log.setConfigKey(key);
|
|
935
|
-
log.setOldValue(change.getOldValue());
|
|
936
|
-
log.setNewValue(change.getNewValue());
|
|
937
|
-
log.setOperator(getCurrentUser());
|
|
938
|
-
log.setOperationTime(LocalDateTime.now());
|
|
939
|
-
log.setClientIp(getClientIp());
|
|
940
|
-
|
|
941
|
-
auditLogRepository.save(log);
|
|
942
|
-
}
|
|
943
|
-
}
|
|
944
|
-
}
|
|
945
|
-
```
|
|
946
|
-
|
|
947
|
-
## 配置中心高可用
|
|
948
|
-
|
|
949
|
-
### 1. 集群部署
|
|
950
|
-
|
|
951
|
-
#### Nacos集群
|
|
952
|
-
```yaml
|
|
953
|
-
# nacos-cluster.conf
|
|
954
|
-
node1:8848
|
|
955
|
-
node2:8848
|
|
956
|
-
node3:8848
|
|
957
|
-
|
|
958
|
-
# application.properties
|
|
959
|
-
nacos.inetutils.ip-address=节点IP
|
|
960
|
-
```
|
|
961
|
-
|
|
962
|
-
#### Apollo集群
|
|
963
|
-
```yaml
|
|
964
|
-
# 多机房部署
|
|
965
|
-
apollo-configservice-sh: 上海
|
|
966
|
-
apollo-configservice-bj: 北京
|
|
967
|
-
|
|
968
|
-
# 客户端配置
|
|
969
|
-
apollo.meta=http://configservice-sh:8080,http://configservice-bj:8080
|
|
970
|
-
```
|
|
971
|
-
|
|
972
|
-
### 2. 数据库高可用
|
|
973
|
-
|
|
974
|
-
```yaml
|
|
975
|
-
# MySQL主从
|
|
976
|
-
spring:
|
|
977
|
-
datasource:
|
|
978
|
-
master:
|
|
979
|
-
url: jdbc:mysql://master:3306/nacos
|
|
980
|
-
username: root
|
|
981
|
-
password: root
|
|
982
|
-
slave:
|
|
983
|
-
url: jdbc:mysql://slave:3306/nacos
|
|
984
|
-
username: root
|
|
985
|
-
password: root
|
|
986
|
-
```
|
|
987
|
-
|
|
988
|
-
### 3. 客户端容错
|
|
989
|
-
|
|
990
|
-
```java
|
|
991
|
-
// 本地缓存
|
|
992
|
-
@Configuration
|
|
993
|
-
public class ConfigCacheConfig {
|
|
994
|
-
@Bean
|
|
995
|
-
public ConfigCache configCache() {
|
|
996
|
-
return new LocalFileConfigCache();
|
|
997
|
-
}
|
|
998
|
-
}
|
|
999
|
-
|
|
1000
|
-
public class LocalFileConfigCache {
|
|
1001
|
-
private static final String CACHE_DIR = "/var/cache/config/";
|
|
1002
|
-
|
|
1003
|
-
public void save(String key, String value) {
|
|
1004
|
-
String filePath = CACHE_DIR + key + ".cache";
|
|
1005
|
-
Files.writeString(Path.of(filePath), value);
|
|
1006
|
-
}
|
|
1007
|
-
|
|
1008
|
-
public String load(String key) {
|
|
1009
|
-
String filePath = CACHE_DIR + key + ".cache";
|
|
1010
|
-
if (Files.exists(Path.of(filePath))) {
|
|
1011
|
-
return Files.readString(Path.of(filePath));
|
|
1012
|
-
}
|
|
1013
|
-
return null;
|
|
1014
|
-
}
|
|
1015
|
-
}
|
|
1016
|
-
```
|
|
1017
|
-
|
|
1018
|
-
## 配置管理工具
|
|
1019
|
-
|
|
1020
|
-
### 1. 配置校验
|
|
1021
|
-
|
|
1022
|
-
```java
|
|
1023
|
-
@Component
|
|
1024
|
-
public class ConfigValidator {
|
|
1025
|
-
@PostConstruct
|
|
1026
|
-
public void validateConfig() {
|
|
1027
|
-
validateDatabaseConfig();
|
|
1028
|
-
validateRedisConfig();
|
|
1029
|
-
validateBusinessConfig();
|
|
1030
|
-
}
|
|
1031
|
-
|
|
1032
|
-
private void validateDatabaseConfig() {
|
|
1033
|
-
String url = environment.getProperty("spring.datasource.url");
|
|
1034
|
-
if (url == null || url.isEmpty()) {
|
|
1035
|
-
throw new IllegalStateException("数据库URL未配置");
|
|
1036
|
-
}
|
|
1037
|
-
|
|
1038
|
-
int maxPoolSize = environment.getProperty(
|
|
1039
|
-
"spring.datasource.hikari.maximum-pool-size",
|
|
1040
|
-
Integer.class,
|
|
1041
|
-
20
|
|
1042
|
-
);
|
|
1043
|
-
if (maxPoolSize < 1 || maxPoolSize > 100) {
|
|
1044
|
-
throw new IllegalStateException(
|
|
1045
|
-
"数据库连接池大小配置错误: " + maxPoolSize
|
|
1046
|
-
);
|
|
1047
|
-
}
|
|
1048
|
-
}
|
|
1049
|
-
}
|
|
1050
|
-
```
|
|
1051
|
-
|
|
1052
|
-
### 2. 配置迁移工具
|
|
1053
|
-
|
|
1054
|
-
```java
|
|
1055
|
-
public class ConfigMigrationTool {
|
|
1056
|
-
public void migrateFromPropertiesToYaml() {
|
|
1057
|
-
// 读取.properties文件
|
|
1058
|
-
Properties props = loadProperties("application.properties");
|
|
1059
|
-
|
|
1060
|
-
// 转换为YAML
|
|
1061
|
-
Map<String, Object> configMap = new HashMap<>();
|
|
1062
|
-
props.forEach((key, value) -> {
|
|
1063
|
-
String[] keys = key.toString().split("\\.");
|
|
1064
|
-
Map<String, Object> current = configMap;
|
|
1065
|
-
for (int i = 0; i < keys.length - 1; i++) {
|
|
1066
|
-
current = (Map<String, Object>)
|
|
1067
|
-
current.computeIfAbsent(keys[i], k -> new HashMap<>());
|
|
1068
|
-
}
|
|
1069
|
-
current.put(keys[keys.length - 1], value);
|
|
1070
|
-
});
|
|
1071
|
-
|
|
1072
|
-
// 写入YAML文件
|
|
1073
|
-
Yaml yaml = new Yaml();
|
|
1074
|
-
yaml.dump(configMap, new FileWriter("application.yaml"));
|
|
1075
|
-
}
|
|
1076
|
-
}
|
|
1077
|
-
```
|
|
1078
|
-
|
|
1079
|
-
### 3. 配置对比工具
|
|
1080
|
-
|
|
1081
|
-
```java
|
|
1082
|
-
public class ConfigDiffTool {
|
|
1083
|
-
public List<ConfigDiff> diff(String env1, String env2) {
|
|
1084
|
-
Map<String, String> config1 = loadConfig(env1);
|
|
1085
|
-
Map<String, String> config2 = loadConfig(env2);
|
|
1086
|
-
|
|
1087
|
-
List<ConfigDiff> diffs = new ArrayList<>();
|
|
1088
|
-
|
|
1089
|
-
// 查找新增配置
|
|
1090
|
-
config2.forEach((key, value) -> {
|
|
1091
|
-
if (!config1.containsKey(key)) {
|
|
1092
|
-
diffs.add(new ConfigDiff(key, null, value, "ADDED"));
|
|
1093
|
-
}
|
|
1094
|
-
});
|
|
1095
|
-
|
|
1096
|
-
// 查找删除配置
|
|
1097
|
-
config1.forEach((key, value) -> {
|
|
1098
|
-
if (!config2.containsKey(key)) {
|
|
1099
|
-
diffs.add(new ConfigDiff(key, value, null, "DELETED"));
|
|
1100
|
-
}
|
|
1101
|
-
});
|
|
1102
|
-
|
|
1103
|
-
// 查找修改配置
|
|
1104
|
-
config1.forEach((key, value1) -> {
|
|
1105
|
-
String value2 = config2.get(key);
|
|
1106
|
-
if (value2 != null && !value1.equals(value2)) {
|
|
1107
|
-
diffs.add(new ConfigDiff(key, value1, value2, "MODIFIED"));
|
|
1108
|
-
}
|
|
1109
|
-
});
|
|
1110
|
-
|
|
1111
|
-
return diffs;
|
|
1112
|
-
}
|
|
1113
|
-
}
|
|
1114
|
-
```
|
|
1115
|
-
|
|
1116
|
-
## 选型建议
|
|
1117
|
-
|
|
1118
|
-
### 场景对比
|
|
1119
|
-
```
|
|
1120
|
-
Nacos:
|
|
1121
|
-
- Spring Cloud Alibaba生态
|
|
1122
|
-
- 配置管理+服务发现一体化
|
|
1123
|
-
- 中小型系统(10-100服务)
|
|
1124
|
-
- 国内环境
|
|
1125
|
-
|
|
1126
|
-
Apollo:
|
|
1127
|
-
- 大规模微服务(100+服务)
|
|
1128
|
-
- 需要完善管理界面
|
|
1129
|
-
- 强审计需求
|
|
1130
|
-
- 企业级应用
|
|
1131
|
-
|
|
1132
|
-
Consul:
|
|
1133
|
-
- 异构技术栈
|
|
1134
|
-
- 多数据中心
|
|
1135
|
-
- 简单配置需求
|
|
1136
|
-
- Go生态
|
|
1137
|
-
|
|
1138
|
-
Spring Cloud Config:
|
|
1139
|
-
- Spring Cloud生态
|
|
1140
|
-
- Git版本管理需求
|
|
1141
|
-
- 小型系统
|
|
1142
|
-
- 简单场景
|
|
1143
|
-
|
|
1144
|
-
Etcd:
|
|
1145
|
-
- Kubernetes环境
|
|
1146
|
-
- Go技术栈
|
|
1147
|
-
- 简单配置需求
|
|
1148
|
-
```
|
|
1149
|
-
|
|
1150
|
-
## 参考资源
|
|
1151
|
-
|
|
1152
|
-
### 官方文档
|
|
1153
|
-
- Nacos: https://nacos.io/
|
|
1154
|
-
- Apollo: https://www.apolloconfig.com/
|
|
1155
|
-
- Consul: https://www.consul.io/
|
|
1156
|
-
- Spring Cloud Config: https://spring.io/projects/spring-cloud-config
|
|
1157
|
-
- Etcd: https://etcd.io/
|
|
1158
|
-
|
|
1159
|
-
### 最佳实践
|
|
1160
|
-
- 《微服务配置管理》
|
|
1161
|
-
- 12-Factor App配置原则
|
|
1162
|
-
- Spring Cloud配置管理指南
|
|
11
|
+
# 配置中心选型规范(商业级必读)
|
|
12
|
+
|
|
13
|
+
> 配置中心负责把配置**集中存储、动态下发、版本管理、环境隔离、变更审计**。选型选错的代价很高:上了重型平台却只用到一成能力、徒增运维面;或选了过轻的方案,到了大规模才发现没有审计、没有灰度、没有管理界面,被迫迁移。
|
|
14
|
+
> 本规范只解决**"选哪个配置中心"以及"接入时要确认什么"**。**配置本身怎么治理**(配置即代码、环境对等、启动即校验、密钥分离、配置漂移)是另一层纪律,见 `architecture/01-standards/configuration-and-environment-management`,本文不重复——那是无论选哪个产品都必须遵守的;本文是在那套纪律之上帮你**把承载它的产品选对**。
|
|
15
|
+
|
|
16
|
+
## 1. 先判断你到底需不需要配置中心
|
|
17
|
+
|
|
18
|
+
| 场景 | 建议 |
|
|
19
|
+
|---|---|
|
|
20
|
+
| 单体/少量服务、配置变更不频繁 | 环境变量 + 配置文件 + IaC 足够,**别为它上一套中间件** |
|
|
21
|
+
| 多服务、需要动态下发/灰度/审计/统一管理 | 引入配置中心 |
|
|
22
|
+
| 已有服务发现/KV 基础设施,配置需求简单 | 复用既有 KV,别再叠一套配置平台 |
|
|
23
|
+
|
|
24
|
+
判据:配置中心解决的是**规模化下的集中治理与动态下发**。没有这个痛点,引入它只是增加故障点与运维负担。
|
|
25
|
+
|
|
26
|
+
## 2. 核心能力维度(拿这几条去套候选产品)
|
|
27
|
+
|
|
28
|
+
| 能力 | 为什么重要 | 选型时确认 |
|
|
29
|
+
|---|---|---|
|
|
30
|
+
| 动态下发 | 改配置不重启、秒级生效 | 推送时延、是否长轮询/watch、客户端如何热更 |
|
|
31
|
+
| 环境/租户隔离 | dev/staging/prod 与多租户互不串 | 命名空间/分组/集群模型是否清晰 |
|
|
32
|
+
| 版本与回滚 | 配置变更可追溯、可一键回退 | 是否有历史版本与回滚,回滚是否即时 |
|
|
33
|
+
| 灰度发布 | 高风险配置先小范围验证 | 是否支持按实例/标签灰度 + 监控 |
|
|
34
|
+
| 权限与审计 | 谁改了什么、能不能改 | 是否有 RBAC、变更审计日志 |
|
|
35
|
+
| 管理界面 | 大规模下的可操作性 | 是否自带 UI,还是要自行搭建 |
|
|
36
|
+
| 高可用 | 配置中心挂了不能拖垮业务 | 集群模式、客户端本地缓存容错 |
|
|
37
|
+
| 生态契合 | 接入成本与长期维护 | 与现有技术栈/框架的原生集成度 |
|
|
38
|
+
|
|
39
|
+
## 3. 候选产品定位与选型矩阵
|
|
40
|
+
|
|
41
|
+
下面按"能力档位"而非品牌站队来描述,落地时对号入座:
|
|
42
|
+
|
|
43
|
+
| 类型 | 能力画像 | 适合 | 代价 |
|
|
44
|
+
|---|---|---|---|
|
|
45
|
+
| 一体化配置+服务发现(中量级) | 动态下发、命名空间隔离、回滚、灰度、自带 UI;配置与服务发现一体 | 主流微服务规模、希望配置与注册中心合一、要中文友好生态 | 超大规模下性能与精细治理弱于重型平台 |
|
|
46
|
+
| 企业级配置平台(重量级) | 完整环境/集群/命名空间模型、强权限、强审计、灰度、高客户端承载 | 大规模微服务(上百服务)、强审计与管理界面刚需的企业 | 组件多、部署与运维成本高、学习曲线陡 |
|
|
47
|
+
| 通用 KV + 服务发现 | KV 存储 + 健康检查 + 多数据中心 + watch;配置功能偏基础 | 异构技术栈、多数据中心、配置需求简单 | 缺版本管理与配置 UI,高级能力要自建 |
|
|
48
|
+
| 框架原生 + Git 配置 | 以 Git 为存储、天然版本管理、与某生态无缝;改动靠 Git 评审 | 已重度使用该框架生态、想用 Git 做配置版本与评审、规模不大 | 动态刷新需配合消息总线,无管理界面,功能基础 |
|
|
49
|
+
| 强一致 KV(编排底座同款) | 高性能强一致 KV + watch;多作为编排/协调底座 | 容器编排环境、需要强一致协调、团队能自建上层能力 | 纯做应用配置中心偏底层,管理/版本/灰度要自己补 |
|
|
50
|
+
|
|
51
|
+
### 选型决策树(按主诉求倒推)
|
|
52
|
+
|
|
53
|
+
| 主诉求 | 倾向选择 |
|
|
54
|
+
|---|---|
|
|
55
|
+
| 配置 + 服务发现一体、生态友好、规模中等 | 一体化配置+服务发现(中量级) |
|
|
56
|
+
| 上百服务、强审计 + 完善管理界面是硬需求 | 企业级配置平台(重量级) |
|
|
57
|
+
| 异构栈 / 多数据中心 / 配置需求简单 | 通用 KV + 服务发现 |
|
|
58
|
+
| 已绑定某框架生态、想用 Git 管配置版本 | 框架原生 + Git 配置 |
|
|
59
|
+
| 已在容器编排环境、愿意自建上层能力 | 强一致 KV(编排底座同款) |
|
|
60
|
+
|
|
61
|
+
**反推一句**:能力够用前提下选**运维最轻、与现有栈最贴**的;别为"将来可能用到"的灰度/审计提前背上重型平台的运维负担——真到那一步再迁移的成本,往往低于一直养一套用不满的平台。
|
|
62
|
+
|
|
63
|
+
## 4. 接入时必须确认的工程点
|
|
64
|
+
|
|
65
|
+
选定产品后,接入阶段这几项不确认就会埋雷:
|
|
66
|
+
|
|
67
|
+
- **来源优先级唯一**:配置中心的值与本地默认值/环境变量的覆盖顺序要确定且文档化,同一个键绝不允许多处都"可能生效"(细则见配置与环境管理规范)。
|
|
68
|
+
- **客户端本地缓存容错**:配置中心**临时不可用**时,应用必须能用本地缓存的最后一次良好配置启动/运行,不能因为配置中心抖动就全线起不来——配置中心不可成为新的单点。
|
|
69
|
+
- **热更新要安全**:支持动态刷新的配置,变更后要有校验与生效确认;不可让一个错值在无校验下瞬间打到全量(高风险配置走灰度)。
|
|
70
|
+
- **密钥不混入**:普通配置与密钥分两套,密钥走密钥管理服务,**不要**把口令/私钥塞进配置中心当普通项明文存(见 `security/secrets-management`)。
|
|
71
|
+
- **变更可审计可回滚**:开启变更审计(谁/何时/把哪个键从什么改成什么),确认回滚是否即时可用。
|
|
72
|
+
- **高可用部署**:生产用集群模式,存储层(若依赖数据库)做高可用;演练"配置中心宕机"下业务是否仍可启动与运行。
|
|
73
|
+
|
|
74
|
+
## 5. 高可用与容错基线
|
|
75
|
+
|
|
76
|
+
- **集群而非单点**:生产环境配置中心多节点部署,避免单实例故障拖垮全局。
|
|
77
|
+
- **存储层高可用**:依赖数据库的方案,数据库做主从/多副本;纯 KV 方案确认其一致性协议与多副本。
|
|
78
|
+
- **客户端降级**:客户端持久化最后一次良好配置,配置中心不可达时**降级用本地缓存**,并告警,不阻塞业务。
|
|
79
|
+
- **变更与制品绑定**:每次部署记录"制品版本 + 配置版本",出事可精确反查组合(呼应配置漂移治理)。
|
|
80
|
+
|
|
81
|
+
## 6. 反模式(出现即不合格)
|
|
82
|
+
|
|
83
|
+
1. **杀鸡用牛刀**:少量服务、配置几乎不变,却上一套重型配置平台徒增故障点与运维负担。
|
|
84
|
+
2. **能力错配**:选了过轻的方案,规模上来后没有审计/灰度/管理界面,被迫紧急迁移。
|
|
85
|
+
3. **配置中心成单点**:客户端无本地缓存容错,配置中心一抖动业务全线起不来。
|
|
86
|
+
4. **密钥当普通配置存**:把口令/私钥明文塞进配置中心,泄露面放大。
|
|
87
|
+
5. **热更新无校验**:错配置无启动/变更校验,瞬间全量生效打挂线上。
|
|
88
|
+
6. **来源含糊**:配置中心值与环境变量/默认值覆盖顺序不清,实际取了哪个值靠猜。
|
|
89
|
+
7. **无审计无回滚**:控制台裸改、无变更记录、无法回退。
|
|
90
|
+
8. **为"将来"提前背重型平台**:用不到的能力天天养着,运维成本远超收益。
|
|
91
|
+
|
|
92
|
+
## 7. 最低交付 checklist
|
|
93
|
+
|
|
94
|
+
- [ ] 先判断是否真需要配置中心;规模小/变更少时用环境变量+配置文件+IaC,不强上中间件。
|
|
95
|
+
- [ ] 用能力维度(动态下发/隔离/版本回滚/灰度/审计/UI/HA/生态)逐项对比候选,能力够用选最轻最贴的。
|
|
96
|
+
- [ ] 接入时确认来源优先级唯一、客户端本地缓存容错、热更新有校验、密钥不混入。
|
|
97
|
+
- [ ] 开启变更审计与回滚;生产集群部署 + 存储层高可用 + 客户端降级,配置中心不成单点。
|
|
98
|
+
- [ ] 部署记录"制品版本 + 配置版本"可追溯;演练配置中心宕机下业务仍可启动运行。
|
|
99
|
+
- [ ] 配置治理纪律(配置即代码/环境对等/启动即校验/密钥分离/漂移检测)按 `architecture/01-standards/configuration-and-environment-management` 落地,本文不重复。
|