Skip to content

Dubbo面试题

1. Dubbo的基本概念

问题:什么是Dubbo?

答案

  • Dubbo:阿里巴巴开源的高性能、轻量级的RPC框架。
  • 特点
    • 高性能
    • 轻量级
    • 易于使用
    • 支持多种协议
    • 支持多种注册中心

2. Dubbo的架构

问题:Dubbo的架构有哪些组成部分?

答案

  • Provider:服务提供者。
  • Consumer:服务消费者。
  • Registry:注册中心。
  • Monitor:监控中心。
  • Container:服务容器。

3. Dubbo的注册中心

问题:Dubbo支持哪些注册中心?

答案

  • Zookeeper:官方推荐,支持集群。
  • Nacos:阿里巴巴开源,支持动态配置。
  • Redis:轻量级,支持集群。
  • Multicast:组播,适合测试环境。
  • Simple:简单注册中心,适合测试环境。

4. Dubbo的协议

问题:Dubbo支持哪些协议?

答案

  • dubbo协议:默认协议,基于TCP。
  • rmi协议:基于RMI。
  • hessian协议:基于HTTP。
  • http协议:基于HTTP。
  • webservice协议:基于WebService。
  • thrift协议:基于Thrift。
  • memcached协议:基于Memcached。
  • redis协议:基于Redis。

5. Dubbo的序列化

问题:Dubbo支持哪些序列化方式?

答案

  • Hessian2:默认序列化方式。
  • Dubbo序列化:Dubbo自定义序列化。
  • Kryo:高性能序列化。
  • FST:高性能序列化。
  • Fastjson:JSON序列化。
  • Protostuff:高性能序列化。

6. Dubbo的负载均衡

问题:Dubbo支持哪些负载均衡策略?

答案

  • Random:随机选择。
  • RoundRobin:轮询。
  • LeastActive:最少活跃调用数。
  • ConsistentHash:一致性哈希。
  • ShortestResponse:最短响应时间。

示例

xml
<dubbo:service interface="com.example.UserService" loadbalance="random"/>
<dubbo:reference interface="com.example.UserService" loadbalance="roundrobin"/>

7. Dubbo的集群容错

问题:Dubbo支持哪些集群容错策略?

答案

  • Failover:失败自动切换,默认策略。
  • Failfast:快速失败,只发起一次调用。
  • Failsafe:失败安全,出现异常时忽略。
  • Failback:失败自动恢复,后台记录失败请求。
  • Forking:并行调用多个服务,只要一个成功即返回。
  • Broadcast:广播调用所有服务,任意一个报错则报错。

示例

xml
<dubbo:reference interface="com.example.UserService" cluster="failover"/>

8. Dubbo的超时控制

问题:如何配置超时?

答案

xml
<!-- 服务提供者配置超时 -->
<dubbo:service interface="com.example.UserService" timeout="3000"/>

<!-- 服务消费者配置超时 -->
<dubbo:reference interface="com.example.UserService" timeout="5000"/>

<!-- 方法级别配置超时 -->
<dubbo:service interface="com.example.UserService">
    <dubbo:method name="getUser" timeout="2000"/>
</dubbo:service>

9. Dubbo的重试机制

问题:如何配置重试?

答案

xml
<!-- 配置重试次数 -->
<dubbo:reference interface="com.example.UserService" retries="3"/>

<!-- 方法级别配置重试 -->
<dubbo:reference interface="com.example.UserService">
    <dubbo:method name="getUser" retries="2"/>
</dubbo:reference>

10. Dubbo的异步调用

问题:如何实现异步调用?

答案

java
// 服务提供者
public interface UserService {
    String getUser(Long id);
    CompletableFuture<String> getUserAsync(Long id);
}

// 服务消费者
UserService userService = ...;

// 同步调用
String user = userService.getUser(1L);

// 异步调用
CompletableFuture<String> future = userService.getUserAsync(1L);
future.thenAccept(user -> System.out.println(user));

11. Dubbo的泛化调用

问题:什么是泛化调用?

答案

  • 泛化调用:没有接口类的情况下调用服务。
  • 作用
    • 测试环境
    • 网关服务
    • 动态调用

示例

java
GenericService genericService = ...;

// 泛化调用
Object result = genericService.$invoke("getUser", new String[]{"java.lang.Long"}, new Object[]{1L});

12. Dubbo的参数验证

问题:如何实现参数验证?

答案

java
// 使用JSR303验证
public class UserRequest {
    @NotNull(message = "用户ID不能为空")
    private Long id;
    
    @Size(min = 1, max = 50, message = "用户名长度必须在1-50之间")
    private String username;
}

// 配置验证
<dubbo:service interface="com.example.UserService" validation="true"/>

13. Dubbo的异步调用

问题:如何实现异步调用?

答案

java
// 使用CompletableFuture
public interface UserService {
    CompletableFuture<String> getUserAsync(Long id);
}

// 调用
CompletableFuture<String> future = userService.getUserAsync(1L);
future.thenAccept(user -> System.out.println(user));

14. Dubbo的本地存根

