Apache Dubbo 是一款高性能、轻量级的开源 Java RPC 框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。
Dubbo调用流程
provider流程
第0步,start启动服务
第1步,注册提供者信息到注册中心
consumer流程
第2步,subscribe订阅使用到的服务提供者列表,并缓存到本地
第3步【异步】,当服务提供者发生变化时,注册中心notify服务消费者,获取最新的服务列表,更新本地缓存
invoke调用
第4步,consumer直接发起对provider的调用,无需经过注册中心,而对多个provider的负载均衡,consumer通过cluster组件实现
count监控
第5步【异步】,consumer和provider都异步通知监控中心
Dubbo 异常处理
dubbo的异常处理类是com.alibaba.dubbo.rpc.filter.ExceptionFilter 类,源码这里就不贴了.归纳下对异常的处理分为下面几类:
- 如果provider实现了GenericService接口,直接抛出
- 如果是checked异常,直接抛出
- 在方法签名上有声明,直接抛出
- 异常类和接口类在同一jar包里,直接抛出
- 是JDK自带的异常,直接抛出
- 是Dubbo本身的异常,直接抛出
- 否则,包装成RuntimeException抛给客户端
如何使用自定义异常
- 自定义异常声明为checked异常,直接继承Exception类
- api方法声明抛出该自定义异常
- 把自定义异常放在api包中
- 重写ExceptionFilter,允许直接返回指定的自定义异常
Dubbo 对调用结果进行缓存
Dubbo通过CacheFilter过滤器,提供对结果缓存的功能,既可以适用于Consumer也可以适用与Provider。目前提供了三种实现:
- lru:基于最近最少使用原则,保持最热数据被缓存。通过继承LinkedHashMap实现。
- threadlocal:当前线程缓存。
- jcache:可以桥接各种缓存实现。
本地暴露和远程暴露的区别
远程暴露:consumer调用provider是跨进程的,需要进行网络通信。
本地暴露:使用 injvm:// 协议,是一个伪协议,它不开启端口,不发起远程调用,但执行Dubbo的filter链。
Dubbo 有哪些负债均衡策略
- Random LoadBalance:随机,按权重设置随机概率。
- RoundRobin LoadBalance:轮询,按公约后的权重设置轮询比率。
- LeastActive LoadBalance:最少活跃调用数,相同活跃数的随机。使慢的提供者收到更少的请求,因为越慢的提供者的调用前后计数差(时间差)会越大。
- ConsistentHash LoadBalance:一致性Hash,相同参数的请求总是发到同一提供者。
Dubbo 有哪些集群容错策略
- Failover Cluster:失败自动切换,重试其他服务器,默认值。通常用于读操作,但重试会带来更长延迟。可通过
retries="2"
来设置重试次数(不含第一次)。 - Failfast Cluster:快速失败,只发起一次调用,失败立即报错。通常用于非幂等性的写操作,例如新增记录。
- Failsafe Cluster:失败安全,出现异常时,直接忽略。通常用于写入审计日志等操作。
- Failback Cluster:失败自动恢复,后台记录失败请求,定时重发。通常用于消息通知操作。
- Forking Cluster:并行调用多个服务器,只要一个成功即返回。通常用于实时性要求较高的读操作,但需要浪费更多服务资源。可通过
forks="2"
来设置最大并行数。 - Broadcast Cluster:广播调用所有提供者,逐个调用,任意一台报错则报错。通常用于通知所有提供者更新缓存或日志等本地资源信息。
Dubbo 其他知识点
- 支持的通信协议有9中,常见的有dubbo和rest协议。
- 支持点对点直连,以服务接口为单位忽略注册中心的提供者列表。另外,直连provider时,如果要debug调试provider,禁用该provider注册到注册中心。否则,会被其他consumer调用到。
- Dubbo使用Javassist和JDK两种方式实现动态代理。
- Dubbo可使用 Apache SkyWalking 组件实现链路追踪。
- Dubbo可使用 Sentinel 组件实现服务降级。