dubbo源码分析系列——项目工程结构介绍

摘要

dubbo是目前国内最流行的分布式服务框架,已经俨然成为行业的标准了,多数无自研能力的公司都在使用这个框架,而且这个框架本身非常具有代表性,即使很多公司自研的分布式服务框架也都是对dubbo的扩展或者借鉴了该框架,因此研究它的源码意义还是非常大的,对于掌握分布式服务框架的原理和实现细节有着非常好的帮助。

项目源码地址

本系列文章是基于当当网维护的dubbox版本进行分析的,源码地址参考:https://github.com/dangdangdotcom/dubbox

项目源码结构

我们下载源码后导入到ide中可以看到如此之多的项目组成,真的是非常之多的项目组成,而且用到的技术也非常多,redis、zookeeper,netty等等,不禁让人心生畏惧,这么大的工程源码该如何下手阅读呢?我们必须理清楚这些工程的职责和关系,才能够抽丝剥茧的把dubbo搞清楚。

核心项目间关系

结构图说明

为了让图保持清晰明了,该图特意忽略了一些具体的api实现模块,只保留了核心的一些借口定义模块,而具体技术实现的模块忽略了。通过分析dubbo的各项目及组成关系分析出该项目如下特点。

  1. duubo的项目划分得非常细。因此导致工程数目达到几十个之多,这样的好处就是开发者可以根据自己的需求去编译符合需求的包,只保留自己需要用到的模块。缺点是导致工程接口的非常复杂。
  2. 强大的可扩展性和灵活性。dubbo抽象出了很多核心接口,而针对这些接口都提供了不同的实现了,开发者可以根据自己的需要选择各种实现,也可以根据需要扩展开发自己的实现,具有非常强大的扩展和定制能力。

核心模块职责介绍

dubbo-common

通用模块,定义了几乎所有dubbo模块都会使用到的一些通用与业务领域无关的工具类(io处理、日志处理、配置处理、类处理等等),线程池扩展、二进制代码处理、class编译处理、json处理、数据存储接口,系统版本号等等通用的类和接口。

dubbo-rpc-api

分布式服务框架的核心是rpc,这是最基本的功能,这个模块定义了rpc的一些抽象的rpc接口和实现类,包括服务发布,服务调用代理,远程调用结果及异常,rpc调用网络协议,rpc调用监听器和过滤器等等。该模块提供了默认的基于dubbo协议的实现模块,还提供了hessian、http、rest、rmi、thrift和webservice等协议的实现,还实现了injvm的本地调用实现,灵活性强,非常通用,能够满足绝大多数项目的使用需求,而且还可以自行实现rpc协议。

dubbo-registry-api

注册中心也是最重要的组成部分,它是rpc中的consumer和provider两个重要角色的协调者。该项目定义了核心的注册中心接口和实现。具体实现留给了其它项目。有一个默认的实现模块,组册中心提供了mutilcast、redis和zookeeper等多种方式的注册中心实现,用于不同的使用场景。

dubbo-remoting-api

该模块是dubbo中的远程通讯模块。rpc的实现基础就是远程通讯,consmer要调用provider的远程方法必须通过网络远程通讯实现。该模块定义了远程传输器、终端(endpoint)、客户端、服务端、编码解码器、数据交换、缓冲区、通讯异常定义等等核心的接口及类构成。他是对于远程网络通讯的抽象。提供了诸如netty、mina、grizzly、http、p2p和zookeeper的协议和技术框架的实现方式。

dubbo-monitor-api

该模块是dubbo的监控模块,通过该模块可以监控服务调用的各种信息,例如调用耗时、调用量、调用结果等等,监控中心在调用过程中收集调用的信息,发送到监控服务,在监控服务中可以存储这些信息,对这些数据进行统计分析,最终可以产生各种维护的调用监控信息。dubbo默认提供了一个实现,该实现非常简单,只是作为默认的实现范例,生产环境使用价值不高,需要自行实现自己的监控。

dubbo-container-api

dubbo服务运行容器api模块。定义了启动容器列表的包含应用程序入口main方法的类Main;定义了容器接口Container,该接口包含了启动和停止方法定义;还有一些通用的分页功能的相关类。dubbo内置了javaconfig、jetty、log4j、logback和spring几种容器的实现。

dubbo-config-api

