核心概念

服务治理是指对分布式系统中的服务进行管理和控制,确保服务的高可用、高性能和高稳定性。Dubbo 提供了全方位的服务治理能力,涵盖服务的全生命周期。

核心目标

  • 高可用:服务故障自动切换、降级保护
  • 高性能:负载均衡、并发控制、异步调用
  • 可观测:监控、链路追踪、日志
  • 可管理:动态配置、版本管理、灰度发布

Dubbo 服务治理功能

1. 服务注册与发现

核心功能

  • 自动注册服务到注册中心
  • 自动发现可用的服务提供者
  • 实时感知服务上下线

支持的注册中心

// Zookeeper(常用)
dubbo:
  registry:
    address: zookeeper://127.0.0.1:2181

// Nacos(推荐,功能更强大)
dubbo:
  registry:
    address: nacos://127.0.0.1:8848

// Redis
dubbo:
  registry:
    address: redis://127.0.0.1:6379

// Multicast(简单测试)
dubbo:
  registry:
    address: multicast://224.5.6.7:1234

// 多注册中心
dubbo:
  registries:
    registry1:
      address: zookeeper://127.0.0.1:2181
    registry2:
      address: nacos://127.0.0.1:8848

动态上下线

// Provider 启动,自动注册
@Service
public class UserServiceImpl implements UserService {
    // 启动时自动注册到注册中心
}

// Consumer 启动,自动订阅
@Reference
private UserService userService;
// 自动获取 Provider 列表并建立连接

// 动态感知(Provider 下线,Consumer 自动感知)
// Zookeeper:通过 Watch 机制
// Nacos:通过长轮询机制

2. 负载均衡

支持的策略

// Random(随机,默认)
@Service(loadbalance = "random", weight = 100)
public class UserServiceImpl { }

// LeastActive(最少活跃数,推荐)
@Service(loadbalance = "leastactive")
public class UserServiceImpl { }

// RoundRobin(轮询)
@Service(loadbalance = "roundrobin")
public class UserServiceImpl { }

// ConsistentHash(一致性哈希)
@Service(loadbalance = "consistenthash")
public class CacheServiceImpl { }

动态权重调整

// 通过 Dubbo Admin 动态调整权重
// 高峰期:提升高性能服务器权重
// 低峰期:均匀分配

3. 集群容错

容错策略

(1)Failover(失败自动切换,默认)

@Reference(
    cluster = "failover",
    retries = 2  // 失败重试 2 次
)
private UserService userService;

// 适用场景:读操作、幂等操作
// 原理:调用失败后,自动切换到其他 Provider 重试

(2)Failfast(快速失败)

@Reference(cluster = "failfast")
private PaymentService paymentService;

// 适用场景:非幂等写操作(支付、下单)
// 原理:调用失败立即抛出异常,不重试

(3)Failsafe(失败安全)

@Reference(cluster = "failsafe")
private LogService logService;

// 适用场景:日志记录、审计
// 原理:调用失败,忽略异常,返回空结果

(4)Failback(失败自动恢复)

@Reference(cluster = "failback")
private NotificationService notificationService;

// 适用场景:消息通知、事件上报
// 原理:调用失败,后台记录,定时重试

(5)Forking(并行调用)

@Reference(
    cluster = "forking",
    forks = 2  // 并行调用 2 个 Provider
)
private RecommendService recommendService;

// 适用场景:实时性要求高、可以容忍浪费资源
// 原理:同时调用多个 Provider,只要一个成功就返回

(6)Broadcast(广播调用)

@Reference(cluster = "broadcast")
private CacheService cacheService;

// 适用场景:缓存刷新、配置更新
// 原理:调用所有 Provider,任意一个失败就算失败

4. 服务降级

降级策略

(1)Mock 降级

// 失败时返回 Mock 数据
@Reference(mock = "return null")
private UserService userService;

@Reference(mock = "return {\"code\": 500, \"message\": \"服务降级\"}")
private OrderService orderService;

