八股文-Dubbo

Dubbo通过spring.handlers对spring进行扩展,对spring强依赖。相关代码在dubbo-config包的DubboNamespaceHandler中,由DubboBeanDefinitionParser进行配置解析(2017/12/22将Annotation的解析剥离至AnnotationBeanDefinitionParser)。

DubboBeanDefinitionParser设计上将不同配置的解析混杂在一起。低版本service的ref属性解析做了提前Bean定义校验,导致Dubbo在定义时必须位于Spring Bean定义之后。

1
2
3
4
BeanDefinition refBean = parserContext.getRegistry().getBeanDefinition(value);
if (!refBean.isSingleton()) {
throw new IllegalStateException("The exported service ref " + value + " must be singleton! Please set the " + value + " bean scope to singleton, eg: <bean id=\"" + value + "\" scope=\"singleton\" ...>");
}

服务时序图

暴露服务

吐槽

日志系统

Dubbo内部通过自定义的Logger接口进行日志输出,代码内部通过LoggerFactory实现了JCL、slf4j、jdk、Log4J的适配。
优先采用系统属性dubbo.application.logger定义的类,而后依次试测试Log4J、slf4j、JCL、JDK是否可用。
过度设计,自造轮子,完全可以用slf4j代替。

Filter机制

Dubbo通过内部匿名类来构造Invoker的链式调用实现,具体代码参考com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper#buildInvokerChain
个人比较倾向Tomcat中Filter(org.apache.catalina.core.ApplicationFilterChain)和Struts中Interceptor(com.opensymphony.xwork2.DefaultActionInvocation)的实现思路,Struts采用Iterator进行递归调用,Tomcat采用计数来模拟Iterator。

Dubbo协议编解码

DubboCodec继承关系为 Codec -> AbstractCodec -> TransportCodec -> TelnetCodec -> ExchangeCodec -> DubboCodec。

编码的文档信息里面掺杂IP和TCP的无用信息,Dubbo未修改IP和TCP层,故无需考虑。具体协议头参见文档中->实现细节->远程通讯细节->协议头约定。

Dubbo编码未以字节为单位进行划分,详细结构如图(Dubbo文档中字节3的内容描述错误):

1
2
3
4
5
6
7
BYTE   0       2                                          3        4    11            15
BIT 0 15 16 17 18 23 31 95 127
+-------+---------+---------+-------+--------------+--------+----+-------------+------+
| MAGIC | REQ/RES | TWO_WAY | EVENT | CONTENT_TYPE | STATUS | ID | DATA_LENGTH | DATA |
+-------+---------+---------+-------+--------------+--------+----+-------------+------+
LENGTH | 16 | 1 | 1 | 1 | 5 | 8 | 64 | 32 | DATA |
+-------+---------+---------+-------+--------------+--------+----+-------------+------+
标题名
MAGIC 0xDABB
REQ/RES 1 Request
2 Response
TWO_WAY 1 TWO WAY
EVENT 1 EVENT
CONTENT_TYPE Serialization Type:
1 Dubbo
2 Hessian2
3 Java
4 CompatedJava
5 Json
6 FastJson
STATUS Response Status:
20 OK
30 CLIENT_TIMEOUT
31 SERVER_TIMEOUT
40 BAD_REQUEST
50 BAD_RESPONSE
60 SERVICE_NOT_FOUND
70 SERVICE_ERROR
80 SERVER_ERROR
90 CLIENT_ERROR
ID Incrementable ID
DATA When EVENT=1, HEARTBEAT=null; READONLY=‘R’