您的当前位置:首页正文

Dubbo总篇

来源:图艺博知识网

源码github

功能特性

  • 实现rpc调用,像调用本地方法一样调用远程server上的方法
  • 支持多协议:(默认Dubbo协议)用户可以根据业务场景选择合适的协议
  • 解耦:利用注册中心,实现服务提供者和消费者之间解耦,也实现服务提供者和提供者之间的解耦,实现灵活的扩展和缩容。
  • 负载均衡:4种策略配合权重,而且支持代码配置和Dubbo控制台动态配置
  • 高可用: 利用注册中心发现功能,一个provider挂了的话,会自动被剔除掉,保证服务器继续对外提供服务,如果重新provider重新恢复的话,又恢复到服务提供队列当中了
  • 重试容错: 支持failover、failfast、forking等多种容错机制
  • 并发控制:服务端(executors)和消费端(actives)都支持不同形式的并发控制
  • 缓存:消费端支持配置3种策略的结果缓存(但是需要自己实现缓存结果超时的配置)
  • 支持两种调用方式:同步(默认)和异步(返回Future对象)两种调用方式
  • 支持权限配置功能:比如白名单功能

Dubbo 原理浅析(基于Dubbo协议)

  1. 每个Provider就是一个Nio的Server,内部机制由Netty实现(也可以是Mina等),两个线程组工作。Provider启动的时候,结合注册中心,暴露对外服务。
  2. Consumer的一个线程发起请求,会获取一个全局的线程ID,然后会把该请求的接口名称、方法名称、参数值等信息封装成一个object的对象
  3. 把 ID,请求Object放在全局的ConcurrentHashMap里面,发起异步的调用,自身用object为锁对象,wait请求线程进入阻塞状态
  4. 调用成功后,触发客户端的监听,然后根据全局ConcurrentHashMap中ID找到object,设置好返回值和回调方法的时候,notifyAll调用的阻塞线程,完成调用

Dubbo配置

配置规则(timeout 、 retries, loadbalance, actives )

  1. 方法级优先,接口级次之,全局配置再次之
  2. 如果级别一样,则消费方优先,提供方次之,其中,服务提供方配置,通过 URL 经由注册中心传递给消费方。作服务的提供者,比服务使用方更清楚服务性能参数,如调用的超时时间,合理的重试次数,等等
  3. 在Provider配置后,Consumer不配置则会使用Provider的配置值,即Provider配置可以作为Consumer的缺省值。否则,Consumer会使用Consumer端的全局设置,这对于Provider不可控的,并且往往是不合理的

默认配置

  1. 默认集群容错方案: failover,超时失败就切换到Provider的其它Node
  2. 默认负载均衡方案:random
  3. 默认调用超时重试的时间: 1s,未响应就重试
  4. 默认重试的次数: retries=2
  5. 默认Dubbo服务接口: port="20880"

其它高级特性

Dubbo 结果缓存(支持3种策略:LRU、FIFO、LFU)

Dubbo的缓存是在服务消费者调用端进行配置的,因为只有业务端才知道自己业务,然后配置相应的策略

配置在消费者上面
<dubbo:reference id="demoService" interface="com.mor.server.dubbo.service.DemoServer"  cache="lru" />

白名单功能

  1. maven项目需要在resources 下创建 META-INF\dubbocom.alibaba.dubbo.rpc.Filter文件
  2. 配置
dubboContextFilter=com.mor.server.dubbo.service.AuthorityFilter
  1. 重写Filter方法

注意事项

  1. 调用参数、返回值都要实现序列号接口,因为交互时需要序列化
public class ProductType implements Serializable{
    private static final long serialVersionUID = -5661679310882808443L;
  1. 前后端的Bean和接口名字要一致,不然报错找不到
    provider.xml
第一个要配置的接口,但是ref要配置的是实际的实现类才行
<dubbo:service interface="com.mor.server.dubbo.service.DemoServer" ref="demoService"  />
  1. 实际上RPC在Consumer端也可以没有Provider的jar包,只需要在本地实现包名一样的接口,也一样

异步调用

  1. 同步调用:看起来是一种阻塞式的调用方式,即 Consumer 端代码一直阻塞等待,直到 Provider 端返回为止。实际上底层 IO 操作都是异步的。Consumer 端发起调用后,得到一个 Future 对象。对于同步调用,业务线程通过Future#get(timeout),阻塞等待 Provider 端将结果返回;timeout则是 Consumer 端定义的超时时间
  2. 异步将来式:future.get(timeout)直接将来式获取结果
  3. 异步回调式:基于Callback 机制

参考博客

Top