从图中可以看出改模块依赖了几乎所有的其它模块,他是dubbo的配置模块,通过它的配置和组装将dubbo组件的多个模块整合在一起给最终的开发者提供有价值的分布式服务框架。通过它的配置可以让开发者选择符合自己需求和使用场景的模块和技术,它定义了面向dubbo使用者的各种信息配置,比如服务发布配置、方法发布配置、服务消费配置、应用程序配置、注册中心配置、协议配置、监控配置等等。另外还有一个spring的配置模块,定义了一些spring的XML Schema,能够大大简化使用dubbo的配置,可以大大降低spring使用场景的学习和配置成本。

dubbo-cluster

该模块是dubbo实现的集群模块。支持远程服务的集群,支持多种集群调用策略,包括failover,failsafe,failfast,failback,forking等。并且支持目录服务,注册中心就是目录服务的一种实现,支持负载均衡,该模块还实现了路由器特性,此外还包括合并技术,当将调用请求分发给所有的服务提供者,则会返回多个结果,则将多个结果合并需要用到合并器的实现,该模块也是非常重要的一个模块。

dubbo-admin

该项目是一个web应用,可以独立部署,它可以管理dubbo服务,通过该管理应用可以连接注册中心,重点是读取注册中心中的信息,也可以通过该应用改写注册中心的信息,从而实现动态的管控服务。该模块的功能也非常简单,对于实际的生产使用场景,还需要对该应用的功能进行扩展和定制,以满足实际的使用场景。

总结

通过分析项目结构,让我们对dubbo有了一个全面系统的了解,尤其是对于它的组成结构,但是这只是一个开始,对于细节的掌握,我们还需要逐层深入,进入到每个具体的项目和类中去探索它的实现细节。

我们可以看出来dubbo是一个设计比较精良的项目,它的项目和代码组织结构合理;并且它又是一个非常庞大的项目,涉及的具体技术包含方方面面,如果不进行良好的设计,那项目的质量也无法保障,也要求它必须进行良好的设计;同时它又是一个非常通用和灵活的框架项目,该项目定义了大量的api和配置,也提供了很多框架和技术的实现方案,因此它能够适应绝大多数的使用场景,另外又具有非常灵活的配置和扩展能力,因此也能够非常方便地扩展实现以满足自己个性化的需求,它的广泛流行也是有其必然原因的。

从它的设计中又印证了我一直比较认同的一种设计模式。就是分层设计模型:

底层是一些通用和支撑性的通用模块,比如dubbo-commom、dubbo-remoting-api,它们是非常通用的,不解决任何领域业务问题,可使用于全部或者多数业务领域模块;

中间层是核心业务领域模块。它们相互组合协作完成一个完整的对使用者有价值的功能特性,分布式服务框架里面就是dubbo-rpc-api远程调用、dubbo-registry-api是注册中心、dubbo-monitor-api是监控中心和dubbo-container-api等。模块化设计降低了代码复杂度和缩小了关注焦点,也有利于分工协作,还方便各模块能够独立演变;结构化良好的中间层才能够灵活应对各种技术和业务需求的演变。

上层是用户界面模块。该层会将结构化良好的中间层服务进行配置和组装,整合成为一个对用户有价值的打包服务,在该层要考虑的是用户体验,降低用户的学习和使用成本,这就需要面向用户类型、用户使用场景进行设计,用户类型需要了解用户掌握的知识,环境和使用场景,依据这些特性进行设计,面向原生java环境使用dubbo-config-api模块去配置使用dubbo,面向使用spring环境则使用dubbo-config-spring模块,该层是主要是为了降低用户的学习使用成本,填补内部结构和用户之间的知识、技能方面的鸿沟。

dubbo整体架构和流程图

next

dubbo-rpc-api是最为核心的模块,我们将从该模块入手来研究。

时间: 2024-11-06 09:32:02

dubbo源码分析系列——项目工程结构介绍的相关文章

Dubbo源码分析系列-服务的发布

RPC简化类图 RPC模块核心接口和抽象实现 默认实现Dubbo协议的接口和抽象实现 服务发布过程 调用过程 上图是服务提供者暴露服务的主过程: 首先ServiceConfig类拿到对外提供服务的实际类ref(如:HelloWorldImpl),然后通过ProxyFactory类的getInvoker方法使用ref生成一个AbstractProxyInvoker实例,到这一步就完成具体服务到Invoker的转化.接下来就是Invoker转换到Exporter的过程. Dubbo处理服务暴露的关键

Dubbo源码分析系列-扩展机制的实现

Spring可扩展Schema 像标签dubbo:monitor.dubbo:service.dubbo:provider等怎么读的,读完之后怎么又是怎么解析的呢? 以上标签都是基于Spring可扩展Schema提供的自定义配置 下面举个例子 1)创建JavaBean 首先设计好配置项,通过JavaBean来建模,如类People public class People { private String name; private Integer age; } 2)编写XSD文件 XSD文件是X

