CC 咖啡猫的工作空间 Coding Space

服务治理实践

微服务架构将单体应用拆分为多个独立的服务,带来了开发和部署的灵活性,但也引入了服务间通信、故障处理、流量控制等复杂性问题。服务治理就是解决这些复杂性的系统性方案。


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
收集层
  • 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 最佳实践

  1. 统一命名规范:指标、日志、追踪中的服务名、标签保持一致
  2. 关联上下文:在日志中包含 TraceID,便于跨维度关联分析
  3. 分层采样:高频指标全量采集,低频追踪按需采样(如 1%)
  4. 成本控制:根据数据重要性设置不同的保留策略(热数据7天,冷数据90天)
  5. 自动化运维:基于可观测性数据实现自动扩缩容和故障自愈
  6. 安全合规:日志脱敏处理,敏感信息加密存储
  7. 性能影响:监控埋点的性能开销控制在 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 配置
  • 监控全覆盖:从基础设施到业务指标的全方位监控
  • 自动化恢复:故障自动检测和恢复机制
  • 混沌工程:定期进行故障演练,验证系统韧性

总结

微服务治理是一个复杂的系统工程,需要从多个维度综合考虑:

  1. 基础治理:注册发现、负载均衡、配置管理
  2. 稳定性保障:熔断降级、限流控制、容错处理
  3. 可观测性:监控告警、链路追踪、日志分析
  4. 安全性:认证授权、安全通信、漏洞防护
  5. 运维效率:自动化部署、弹性伸缩、故障恢复

随着技术演进,服务网格正在成为新一代的服务治理方案,它将治理能力进一步下沉到基础设施层,让业务开发更加专注核心逻辑。但在选择技术方案时,需要根据团队技术栈、业务复杂度、运维能力等因素综合评估,选择最适合的治理方案。


最后更新:2026/05/13