Appearance
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配置的优先级是什么?
答案:
- 优先级从高到低:
- JVM参数
- XML配置
- Properties配置
- 注解配置
- 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功能。
- 合理配置序列化方式。
- 使用直连测试服务。
- 合理配置线程池。
- 定期清理无效服务。
