Dubbo通过spring.handlers对spring进行扩展,对spring强依赖。相关代码在dubbo-config包的DubboNamespaceHandler中,由DubboBeanDefinitionParser进行配置解析(2017/12/22将Annotation的解析剥离至AnnotationBeanDefinitionParser)。
DubboBeanDefinitionParser设计上将不同配置的解析混杂在一起。低版本service的ref属性解析做了提前Bean定义校验,导致Dubbo在定义时必须位于Spring Bean定义之后。
1 | BeanDefinition refBean = parserContext.getRegistry().getBeanDefinition(value); |
服务时序图
暴露服务
吐槽
日志系统
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 | BYTE 0 2 3 4 11 15 |
标题名 | 值 |
---|---|
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’ |