Dubbo源码分析系列---扩展点加载

扩展点配置: 约定: 在扩展类的jar包内,放置扩展点配置文件:META-INF/dubbo/接口全限定名,内容为:配置名=扩展实现类全限定名,多个实现类用换行符分隔.(摘自dubbo文档) 示例: 假如我现在想使用自己定义的协议Myprotocol,在resources目录下新建META-INF/dubbo/com.alibaba.dubbo.rpc.Protocol目录文件,文件内容定义: myprotocol=com.selrain.MyProtocol 实现类内容: public cla

Dubbo 源码分析系列之三 —— 架构原理

1 核心功能 首先要了解Dubbo提供的三大核心功能: Remoting:远程通讯 提供对多种NIO框架抽象封装,包括"同步转异步"和"请求-响应"模式的信息交换方式. Cluster: 服务框架 提供基于接口方法的透明远程过程调用,包括多协议支持,以及软负载均衡,失败容错,地址路由,动态配置等集群支持. Registry: 服务注册中心 基于注册中心目录服务,使服务消费方能动态的查找服务提供方,使地址透明,使服务提供方可以平滑增加或减少机器. 2 Dubbo各个组

Dubbo 源码分析 - 服务导出全过程解析

1.服务导出过程 本篇文章,我们来研究一下 Dubbo 导出服务的过程.Dubbo 服务导出过程始于 Spring 容器发布刷新事件,Dubbo 在接收到事件后,会立即执行服务导出逻辑.整个逻辑大致可分为三个部分,第一是前置工作,主要用于检查参数,组装 URL.第二是导出服务,包含导出服务到本地 (JVM),和导出服务到远程两个过程.第三是向注册中心注册服务,用于服务发现.本篇文章将会对这三个部分代码进行详细的分析,在分析之前,我们先来了解一下服务的导出过程. Dubbo 支持两种服务导出方式,

Dubbo 源码分析 - 集群容错之 LoadBalance

1.简介 LoadBalance 中文意思为负载均衡,它的职责是将网络请求,或者其他形式的负载"均摊"到不同的机器上.避免集群中部分服务器压力过大,而另一些服务器比较空闲的情况.通过负载均衡,可以让每台服务器获取到适合自己处理能力的负载.在为高负载的服务器分流的同时,还可以避免资源浪费,一举两得.负载均衡可分为软件负载均衡和硬件负载均衡.在我们日常开发中,一般很难接触到硬件负载均衡.但软件负载均衡还是能够接触到一些的,比如 Nginx.在 Dubbo 中,也有负载均衡的概念和相应的实现

Cordova Android源码分析系列一(项目总览和CordovaActivity分析)

PhoneGap/Cordova是一个专业的移动应用开发框架,是一个全面的WEB APP开发的框架,提供了以WEB形式来访问终端设备的API的功能.这对于采用WEB APP进行开发者来说是个福音,这可以避免了原生开发的某些功能.Cordova 只是个原生外壳,app的内核是一个完整的webapp,需要调用的原生功能将以原生插件的形式实现,以暴露js接口的方式调用. Cordova Android项目是Cordova Android原生部分的Java代码实现,提供了Android原生代码和上层We

【Dubbo源码阅读系列】服务暴露之远程暴露

引言 什么叫 远程暴露 ?试着想象着这么一种场景:假设我们新增了一台服务器 A,专门用于发送短信提示给指定用户.那么问题来了,我们的 Message 服务上线之后,应该如何告知调用方服务器,服务器 A 提供了 Message 功能?那么我们是不是可以把目前已提供的服务暴露在一个地方,让调用方知道某台机器提供了某个特定功能?带着这样的假设,我们今天就来聊聊 Dubbo 服务暴露之远程暴露!! 服务远程暴露 先回顾一下上篇文章,上篇文章我们聊到了 ServiceConfig 的 export() 方

【Dubbo源码阅读系列】之远程服务调用(上)

今天打算来讲一讲 Dubbo 服务远程调用.笔者在开始看 Dubbo 远程服务相关源码的时候,看的有点迷糊.后来慢慢明白 Dubbo 远程服务的调用的本质就是动态代理模式的一种实现.本地消费者无须知道远程服务具体的实现,消费者和提供者通过代理类来进行交互!! 一.JAVA 动态代理 简单看一段代码回顾一下动态代理: public class MyInvocationHandler implements InvocationHandler{ private Object object; publi