问题:什么是本地存根?

答案

  • 本地存根:在客户端执行部分逻辑,减少网络调用。
  • 作用
    • 减少网络开销
    • 提高性能
    • 实现缓存

示例

java
public class UserServiceStub implements UserService {
    private UserService userService;
    
    public UserServiceStub(UserService userService) {
        this.userService = userService;
    }
    
    @Override
    public String getUser(Long id) {
        // 本地逻辑
        if (id == 1L) {
            return "cached_user";
        }
        return userService.getUser(id);
    }
}

// 配置本地存根
<dubbo:reference interface="com.example.UserService" stub="com.example.UserServiceStub"/>

15. Dubbo的回调

问题:如何实现回调?

答案

java
// 定义回调接口
public interface CallbackListener {
    void onResult(String result);
}

// 服务提供者
public interface UserService {
    String getUser(Long id);
    void getUserAsync(Long id, CallbackListener callback);
}

// 服务消费者
userService.getUserAsync(1L, result -> System.out.println(result));

16. Dubbo的分组

问题:如何配置分组?

答案

xml
<!-- 服务提供者配置分组 -->
<dubbo:service interface="com.example.UserService" group="group1"/>

<!-- 服务消费者配置分组 -->
<dubbo:reference interface="com.example.UserService" group="group1"/>

17. Dubbo的版本控制

问题:如何配置版本?

答案

xml
<!-- 服务提供者配置版本 -->
<dubbo:service interface="com.example.UserService" version="1.0.0"/>

<!-- 服务消费者配置版本 -->
<dubbo:reference interface="com.example.UserService" version="1.0.0"/>

<!-- 多版本 -->
<dubbo:reference interface="com.example.UserService">
    <dubbo:parameter key="version" value="1.0.0"/>
</dubbo:reference>

18. Dubbo的直连

问题:如何实现直连?

答案

xml
<!-- 直连配置 -->
<dubbo:reference interface="com.example.UserService" url="dubbo://localhost:20880"/>

19. Dubbo的只订阅

问题:如何实现只订阅?

答案

xml
<!-- 只订阅配置 -->
<dubbo:reference interface="com.example.UserService" check="false"/>

20. Dubbo的监控

问题:如何监控Dubbo?

答案

  • Dubbo Admin:官方管理控制台。
  • Dubbo Monitor:监控中心。
  • Dubbo Telnet:Telnet命令行工具。

示例

xml
<!-- 配置监控中心 -->
<dubbo:monitor protocol="registry"/>

21. Dubbo的配置优先级

问题:Dubbo配置的优先级是什么?

答案

  • 优先级从高到低
    1. JVM参数
    2. XML配置
    3. Properties配置
    4. 注解配置
    5. API配置

22. Dubbo的SPI

问题:什么是Dubbo SPI?

答案

  • SPI(Service Provider Interface):Dubbo的扩展机制。
  • 作用
    • 扩展Dubbo功能
    • 自定义协议
    • 自定义负载均衡

示例

java
// 定义扩展接口
@SPI("default")
public interface LoadBalance {
    <T> Invoker<T> select(List<Invoker<T>> invokers, URL url, Invocation invocation);
}

// 实现扩展
public class MyLoadBalance implements LoadBalance {
    @Override
    public <T> Invoker<T> select(List<Invoker<T>> invokers, URL url, Invocation invocation) {
        // 自定义负载均衡逻辑
        return invokers.get(0);
    }
}

// 配置扩展
<dubbo:parameter key="loadbalance" value="myLoadBalance"/>

23. Dubbo的过滤器

问题:如何实现过滤器?

答案

java
// 定义过滤器
@Activate(group = {Constants.PROVIDER, Constants.CONSUMER})
public class MyFilter implements Filter {
    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) {
        // 前置处理
        System.out.println("Before invoke");
        
        Result result = invoker.invoke(invocation);
        
        // 后置处理
        System.out.println("After invoke");
        return result;
    }
}

// 配置过滤器
<dubbo:service filter="myFilter"/>

24. Dubbo的路由规则

问题:如何配置路由规则?

答案

xml
<!-- 配置路由规则 -->
<dubbo:registry address="zookeeper://127.0.0.1:2181">
    <dubbo:parameter key="router" value="script"/>
</dubbo:registry>

<!-- 脚本路由 -->
<dubbo:parameter key="router.script" value="function(route) { return route.invokers[0]; }"/>

25. Dubbo的最佳实践

问题:使用Dubbo的最佳实践有哪些?

答案

  • 合理配置超时和重试。
  • 选择合适的负载均衡策略。
  • 使用注册中心实现服务发现。
  • 使用监控中心监控服务。
  • 合理配置集群容错策略。
  • 使用分组和版本管理服务。
  • 使用异步调用提高性能。
  • 使用本地存根减少网络调用。
  • 使用过滤器实现统一处理。
  • 使用SPI扩展Dubbo功能。
  • 合理配置序列化方式。
  • 使用直连测试服务。
  • 合理配置线程池。
  • 定期清理无效服务。