服务治理实践
微服务架构将单体应用拆分为多个独立的服务,带来了开发和部署的灵活性,但也引入了服务间通信、故障处理、流量控制等复杂性问题。服务治理就是解决这些复杂性的系统性方案。
1. 服务注册与发现
1.1 核心概念
服务注册:服务实例启动时向注册中心注册自身信息(服务名、IP地址、端口、健康状态、元数据等)。
服务发现:服务消费者通过服务名从注册中心获取可用的服务实例列表。
健康检查:注册中心定期检测服务实例的健康状态,自动剔除不健康的实例。
1.2 常用注册中心对比
| 组件 | 一致性模型 | 特点 | 适用场景 |
|---|---|---|---|
| Eureka | AP(最终一致) | 自我保护机制,网络分区时仍可提供服务 | Netflix生态,对一致性要求不高的场景 |
| Consul | CP(强一致) | 多数据中心支持,健康检查丰富 | 对一致性要求高,多数据中心部署 |
| Nacos | AP/CP可切换 | 配置中心+注册中心,功能全面 | 阿里系技术栈,需要配置管理的场景 |
| ZooKeeper | CP(强一致) | 成熟稳定,但性能相对较低 | 对一致性要求极高,已有ZK基础设施 |
1.3 实现示例
// Spring Cloud Eureka 客户端配置
@SpringBootApplication
@EnableDiscoveryClient
public class UserServiceApplication {
public static void main(String[] args) {
SpringApplication.run(UserServiceApplication.class, args);
}
}
// application.yml
spring:
application:
name: user-service
server:
port: 8081
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
instance:
prefer-ip-address: true
instance-id: ${spring.application.name}:${server.port}
1.4 最佳实践
- 服务命名规范:使用有意义的服务名,避免随意命名
- 健康检查配置:合理设置健康检查间隔和超时时间
- 元数据使用:利用元数据传递版本号、环境信息等
- 多注册中心:关键服务可同时注册到多个注册中心提高可用性
2. 负载均衡
2.1 客户端负载均衡
客户端负载均衡由服务消费者负责选择具体的服务实例。
// Ribbon + RestTemplate(已进入维护模式)
@LoadBalanced
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
@Service
public class OrderService {
@Autowired
private RestTemplate restTemplate;
public User getUser(Long userId) {
// user-service 是服务名,Ribbon 自动进行负载均衡
return restTemplate.getForObject("http://user-service/users/" + userId, User.class);
}
}
// Feign 内置负载均衡(推荐)
@FeignClient(name = "user-service", fallback = UserClientFallback.class)
public interface UserClient {
@GetMapping("/users/{id}")
User getUser(@PathVariable Long id);
@PostMapping("/users")
User createUser(@RequestBody CreateUserRequest request);
}
@Component
public class UserClientFallback implements UserClient {
@Override
public User getUser(Long id) {
return new User("default", "默认用户");
}
@Override
public User createUser(CreateUserRequest request) {
throw new RuntimeException("用户服务不可用");
}
}
2.2 服务端负载均衡
服务端负载均衡由专门的负载均衡器(如 Nginx、LVS)负责。
# Nginx 配置示例
upstream user-service {
server 192.168.1.10:8081 weight=1;
server 192.168.1.11:8081 weight=1;
server 192.168.1.12:8081 weight=1;
}
server {
listen 80;
location /api/users/ {
proxy_pass http://user-service;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
2.3 负载均衡策略
| 策略 | 说明 | 适用场景 |
|---|---|---|
| 轮询(Round Robin) | 依次选择每个实例 | 实例性能相近 |
| 随机(Random) | 随机选择实例 | 实例性能相近,简单高效 |
| 最少连接(Least Connections) | 选择连接数最少的实例 | 实例处理能力差异较大 |
| 加权轮询/随机 | 根据权重分配流量 | 实例硬件配置不同 |
| 一致性哈希 | 相同请求路由到相同实例 | 缓存场景,需要会话保持 |
2.4 Spring Cloud LoadBalancer
Spring Cloud 2020+ 推荐使用 Spring Cloud LoadBalancer 替代 Ribbon:
// 启用 Spring Cloud LoadBalancer
@Configuration
public class LoadBalancerConfig {
@Bean
@LoadBalanced
public WebClient.Builder webClientBuilder() {
return WebClient.builder();
}
}
@Service
public class OrderService {
@Autowired
private WebClient.Builder webClientBuilder;
public Mono<User> getUser(Long userId) {
return webClientBuilder.build()
.get()
.uri("http://user-service/users/{id}", userId)
.retrieve()
.bodyToMono(User.class);
}
}
3. 服务容错与熔断
3.1 熔断器模式
熔断器有三种状态:
- Closed(关闭):正常调用,记录失败次数
- Open(打开):快速失败,直接返回降级结果
- Half-Open(半开):允许部分请求通过,测试服务是否恢复
3.2 Sentinel 实现
Sentinel 是阿里巴巴开源的流量控制组件,支持熔断、限流、系统保护等功能。
// Sentinel 熔断规则配置
@Configuration
public class SentinelConfig {
@PostConstruct
public void initDegradeRules() {
List<DegradeRule> rules = new ArrayList<>();
// 按响应时间熔断
DegradeRule rtRule = new DegradeRule("getUser")
.setGrade(RuleConstant.DEGRADE_GRADE_RT) // RT模式
.setCount(200) // 超过200ms
.setTimeWindow(10) // 熔断持续10秒
.setMinRequestAmount(5) // 最小请求数
.setSlowRatioThreshold(0.5); // 慢调用比例阈值
// 按异常比例熔断
DegradeRule exceptionRule = new DegradeRule("createOrder")
.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_RATIO)
.setCount(0.5) // 异常比例超过50%
.setTimeWindow(30) // 熔断持续30秒
.setMinRequestAmount(10); // 最小请求数
rules.add(rtRule);
rules.add(exceptionRule);
DegradeRuleManager.loadRules(rules);
}
}
// 业务代码中使用
@Service
public class OrderService {
public User getUser(Long userId) {
Entry entry = null;
try {
entry = SphU.entry("getUser");
// 调用用户服务
return userClient.getUser(userId);
} catch (BlockException e) {
// 熔断触发,返回降级结果
return new User("default", "服务暂时不可用");
} finally {
if (entry != null) {
entry.exit();
}
}
}
// 使用注解方式(推荐)
@SentinelResource(
value = "createOrder",
blockHandler = "handleCreateOrderBlock",
fallback = "createOrderFallback"
)
public Order createOrder(OrderRequest request) {
return orderClient.createOrder(request);
}
// 熔断处理方法
public Order handleCreateOrderBlock(OrderRequest request, BlockException ex) {
log.warn("创建订单被限流或熔断", ex);
return new Order("fallback", "订单创建失败,请稍后重试");
}
// 异常降级方法
public Order createOrderFallback(OrderRequest request, Throwable ex) {
log.error("创建订单发生异常", ex);
return new Order("fallback", "订单创建失败,请稍后重试");
}
}
3.3 熔断最佳实践
- 合理的熔断阈值:根据业务特点设置合适的RT阈值和异常比例
- 渐进式恢复:熔断时间不宜过长,避免服务长时间不可用
- 监控告警:熔断触发时及时告警,便于运维介入
- 降级策略:提供有意义的降级结果,而不是简单的错误信息
4. 限流与流量控制
4.1 多层次限流架构
根据项目规范,限流应在 API网关和内部服务两个层面都进行配置:
网关层限流(第一道防线)
- 全局QPS限制:防止突发流量打垮整个系统
- 租户/IP级别限流:防刷、防爬虫、防DDoS攻击
- 简单接口限流:粗粒度的流量控制
服务层限流(第二道防线)
- 接口级别限流:根据接口复杂度设置不同阈值
- 资源级别限流:保护数据库连接池、缓存等下游资源
- 热点参数限流:对热门商品ID、用户ID等进行特殊限流
- 兜底保护:当网关限流失效时的最后一道防线
4.2 网关层限流实现
# Spring Cloud Gateway 限流配置
spring:
cloud:
gateway:
routes:
- id: user-service
uri: lb://user-service
predicates:
- Path=/api/users/**
filters:
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 10 # 每秒生成令牌数
redis-rate-limiter.burstCapacity: 20 # 令牌桶容量
key-resolver: "#{@userKeyResolver}" # 自定义key解析器
# 自定义Key解析器
@Component
public class UserKeyResolver implements KeyResolver {
@Override
public Mono<String> resolve(ServerWebExchange exchange) {
// 按用户ID限流
String userId = exchange.getRequest().getQueryParams().getFirst("userId");
if (userId != null) {
return Mono.just("user:" + userId);
}
// 按IP限流
String ip = exchange.getRequest().getRemoteAddress().getAddress().getHostAddress();
return Mono.just("ip:" + ip);
}
}
4.3 服务层限流实现(Sentinel)
// 热点参数限流
@PostConstruct
public void initParamFlowRules() {
ParamFlowRule rule = new ParamFlowRule("getUserById")
.setParamIdx(0) // 第一个参数(userId)
.setCount(100) // QPS限制
.setDurationInSec(1) // 统计窗口1秒
.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER);
// 热点参数例外项(特定用户ID可以更高QPS)
ParamFlowItem item = new ParamFlowItem()
.setObject("1001") // 用户ID为1001
.setClassType(String.class)
.setCount(1000); // QPS限制1000
rule.setParamFlowItemList(Collections.singletonList(item));
ParamFlowRuleManager.loadRules(Collections.singletonList(rule));
}
// 系统自适应限流
@PostConstruct
public void initSystemRules() {
SystemRule rule = new SystemRule();
rule.setAvgRt(100); // 平均响应时间不超过100ms
rule.setQps(2000); // QPS不超过2000
rule.setLoad(3.0); // 系统load不超过3
rule.setCpuUsage(0.6); // CPU使用率不超过60%
SystemRuleManager.loadRules(Collections.singletonList(rule));
}
4.4 限流算法对比
| 算法 | 特点 | 适用场景 |
|---|---|---|
| 令牌桶 | 允许突发流量,平滑输出 | API限流,需要处理突发请求 |
| 漏桶 | 严格平滑输出,不允许突发 | 网络流量整形,严格控制输出速率 |
| 滑动窗口 | 精确统计,无临界问题 | 需要精确QPS控制的场景 |
| 计数器 | 实现简单,但有临界问题 | 简单限流,对精度要求不高 |
5. 配置管理
5.1 配置中心核心能力
- 集中管理:统一存储所有微服务的配置
- 动态刷新:配置变更实时生效,无需重启服务
- 版本管理:配置历史版本回溯和对比
- 灰度发布:按实例或分组逐步推送配置
- 权限控制:配置修改的权限管理和审计
5.2 Nacos 配置中心实现
# bootstrap.yml
spring:
application:
name: user-service
cloud:
nacos:
config:
server-addr: ${NACOS_HOST:localhost}:${NACOS_PORT:8848}
file-extension: yaml
group: DEFAULT_GROUP
namespace: ${NAMESPACE:public}
// 动态配置监听
@Component
@RefreshScope // 支持配置动态刷新
public class UserServiceConfig {
@Value("${user.service.timeout:5000}")
private int timeout;
@Value("${user.service.retry-count:3}")
private int retryCount;
// 配置变更时自动更新
public int getTimeout() {
return timeout;
}
public int getRetryCount() {
return retryCount;
}
}
// 监听配置变更事件
@Component
public class ConfigChangeListener {
@EventListener
public void handleConfigChange(RefreshScopeRefreshedEvent event) {
log.info("配置已刷新");
// 执行配置变更后的初始化逻辑
}
}
5.3 配置管理最佳实践
- 配置分类:将配置分为应用配置、环境配置、敏感配置等
- 配置加密:敏感配置(如数据库密码)应加密存储
- 配置验证:配置变更前进行格式和逻辑验证
- 配置回滚:保留历史版本,支持快速回滚
- 配置审计:记录配置变更的操作日志
6. 服务监控与可观测性
传统监控侧重于"系统是否异常",而可观测性关注"为什么异常"。可观测性通过三个核心维度(Metrics + Tracing + Logging)提供系统运行的完整视图,配合可视化工具实现问题快速定位和根因分析。
6.1 可观测性三大支柱
可观测性的核心是以下三个相互补充的维度:
6.1.1 Metrics(指标监控)
- 定义:随时间变化的数值度量,用于监控系统性能和业务状态
- 服务指标:QPS、响应时间、错误率、CPU/内存使用率
- 业务指标:订单量、用户活跃度、转化率等
- 基础设施指标:磁盘IO、网络带宽、数据库连接数
- 特点:高聚合性、低存储成本、适合趋势分析和告警
6.1.2 Tracing(分布式追踪)
- 定义:跟踪单个请求在多个服务间的完整调用链路
- 链路追踪:记录请求经过的每个服务、方法、数据库调用
- 性能分析:识别性能瓶颈和慢调用的具体位置
- 依赖分析:可视化服务间的调用关系和依赖拓扑
- 特点:高详细度、适合根因分析、存储成本较高
6.1.3 Logging(日志收集)
- 定义:离散的事件记录,包含系统运行的详细信息
- 结构化日志:统一的日志格式(JSON),便于机器解析和分析
- 日志聚合:集中收集和存储来自不同服务的日志
- 日志告警:基于日志内容的异常检测和实时告警
- 特点:最详细的信息、适合调试和审计、存储成本最高
6.2 技术栈实现
6.2.1 指标监控技术栈
数据流程:埋点 → 收集 → 存储 → 查询 → 可视化
采集层(埋点)
- Micrometer:Spring Boot 官方推荐的指标门面,支持多后端
- 内置指标:JVM、HTTP、Tomcat、DataSource 等
- 自定义指标:Counter、Timer、Gauge、DistributionSummary
- 标签支持:多维度标签,便于聚合分析
// Micrometer 指标埋点(埋点层)
@RestController
public class UserController {
private final Counter userCreateCounter;
private final Timer userQueryTimer;
public UserController(MeterRegistry meterRegistry) {
this.userCreateCounter = Counter.builder("user.create.count")
.description("用户创建次数")
.tag("environment", "prod")
.register(meterRegistry);
this.userQueryTimer = Timer.builder("user.query.duration")
.description("用户查询耗时")
.tag("method", "getUser")
.register(meterRegistry);
}
@PostMapping("/users")
public User createUser(@RequestBody CreateUserRequest request) {
userCreateCounter.increment();
return userService.createUser(request);
}
@GetMapping("/users/{id}")
public User getUser(@PathVariable Long id) {
return userQueryTimer.recordCallable(() -> userService.getUser(id));
}
}
- Prometheus Client Libraries:各语言的官方客户端库
- Java:
io.prometheus:simpleclient - Python:
prometheus_client - Go:
github.com/prometheus/client_golang
- Java:
收集层
- Spring Boot Actuator:暴露
/actuator/metrics和/actuator/prometheus端点 - Prometheus Server:主动拉取(Pull)模式,定时从目标端点抓取数据
- Pushgateway:被动推送(Push)模式,适用于批处理任务
存储层
-
Prometheus:原生时序数据库,内置存储引擎
- 数据模型:时间序列 + 标签
- 存储格式:自定义的块存储格式
- 保留策略:可配置数据保留时间(默认15天)
-
VictoriaMetrics:高性能 Prometheus 兼容存储
- 更高的写入吞吐量
- 更低的存储空间占用
- 支持长期数据保留
-
InfluxDB:通用时序数据库,支持 PromQL 兼容查询
查询层
- PromQL:Prometheus 查询语言,支持聚合、函数、范围查询
- MetricsQL:VictoriaMetrics 扩展的查询语言
- Flux:InfluxDB 的函数式查询语言
6.2.2 分布式追踪技术栈
采集层(埋点)
-
OpenTelemetry SDK:CNCF 统一标准,支持多语言
- 自动埋点:HTTP、gRPC、数据库、消息队列等
- 手动埋点:自定义 Span 和属性
- 上下文传播:W3C Trace Context 标准
-
Spring Cloud Sleuth:Spring 生态的分布式追踪解决方案
- 自动集成 Spring Web、Feign、RabbitMQ、Kafka 等
- 生成 TraceID、SpanID 并在调用链中传播
- 与 Zipkin、Jaeger 等后端无缝集成
// Sleuth 自动埋点(无需额外代码)
// 只需添加依赖即可自动追踪
// <dependency>
// <groupId>org.springframework.cloud</groupId>
// <artifactId>spring-cloud-starter-sleuth</artifactId>
// </dependency>
// <dependency>
// <groupId>org.springframework.cloud</groupId>
// <artifactId>spring-cloud-sleuth-zipkin</artifactId>
// </dependency>
- SkyWalking Agent:Java 字节码增强,无侵入式埋点
- 自动探针:支持主流框架和中间件
- 手动探针:@Trace 注解自定义追踪点
- 性能开销:通常 < 10%
# SkyWalking Agent 配置
agent:
service_name: ${SW_AGENT_NAME:user-service}
collector_backend_services: ${SW_AGENT_COLLECTOR_BACKEND_SERVICES:127.0.0.1:11800}
收集层
- Zipkin Collector:接收来自客户端的追踪数据
- Jaeger Collector:支持多种采样策略和数据格式
- SkyWalking OAP Server:接收 Agent 发送的追踪数据
存储层
-
Zipkin Storage:
- 内存存储(开发环境)
- MySQL/PostgreSQL(小规模生产)
- Elasticsearch(大规模生产,推荐)
-
Jaeger Storage:
- 内存存储(开发)
- Cassandra(官方推荐)
- Elasticsearch(兼容性好)
- Kafka(缓冲层)
-
SkyWalking Storage:
- Elasticsearch(推荐)
- MySQL/H2(小规模)
- TiDB(分布式场景)
查询层
- Zipkin UI:官方 Web UI,支持链路查看和搜索
- Jaeger UI:功能丰富的追踪界面,支持依赖图
- SkyWalking UI:一体化监控平台,包含拓扑图、服务列表等
主流方案对比:
- SkyWalking:Apache 开源,功能全面,支持自动探针,一体化平台
- Zipkin:Twitter 开源,轻量级,集成简单,社区成熟
- Jaeger:CNCF 项目,云原生友好,支持 OpenTelemetry,企业级特性
6.2.3 日志收集技术栈
采集层(日志生成)
- Logback/Log4j2:Java 主流日志框架
- 结构化输出:JSON 格式,包含 TraceID、SpanID
- 异步日志:提高性能,避免阻塞业务线程
- 条件日志:基于 MDC 实现上下文日志
<!-- Logback 结构化日志配置 -->
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
<providers>
<timestamp/>
<logLevel/>
<loggerName/>
<message/>
<mdc/> <!-- 包含 TraceID 等上下文信息 -->
<stackTrace/>
</providers>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="STDOUT"/>
</root>
</configuration>
- MDC(Mapped Diagnostic Context):线程本地存储,用于传递上下文信息
// 在 Sleuth 或手动埋点中设置 TraceID 到 MDC MDC.put("traceId", traceId); logger.info("处理用户请求"); // 日志中自动包含 traceId 字段
收集层(日志传输)
-
Filebeat/Fluent Bit:轻量级日志收集器
- 文件监控:实时监控日志文件变化
- 过滤处理:解析 JSON、添加字段、过滤敏感信息
- 多输出:支持发送到多个后端
-
Logstash:功能强大的日志处理管道
- 输入插件:File、TCP、UDP、Kafka 等
- 过滤插件:Grok 解析、JSON 解析、字段转换
- 输出插件:Elasticsearch、Kafka、文件等
<!-- Logback + Logstash 配置 -->
<appender name="LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
<destination>logstash:5000</destination>
<encoder charset="UTF-8" class="net.logstash.logback.encoder.LogstashEncoder"/>
</appender>
- Promtail:Loki 官方日志收集器
- 轻量级设计,资源占用少
- 标签提取:从日志内容或文件路径提取标签
- 批量发送:优化网络传输效率
存储层
-
Elasticsearch:分布式搜索和分析引擎
- 倒排索引:支持全文搜索和结构化查询
- 分片机制:水平扩展,高可用
- 映射管理:动态或静态字段类型定义
-
Loki:Grafana Labs 开发的轻量级日志聚合系统
- 标签索引:只对标签建立索引,不索引日志内容
- 块存储:按时间分块存储原始日志
- 成本优势:存储成本比 Elasticsearch 低 5-10 倍
-
ClickHouse:列式数据库,适合日志分析
- 高压缩比:日志数据压缩率可达 90%
- 快速查询:支持复杂的分析查询
- 实时写入:高吞吐量的日志写入能力
查询层
-
Kibana:Elasticsearch 官方可视化工具
- Discover:日志搜索和过滤
- Dashboard:自定义仪表板
- Alerting:基于日志的告警规则
-
Grafana Logs:Loki 的查询界面
- LogQL:类似 PromQL 的日志查询语言
- 关联查询:与 Metrics 和 Traces 联合查询
- 统一视图:在一个界面中查看所有可观测性数据
主流方案对比:
- ELK Stack:Elasticsearch + Logstash + Kibana,功能最全面,但资源消耗大
- EFK Stack:Elasticsearch + Fluentd + Kibana,容器化环境友好
- Loki + Promtail + Grafana:轻量级方案,与 Prometheus 生态集成,成本效益高
6.3 可视化与告警
6.3.1 Grafana(统一可视化平台)
- 多数据源支持:同时连接 Prometheus、Loki、Elasticsearch、Jaeger 等
- 仪表板模板:预置微服务监控模板,快速搭建监控视图
- 告警规则:基于指标阈值的告警配置
- 统一视图:在一个界面中同时查看 Metrics、Logs、Traces
- 关联分析:点击指标图表可跳转到相关日志和追踪
6.3.2 监控告警策略
- 黄金信号监控:延迟(Latency)、流量(Traffic)、错误(Errors)、饱和度(Saturation)
- 分层告警:基础设施层 → 服务层 → 应用层 → 业务层
- 智能告警:基于历史数据的动态阈值,减少误报
- 告警收敛:相同问题的告警合并,避免告警风暴
- 告警渠道:邮件、Slack、钉钉、企业微信、PagerDuty 等
6.4 最佳实践
- 统一命名规范:指标、日志、追踪中的服务名、标签保持一致
- 关联上下文:在日志中包含 TraceID,便于跨维度关联分析
- 分层采样:高频指标全量采集,低频追踪按需采样(如 1%)
- 成本控制:根据数据重要性设置不同的保留策略(热数据7天,冷数据90天)
- 自动化运维:基于可观测性数据实现自动扩缩容和故障自愈
- 安全合规:日志脱敏处理,敏感信息加密存储
- 性能影响:监控埋点的性能开销控制在 5% 以内
7. API 网关
7.1 API 网关核心功能
- 统一入口:所有外部请求通过网关进入内部服务
- 路由转发:根据路径、域名等规则转发到对应服务
- 认证鉴权:统一的身份验证和权限控制
- 协议转换:HTTP/HTTPS、gRPC、WebSocket 等协议适配
- 安全防护:防刷、防爬虫、WAF、IP黑白名单
- 流量控制:限流、熔断、负载均衡
7.2 Spring Cloud Gateway 实现
@Component
public class AuthGlobalFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
// 跳过不需要认证的路径
if (isSkipAuth(request.getPath().pathWithinApplication().value())) {
return chain.filter(exchange);
}
// 获取Token并验证
String token = getTokenFromHeader(request);
if (token == null || !validateToken(token)) {
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
return exchange.getResponse().setComplete();
}
// 将用户信息传递给下游服务
ServerHttpRequest modifiedRequest = request.mutate()
.header("X-User-Id", getUserIdFromToken(token))
.build();
return chain.filter(exchange.mutate().request(modifiedRequest).build());
}
@Override
public int getOrder() {
return -100; // 优先级较高
}
private boolean isSkipAuth(String path) {
return "/api/public/**".equals(path) || "/health".equals(path);
}
}
@Configuration
public class GatewayRoutesConfig {
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
.route("user-service", r -> r.path("/api/users/**")
.filters(f -> f.stripPrefix(1)
.requestRateLimiter(c -> c.setRateLimiter(redisRateLimiter())
.setKeyResolver(userKeyResolver())))
.uri("lb://user-service"))
.route("order-service", r -> r.path("/api/orders/**")
.filters(f -> f.stripPrefix(1))
.uri("lb://order-service"))
.build();
}
}
7.3 网关选型对比
| 网关 | 特点 | 适用场景 |
|---|---|---|
| Spring Cloud Gateway | 基于WebFlux,非阻塞,高性能 | Spring Cloud生态,Java技术栈 |
| Zuul | Netflix开源,阻塞式,成熟稳定 | 已有Zuul基础设施,简单场景 |
| Kong | 基于Nginx,插件化架构,功能丰富 | 多语言环境,需要丰富插件 |
| Apisix | 云原生API网关,动态配置,高性能 | Kubernetes环境,云原生架构 |
8. 服务安全
8.1 认证与授权
OAuth2.0 + JWT 实现
// 资源服务器配置
@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/api/public/**").permitAll()
.antMatchers("/api/admin/**").hasRole("ADMIN")
.antMatchers("/api/user/**").hasAnyRole("USER", "ADMIN")
.anyRequest().authenticated();
}
@Bean
public TokenStore tokenStore() {
return new JwtTokenStore(jwtAccessTokenConverter());
}
@Bean
public JwtAccessTokenConverter jwtAccessTokenConverter() {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
converter.setSigningKey("my-secret-key");
return converter;
}
}
RBAC 权限模型
// 权限注解
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@PreAuthorize("@permissionService.hasPermission(#userId, 'ORDER_CREATE')")
public @interface RequirePermission {
String value();
}
// 权限服务
@Service
public class PermissionService {
public boolean hasPermission(Long userId, String permission) {
// 查询用户权限
Set<String> userPermissions = userPermissionRepository.findPermissionsByUserId(userId);
return userPermissions.contains(permission);
}
}
// 使用权限注解
@RestController
public class OrderController {
@PostMapping("/orders")
@RequirePermission("ORDER_CREATE")
public Order createOrder(@RequestParam Long userId, @RequestBody OrderRequest request) {
return orderService.createOrder(request);
}
}
8.2 服务间安全通信
mTLS(双向TLS)
# Spring Boot mTLS 配置
server:
ssl:
enabled: true
key-store: classpath:server.keystore
key-store-password: password
trust-store: classpath:server.truststore
trust-store-password: password
client-auth: need # 要求客户端证书
服务网格安全
在 Istio 中启用 mTLS:
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: default
spec:
mtls:
mode: STRICT # 强制mTLS
8.3 安全最佳实践
- 最小权限原则:服务只拥有完成工作所需的最小权限
- 敏感数据保护:配置加密、传输加密、存储加密
- 安全审计:记录所有敏感操作的日志
- 漏洞扫描:定期进行安全漏洞扫描和修复
- 零信任架构:不信任任何网络边界,验证每次访问
9. 服务网格(Service Mesh)
将服务治理下沉到基础设施层,将原本需要在应用代码中实现的服务治理逻辑(如服务发现、负载均衡、熔断限流、安全认证、可观测性等)从应用层剥离,交由专门的基础设施组件统一处理。这种架构模式通过Sidecar代理拦截所有服务间通信,使业务代码完全无感知治理逻辑,从而实现关注点分离和治理能力的标准化。
9.1 服务网格核心理念
服务网格将服务治理能力下沉到基础设施层,通过 Sidecar 代理拦截所有服务间通信,业务代码完全无感知。
9.2 Istio 架构
应用容器 ←→ Sidecar (Envoy) ←→ 控制平面 (Pilot, Citadel, Galley)
↑ ↑
└────── 业务逻辑 ────────── 服务治理能力
9.3 服务网格核心能力
流量管理
# VirtualService - 路由规则
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: user-service
spec:
hosts:
- user-service
http:
- match:
- headers:
version:
exact: v2
route:
- destination:
host: user-service
subset: v2
- route:
- destination:
host: user-service
subset: v1
# DestinationRule - 目标规则
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: user-service
spec:
host: user-service
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
trafficPolicy:
loadBalancer:
simple: ROUND_ROBIN
安全通信
# PeerAuthentication - mTLS策略
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: default
spec:
mtls:
mode: STRICT
# AuthorizationPolicy - 授权策略
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: user-service-policy
spec:
selector:
matchLabels:
app: user-service
rules:
- from:
- source:
principals: ["cluster.local/ns/default/sa/order-service"]
to:
- operation:
methods: ["GET", "POST"]
可观测性
- Metrics:自动收集服务指标
- Tracing:自动注入追踪上下文
- Logging:访问日志自动收集
9.4 服务网格 vs 传统治理
| 维度 | 传统治理 | 服务网格 |
|---|---|---|
| 侵入性 | 业务代码需要集成SDK | 完全无侵入 |
| 多语言支持 | 需要各语言SDK | 语言无关 |
| 升级维护 | 需要重新部署应用 | 独立升级Sidecar |
| 功能丰富度 | 依赖SDK功能 | 功能更丰富统一 |
| 性能开销 | 较低 | 网络跳转增加延迟 |
| 学习成本 | 相对较低 | 较高 |
10. 部署与运维
10.1 自动化部署
CI/CD 流水线
# GitLab CI 示例
stages:
- build
- test
- deploy
build:
stage: build
script:
- mvn clean package -DskipTests
artifacts:
paths:
- target/*.jar
test:
stage: test
script:
- mvn test
deploy-prod:
stage: deploy
script:
- kubectl set image deployment/user-service user-service=user-service:$CI_COMMIT_SHA
only:
- master
蓝绿部署
# Kubernetes 蓝绿部署
apiVersion: apps/v1
kind: Deployment
metadata:
name: user-service-green # 新版本
spec:
replicas: 0 # 初始为0
template:
spec:
containers:
- name: user-service
image: user-service:v2
---
apiVersion: v1
kind: Service
metadata:
name: user-service
spec:
selector:
app: user-service
version: blue # 初始指向blue版本
10.2 弹性伸缩
HPA(水平Pod自动伸缩)
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: user-service-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: user-service
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Pods
pods:
metric:
name: http_requests_per_second
target:
type: AverageValue
averageValue: "100"
KEDA(基于事件的弹性伸缩)
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: user-service-scaledobject
spec:
scaleTargetRef:
name: user-service
triggers:
- type: rabbitmq
metadata:
queueName: user-events
host: amqp://guest:guest@rabbitmq:5672/vhost
queueLength: "5" # 队列长度超过5时扩容
10.3 运维最佳实践
- 基础设施即代码:使用 Terraform、Ansible 等工具管理基础设施
- 配置即代码:使用 Helm、Kustomize 等工具管理 Kubernetes 配置
- 监控全覆盖:从基础设施到业务指标的全方位监控
- 自动化恢复:故障自动检测和恢复机制
- 混沌工程:定期进行故障演练,验证系统韧性
总结
微服务治理是一个复杂的系统工程,需要从多个维度综合考虑:
- 基础治理:注册发现、负载均衡、配置管理
- 稳定性保障:熔断降级、限流控制、容错处理
- 可观测性:监控告警、链路追踪、日志分析
- 安全性:认证授权、安全通信、漏洞防护
- 运维效率:自动化部署、弹性伸缩、故障恢复
随着技术演进,服务网格正在成为新一代的服务治理方案,它将治理能力进一步下沉到基础设施层,让业务开发更加专注核心逻辑。但在选择技术方案时,需要根据团队技术栈、业务复杂度、运维能力等因素综合评估,选择最适合的治理方案。
最后更新:2026/05/13