// 自定义 Mock 实现
@Reference(mock = "com.example.UserServiceMock")
private UserService userService;

public class UserServiceMock implements UserService {
    @Override
    public User getUser(Long userId) {
        // 返回降级数据(缓存、默认值)
        return new User(userId, "默认用户", 0);
    }
}

(2)强制降级

// 通过 Dubbo Admin 配置
// 强制所有调用返回 Mock 数据,不调用真实服务
// 用于:依赖服务不可用时,临时降级

// 配置示例(Dubbo Admin)
// mock=force:return null  // 强制降级
// mock=fail:return null   // 失败时降级

(3)条件降级

// 自定义降级逻辑
public class CustomClusterInvoker<T> implements Invoker<T> {
    
    @Override
    public Result invoke(Invocation invocation) {
        // 根据条件判断是否降级
        if (shouldDegrade()) {
            // 返回降级数据
            return new RpcResult(getMockResult());
        }
        
        // 正常调用
        return invoker.invoke(invocation);
    }
    
    private boolean shouldDegrade() {
        // 判断条件:系统负载、错误率、响应时间等
        double errorRate = getErrorRate();
        return errorRate > 0.5;  // 错误率超过 50% 降级
    }
}

5. 限流与并发控制

(1)并发控制

// Provider 端限制并发执行数
@Service(executes = 10)  // 最多 10 个并发请求
public class UserServiceImpl implements UserService {
    // 超过 10 个并发,后续请求被拒绝
}

// Consumer 端限制并发调用数
@Reference(actives = 5)  // 最多 5 个并发调用
private UserService userService;
// 超过 5 个并发,后续调用等待

// 方法级别限制
@Service
public class UserServiceImpl implements UserService {
    
    @Method(name = "getUser", executes = 20)
    public User getUser(Long userId) { }
    
    @Method(name = "updateUser", executes = 5)
    public void updateUser(User user) { }
}

(2)连接数控制

// Provider 端限制连接数
@Service(
    accepts = 100,     // 最多 100 个连接
    connections = 10   // 每个 Consumer 最多 10 个连接
)
public class UserServiceImpl { }

// Consumer 端限制连接数
@Reference(connections = 5)
private UserService userService;

(3)令牌桶限流(集成 Sentinel)

<!-- 引入 Sentinel -->
<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-apache-dubbo-adapter</artifactId>
</dependency>
// 配置限流规则
@PostConstruct
public void initFlowRules() {
    List<FlowRule> rules = new ArrayList<>();
    FlowRule rule = new FlowRule();
    rule.setResource("com.example.UserService:getUser");
    rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
    rule.setCount(100);  // QPS 限制 100
    rules.add(rule);
    FlowRuleManager.loadRules(rules);
}

6. 超时控制

// Provider 端配置超时
@Service(timeout = 3000)  // 3 秒超时
public class UserServiceImpl { }

// Consumer 端配置超时(优先级更高)
@Reference(timeout = 5000)  // 5 秒超时
private UserService userService;

// 方法级别超时
@Service
public class UserServiceImpl implements UserService {
    
    @Method(name = "getUser", timeout = 1000)
    public User getUser(Long userId) { }
    
    @Method(name = "queryOrder", timeout = 10000)
    public List<Order> queryOrder(Long userId) { }
}

// 超时处理
try {
    User user = userService.getUser(123L);
} catch (RpcException e) {
    if (e.isTimeout()) {
        // 超时处理逻辑
        log.error("调用超时", e);
    }
}

7. 版本管理

// 多版本共存
@Service(version = "1.0.0")
public class UserServiceV1Impl implements UserService {
    // 老版本实现
}

@Service(version = "2.0.0")
public class UserServiceV2Impl implements UserService {
    // 新版本实现
}

// Consumer 指定版本
@Reference(version = "2.0.0")
private UserService userService;  // 调用 2.0.0 版本

@Reference(version = "*")
private UserService userService;  // 调用任意版本

// 灰度发布
// 10% 流量 → 2.0.0
// 90% 流量 → 1.0.0

