曹耘豪的博客

Dubbo基础知识

  1. 加载点,SPI
    1. @SPI注解
    2. @Adaptive注解
    3. 动态代理方式
  2. 通信实现(Transporter)
  3. 远程调用
    1. 调用流程
    2. Dubbo协议
    3. 对象序列化协议
  4. Dubbo容错机制
    1. 重试机制
    2. 负载均衡

加载点,SPI

Transporter为例,通过SPI实例化的对象都是线程安全单例

@SPI注解

SPI注解的value就是该接口实现的默认实现类,value的值对应META-INF下的接口同名文件内。比如这里,value = netty,在org.apache.dubbo.remoting.Transporter文件里,netty对应org.apache.dubbo.remoting.transport.netty4.NettyTransporter这个实现类

1
2
3
4
5
6
7
8
9
10
11
// Transporter.java
@SPI(value = "netty", scope = ExtensionScope.FRAMEWORK)
public interface Transporter {

@Adaptive({"server", "transporter"})
RemotingServer bind(URL url, ChannelHandler handler) throws RemotingException;

@Adaptive({"client", "transporter"})
Client connect(URL url, ChannelHandler handler) throws RemotingException;

}
1
2
3
4
// META-INF/dubbo/internal/org.apache.dubbo.remoting.Transporter
netty3=org.apache.dubbo.remoting.transport.netty.NettyTransporter
netty4=org.apache.dubbo.remoting.transport.netty4.NettyTransporter
netty=org.apache.dubbo.remoting.transport.netty4.NettyTransporter

@Adaptive注解

通过参数动态获取实现类。比如,传入的URL如果包含server=netty3或transporter=netty3,则使用netty3的实现类,即org.apache.dubbo.remoting.transport.netty.NettyTransporter

动态代理方式

通信实现(Transporter)

底层通信方式,org.apache.dubbo.remoting.Transporter

远程调用

调用流程

Cluster -> Invoker -> Router -> LoadBalance -> Invoker

客户端 -> 路由 -> 负载均衡 -> IO线程池(读写、序列化和反序列化)

Dubbo协议

构造Dubbo协议

对象序列化协议

org.apache.dubbo.common.serialize.Serialization

源码使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// ExchangeCodec.class
protected void encodeRequest(Channel channel, ChannelBuffer buffer, Request req) {
ObjectOutput out = serialization.serialize(channel.getUrl(), bos);
// ...
encodeRequestData(channel, out, req.getData(), req.getVersion());
}

// ExchangeCodec.class
protected Object decodeBody(Channel channel, InputStream is, byte[] header) {
// ...
Object data = decodeResponseData(channel, CodecSupport.deserialize(channel.getUrl(), is, proto), getRequestData(id));
}

// CodecSupport.class
public static ObjectInput deserialize(URL url, InputStream is, byte proto) throws IOException {
Serialization s = getSerialization(url, proto);
return s.deserialize(url, is);
}

Dubbo容错机制

重试机制

负载均衡

org.apache.dubbo.rpc.cluster.LoadBalance

   /