前言:或许很多人会使用dubbo,但是阅读源码将使我们更加了解它,以及在未来对它进行改进优化。我就先把flag立在这里了,接下来这阵子将会深入源码进行学习和优化。做为一个要使用dubbo的程序员,必须需要深入理解它,因为dubbo已经停止了维护。
一,dubbo的分层架构
因为是第一篇,这些基础的东西需要先了解,对后面阅读源码也有好处,只做简单介绍,详细的可以看dubbo的官方手册。
1,Service层:该层与实际的业务内容相关,根据服务提供方和消费方提供对应的接口和实现
2,Config层:负责解析spring的配置文件,主要涉及ServiceConfig和ReferenceConfig
3,Proxy层:服务接口透明代理,生成服务的客户端Stub和服务端Skeleton,已ServiceProxy为中心,扩展接口为ProxyFactory
4,Registry层:封装服务地址的注册和发现,以服务URL为中心,扩展为RegistryFactory,Registry和RegistryService,可能没有服务注册中心,此时服务提供方直接暴露服务。
5,Cluster层:封装多个提供者的路由及负载均衡,并桥接注册中心,以Invoker为中心,扩展接口为Cluster,Directory,Router和LoadBalance,将多个服务提供方组合为一个服务提供方,实现对服务消费方来透明,只需要与一个服务提供方进行交互。
6,Monitor层:RPC调用次数和调用时间监控,以Statistics为中心,扩展接口为MonitorFactory,Monitor和MonitorService
7,Protocol层:封装RPC调用,以Invocation和Result为中心,扩展接口为Protocol,Invoker和Exporter。Protocol是服务域,是Invoker暴露和引用的主功能入口,负责Invoker的生命周期管理。Invoker是实体域,是Dubbo的核心模型,其他模型都向他靠拢或者转换为它,它代表一个可执行体,可以向它发起Invoke调用,它有可能是一个本地实现或者一个远程的实现或者一个集群的实现
8,Exchange层:封装请求响应模型,同步转异步,以Request和Response为中心,扩展接口为Exchanger,ExchangeChannel,ExchangeClient和ExchangeServer。
9,Transport层:抽象mina和netty为统一接口,以Message为中心,扩展接口为Channel,Transport,Client,Server和Codec。
10,Serialize层:可复用的一些工具,扩展接口为Serialization,ObjectInput,ObjectOutput和ThreadPool。
二,代码模块划分
1,dubbo-common 公共逻辑模块,包括Util类和通用模型。
2,dubbo-remoting 远程通讯模块,相当于Dubbo协议的实现,如果RPC用RMI协议则不需要使用此包。
3,dubbo-rpc 远程调用模块,抽象各种协议,以及动态代理,只包含一对一的调用,不关心集群的管理。
4,dubbo-cluster 集群模块,将多个服务提供方伪装为一个提供方,包括:负载均衡, 容错,路由等,集群的地址列表可以是静态配置的,也可以是由注册中心下发。
5,dubbo-registry 注册中心模块,基于注册中心下发地址的集群方式,以及对各种注册中心的抽象。
dubbo-monitor 监控模块,统计服务调用次数,调用时间的,调用链跟踪的服务。
6,dubbo-config 配置模块,是Dubbo对外的API,用户通过Config使用Dubbo,隐藏Dubbo所有细节。
7,dubbo-container 容器模块,是一个Standlone的容器,以简单的Main加载Spring启动,因为服务通常不需要Tomcat/JBoss等Web容器的特性,没必要用Web容器去加载服务
三,dubbo-config模块的代码阅读
1,beanutil包(主要是对class的一些定义和对反射的封装)
1.1 JavaBeanAccessor
(这个类相对容易理解,看定义和方法就可以了)
public enum JavaBeanAccessor {
/** Field accessor. */
FIELD,
/** Method accessor.*/
METHOD,
/** Method prefer to field. */
ALL;
public static boolean isAccessByMethod(JavaBeanAccessor accessor) {
return METHOD.equals(accessor) || ALL.equals(accessor);
}
public static boolean isAccessByField(JavaBeanAccessor accessor) {
return FIELD.equals(accessor) || ALL.equals(accessor);
}
}
1.2,JavaBeanDescriptor类。
该类主要定义了表示不同类型的常量
public final class JavaBeanDescriptor implements Serializable, Iterable<Map.Entry<Object, Object>> {
private static final long serialVersionUID = -8505586483570518029L;
public static final int TYPE_CLASS = 1;
public static final int TYPE_ENUM = 2;
public static final int TYPE_COLLECTION = 3;
public static final int TYPE_MAP = 4;
public static final int TYPE_ARRAY = 5;
/** @see com.alibaba.dubbo.common.utils.ReflectUtils#isPrimitive(Class) */
public static final int TYPE_PRIMITIVE = 6;
public static final int TYPE_BEAN = 7;
private static final String ENUM_PROPERTY_NAME = "name";
private static final String CLASS_PROPERTY_NAME = "name";
private static final String PRIMITIVE_PROPERTY_VALUE = "value";
//以下方法省略
}
1.3,JavaBeanSerializeUtil
该类对对象进行序列化成JavaBeanDescriptor。以及可以将JavaBeanDescriptor反序列化为对象。注意里面使用的cache类型为IdentityHashMap。
2,bytecode包
2.1 Proxy类
生成代理对象的工具类,主要是基于javassist的实现
public abstract class Proxy
{
//利用AtomicLong自增获取一个long数组做为生存类的后缀,防止冲突
private static final AtomicLong PROXY_CLASS_COUNTER = new AtomicLong(0);
private static final String PACKAGE_NAME = Proxy.class.getPackage().getName();
public static final InvocationHandler RETURN_NULL_INVOKER = new InvocationHandler(){
public Object invoke(Object proxy, Method method, Object[] args){ return null; }
};
public static final InvocationHandler THROW_UNSUPPORTED_INVOKER = new InvocationHandler(){
public Object invoke(Object proxy, Method method, Object[] args){ throw new UnsupportedOperationException("Method [" + ReflectUtils.getName(method) + "] unimplemented."); }
};
//缓存的map对象
private static final Map<ClassLoader, Map<String, Object>> ProxyCacheMap = new WeakHashMap<ClassLoader, Map<String, Object>>();
private static final Object PendingGenerationMarker = new Object();
/**
* Get proxy.
*
* @param ics interfa