8. 服务分组

// 按环境分组
@Service(group = "dev")
public class UserServiceDevImpl { }

@Service(group = "prod")
public class UserServiceProdImpl { }

// Consumer 指定分组
@Reference(group = "prod")
private UserService userService;

// 按业务分组
@Service(group = "payment")
public class PaymentServiceImpl { }

@Service(group = "refund")
public class RefundServiceImpl { }

// 合并分组结果
@Reference(group = "*", merger = "true")
private PaymentService paymentService;
// 同时调用所有分组,合并结果

9. 路由规则

(1)条件路由

// 通过 Dubbo Admin 配置
// 规则:将特定用户的请求路由到特定服务器

// 示例:VIP 用户路由到高性能服务器
// condition://0.0.0.0/com.example.UserService
//   ?category=routers
//   &rule=user.vip = true => host = 192.168.1.100

(2)标签路由

// Provider 配置标签
@Service(tag = "gray")  // 灰度环境
public class UserServiceImpl { }

@Service(tag = "stable")  // 稳定环境
public class UserServiceImpl { }

// Consumer 指定标签
RpcContext.getContext().setAttachment("tag", "gray");
userService.getUser(123L);  // 路由到灰度环境

(3)脚本路由

// 使用 JavaScript 脚本自定义路由逻辑
function route(invokers, invocation) {
    var result = new java.util.ArrayList(invokers.size());
    
    // 根据请求参数路由
    var userId = invocation.getArguments()[0];
    if (userId % 2 == 0) {
        // 偶数 ID 路由到 A 机房
        for (var i = 0; i < invokers.size(); i++) {
            if (invokers.get(i).getUrl().getParameter("region") == "A") {
                result.add(invokers.get(i));
            }
        }
    } else {
        // 奇数 ID 路由到 B 机房
        for (var i = 0; i < invokers.size(); i++) {
            if (invokers.get(i).getUrl().getParameter("region") == "B") {
                result.add(invokers.get(i));
            }
        }
    }
    
    return result;
}

10. 异步调用

// 同步调用(默认)
User user = userService.getUser(123L);

// 异步调用(提升性能)
CompletableFuture<User> future = RpcContext.getContext()
    .asyncCall(() -> userService.getUser(123L));

future.thenAccept(user -> {
    // 异步处理结果
    System.out.println(user.getName());
});

// 并行调用多个服务
CompletableFuture<User> userFuture = 
    RpcContext.getContext().asyncCall(() -> userService.getUser(123L));

CompletableFuture<Order> orderFuture = 
    RpcContext.getContext().asyncCall(() -> orderService.getOrder(456L));

// 等待所有结果
CompletableFuture.allOf(userFuture, orderFuture).join();

11. 监控与追踪

(1)Dubbo Admin

# 监控功能
- 服务列表
- 实时调用统计
- 成功率、错误率
- 响应时间分布
- 动态配置管理

(2)链路追踪(集成 SkyWalking)

<dependency>
    <groupId>org.apache.skywalking</groupId>
    <artifactId>apm-toolkit-trace</artifactId>
</dependency>
// 自动追踪 Dubbo 调用链路
// A 服务 → B 服务 → C 服务
// TraceId 自动传递,全链路可追踪

(3)Metrics 指标

# Prometheus 集成
dubbo:
  metrics:
    protocol: prometheus
    port: 9090

# 指标:
# - dubbo_provider_requests_total
# - dubbo_provider_requests_succeed_total
# - dubbo_provider_requests_failed_total
# - dubbo_provider_requests_processing
# - dubbo_consumer_requests_total

12. 参数验证

// JSR303 参数校验
@Service(validation = "true")
public class UserServiceImpl implements UserService {
    
    @Override
    public void createUser(@Valid User user) {
        // 参数自动校验
        // 校验失败抛出 ConstraintViolationException
    }
}

public class User {
    @NotNull(message = "用户名不能为空")
    private String name;
    
    @Min(value = 0, message = "年龄不能为负数")
    @Max(value = 150, message = "年龄不能超过 150")
    private Integer age;
    
    @Email(message = "邮箱格式不正确")
    private String email;
}

13. 结果缓存

// 方法级别缓存
@Service
public class UserServiceImpl implements UserService {
    
    @Method(name = "getUser", cache = "lru")
    public User getUser(Long userId) {
        // 结果会被缓存(LRU 策略)
        return userMapper.selectById(userId);
    }
}

// 缓存策略
// - lru:最近最少使用
// - lfu:最不经常使用
// - threadlocal:线程缓存

14. 泛化调用

// 不需要服务接口,直接调用
GenericService genericService = ...;

Object result = genericService.$invoke(
    "getUser",                          // 方法名
    new String[]{"java.lang.Long"},     // 参数类型
    new Object[]{123L}                  // 参数值
);

// 适用场景:
// - 网关服务
// - 测试工具
// - 服务代理

服务治理最佳实践

1. 完整配置示例

@Service(
    // 基础配置
    version = "1.0.0",
    group = "default",
    timeout = 3000,
    retries = 2,
    
    // 负载均衡
    loadbalance = "leastactive",
    weight = 100,
    
    // 容错
    cluster = "failover",
    
    // 并发控制
    executes = 20,
    accepts = 100,
    connections = 10,
    
    // 协议和序列化
    protocol = "dubbo",
    serialization = "hessian2",
    
    // 线程池
    threads = 200,
    threadpool = "fixed",
    
    // 其他
    validation = "true",
    cache = "lru"
)
public class UserServiceImpl implements UserService {
    // ...
}

2. 分层治理

// 网关层:限流、鉴权、路由
@Service(executes = 1000)
public class GatewayServiceImpl { }

// 业务层:降级、容错
@Service(
    cluster = "failover",
    mock = "com.example.UserServiceMock"
)
public class UserServiceImpl { }

// 数据层:超时、重试
@Service(
    timeout = 5000,
    retries = 0  // 数据库操作不重试
)
public class DataServiceImpl { }

3. 监控告警

# 监控指标
- 调用量(QPS)
- 成功率
- 响应时间(P99、P95)
- 错误率
- 慢调用比例

# 告警规则
- 错误率 > 10%
- P99 响应时间 > 3s
- 可用 Provider 数量 < 2

答题总结

Dubbo 支持的服务治理功能

1. 核心功能

  • 服务注册发现:Zookeeper、Nacos、Redis
  • 负载均衡:Random、LeastActive、RoundRobin、ConsistentHash
  • 集群容错:Failover、Failfast、Failsafe、Failback、Forking
  • 服务降级:Mock 降级、强制降级、条件降级
  • 限流控制:并发限制、连接数限制、令牌桶
  • 超时控制:全局超时、方法级超时
  • 版本管理:多版本共存、灰度发布
  • 服务分组:环境分组、业务分组
  • 路由规则:条件路由、标签路由、脚本路由
  • 异步调用:提升性能、并行调用
  • 监控追踪:Dubbo Admin、SkyWalking、Prometheus
  • 参数验证:JSR303 自动校验
  • 结果缓存:LRU、LFU、ThreadLocal
  • 泛化调用:无需接口的动态调用

2. 治理层次

应用层:版本、分组、路由
调用层:负载均衡、容错、降级
传输层:超时、重试、限流
监控层:指标、追踪、告警

3. 配置优先级

Consumer > Provider > 全局配置
方法级 > 接口级 > 全局

4. 最佳实践

  • 默认配置:failover + leastactive
  • 读操作:failover + retries=2
  • 写操作:failfast + retries=0
  • 关键服务:配置降级、限流
  • 监控告警:Dubbo Admin + Prometheus

面试技巧:可以按照服务生命周期(注册 → 调用 → 降级 → 监控)的顺序回答,强调 Dubbo 提供的是全方位的服务治理能力,涵盖高可用、高性能、可观测、可管理等多个维度。