要创建基于dubbo的多层级目录分类的多工程聚合分布式Maven工程,首先就得了解什么是Dubbo
1 Dubbo
1.1什么是Dubbo
Dubbo是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案。简单的说,dubbo就是个服务框架
其核心部分为:
n 远程通讯: 提供对多种基于长连接的NIO框架抽象封装,包括多种线程模型,序列化,以及“请求-响应”模式的信息交换方式。
n 集群容错: 提供基于接口方法的透明远程过程调用,包括多协议支持,以及软负载均衡,失败容错,地址路由,动态配置等集群支持。
n 自动发现: 基于注册中心目录服务,使服务消费方能动态的查找服务提供方,使地址透明,使服务提供方可以平滑增加或减少机器。
1.2Dubbo能做什么
n 透明化的远程方法调用,就像调用本地方法一样调用远程方法,只需简单配置,没有任何API侵入。
n 软负载均衡及容错机制,可在内网替代F5等硬件负载均衡器,降低成本,减少单点。
n 服务自动注册与发现,不再需要写死服务提供方地址,注册中心基于接口名查询服务提供者的IP地址,并且能够平滑添加或删除服务提供者
1.3Dubbo架构
节点角色说明:
n Provider: 暴露服务的服务提供方。
n Consumer: 调用远程服务的服务消费方。
n Registry: 服务注册与发现的注册中心。
n Monitor: 统计服务的调用次调和调用时间的监控中心。
n Container: 服务运行容器
调用关系说明:
n 0服务容器负责启动,加载,运行服务提供者。
n 1服务提供者在启动时,向注册中心注册自己提供的服务。
n 2服务消费者在启动时,向注册中心订阅自己所需的服务。
n 3 注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
n 4 服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
n 5 服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。
1.4Dubbo使用方法
Dubbo采用全Spring配置方式,透明化接入应用,对应用没有任何API侵入,只需用Spring加载Dubbo的配置即可,Dubbo基于Spring的Schema扩展进行加载。如果不想使用Spring配置,而希望通过API的方式进行调用(不推荐) Dubbo采用全Spring配置方式,透明化接入应用,对应用没有任何API侵入,只需用Spring加载Dubbo的配置即可,Dubbo基于Spring的Schema扩展进行加载。
2 环境搭建
首先基于Dubbo分布式环境的“服务注册与发现的注册中心”、“统计服务的调用次调和调用时间的监控中心”以及“Maven”的搭建过程就不在这里阐述了,搭建过程比较简单,网上有很多的介绍。
注:
n 服务注册与发现的注册中心(Registry):采用的是Zookeeper。
n 统计服务的调用次调和调用时间的监控中心(Monitor):采用的是dubbo-admin
2.1搭建过程
2.1.1 搭建暴露服务的服务提供方(Provider)
因为我们要搭建的是基于dubbo的多层级目录分类的多工程聚合分布式Maven工程。所以我们首先要先创建一个【Maven Project】:
2.1.1.1 在eclipse中右键【new→Other→Maven→MavenProject】新建Maven Project:
如下图所示:
2.1.1.2 点击【Next>】,在此页面勾选“Create a simple project(skip archetype selection)”选项后,其他内容保持不变
如下图所示:
2.1.1.3 点击【Next>】,在出现的页面中填写如下内容:
n Group Id:如com.test.dap
n Artifact Id:如:a-platform-test-app
n Version:系统会自动给默认值,也可以自行修改
n Packaging:因为我们创建的是“聚合”工程,因此在此部分必须选择为【pom】
以上内容创建好后点击【Finish】即可。如下图所示:
2.1.1.4 点击【Finish】后如下图所示:
2.1.1.5 工程创建好后将不需要的工程目录包删除,
如下图所示:
2.1.1.6 然后根据自己架构的需要,在此maven工程上创建自己的工程目录结构,创建好的目录结构
如下图所示:
其中:
n biz:为业务层
n common:数据层
n core:领域模型
2.1.1.7 目录结构创建好之后,我们要对pom文件进行修改,修改后的pom.xml内容如下:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.test.dap</groupId> <artifactId>a-platform-test-app</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>pom</packaging> <name>a-platform-test-app</name> <description>基于dubbo的多层级目录分类的多工程聚合分布式Maven工程</description>
<dependencies> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.5.10</version> <exclusions> <exclusion> <groupId>org.springframework</groupId> <artifactId>spring</artifactId> </exclusion> </exclusions> </dependency> <!-- ZooKeeper client --> <dependency> <groupId>com.github.sgroschupf</groupId> <artifactId>zkclient</artifactId> <version>0.1</version> </dependency> <!-- spring相关 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>3.2.16.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>3.2.16.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>3.2.16.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>3.2.16.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>3.2.16.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>3.2.16.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>3.2.16.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>3.2.16.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>3.2.16.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>3.2.16.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>3.2.9.RELEASE</version> </dependency>
</dependencies>
<!-- project build --> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.6.0</version> <configuration> <source>1.8</source> <target>1.8</target> <encoding>UTF-8</encoding> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-source-plugin</artifactId> <version>3.0.1</version> <executions> <execution> <id>attach-sources</id> <goals> <goal>jar</goal> </goals> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-eclipse-plugin</artifactId> <version>2.10</version> <configuration> <downloadSources>true</downloadSources> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.19.1</version> </plugin> </plugins> </build> <!-- modules --> <modules> <module>app/biz/shared</module> <module>app/biz/service-impl</module> <module>app/core/service</module> <module>app/core/model</module> <module>app/common/util</module> <module>app/common/service/facade</module> <module>app/common/service/integration</module> <module>app/common/dal</module> </modules> </project> |
2.1.1.8 基于maven父工程,创建其各个层级的子工程
注:所创建的子工程【Packaging】属性为【jar】
鼠标左键选中工程【a-platform-test-app】,然后右键【new→Other→Maven→Maven Module】,如下图所示:
2.1.1.9 点击【Next>】进入到Maven Module新建页面,在此页面输入要创建的Module工程名子
如下图所示:
在此图中我们可以看到创建的Module工程的父工程为【a-platform-test-app】
2.1.1.10 点击【Next>】,选择“maven-archetype-quickstart”
如下图所示:
注:“maven-archetype-quickstart”代表什么意思,在这不进行阐述,可以网络上自行查询
2.1.1.11 点击【Next>】进入到Module的配置页面,我们在此页面只需要修改一下【Package】即可
如下图所示:
2.1.1.12 修改【Package】后,点击【Finish】完成Maven Module工程的创建
如下图所示:
此时我们可以看到,新创建的【service-impl】工程并没有在【app→biz】下,这也是问题的关键。
在此我们先回顾一下我们修改的【a-platform-test-app】工程下的pom文件中的内容,其中有一块,我们是将各层级结构都已经提前配置好了,如下所示:
<modules> <module>app/biz/shared</module> <module>app/biz/service-impl</module> <module>app/core/service</module> <module>app/core/model</module> <module>app/common/util</module> <module>app/common/service/facade</module> <module>app/common/service/integration</module> <module>app/common/dal</module> </modules> |
2.1.1.13 修改【service-impl】工程中的pom.xml文件
而现在我们首先需要修改一下【service-impl】工程中的pom.xml文件。让【service-impl】工程使用父工程【a-platform-test-app】的pom.xml文件。只需要定位到父工程pom文件的位置即可。如下图所示:
注:填写的位置为什么是【../../../pom.xml】,是因为我们会将【service-impl】工程移动到【app→biz】目录下,在此目录下定定位到父工程的pom.xml文件正好是向上【三级“../../../”】。修改完成保存即可。如果路径配置正确显示如下:
将父工程pom中配置的jar都引用了过来。
2.1.1.14 移动【service-impl】工程到【app→biz】目录下
如下图所示:
点击【OK】,如下图所示:
移动完成后,我们点击父工程pom文件显示如下:
2.1.1.15 对【service-impl】工程的pom文件中的【Aritfact Id】以及【Name】进行修改
如下图所示:
注:以上两个内容也可以不修改。修改的目的是为了后续开发可读性更好一些。
2.1.1.16 以上就是一个子工程的创建过程,按此方式在父工程的各级目录下把相应的子工程创建好,在此就不一一进行阐述了
如下图所示:
现对各层级子工程的作用说明如下:
n app→biz-service-impl:facade接口等具体实现层接口的实现
n app→biz-shared:业务共享层,实现一些业务上的通用逻辑,如定时任务、批处理等
n app→common→dal:数据访问层,如mysql
n app→common→util: 系统工具类,如StringUtils,Assert,DataUtils等
n app→common→service-facade:发布服务 (即门面,系统与外部系统交互的窗口)
最终要生成jar发布到maven中,为前端web提供调用(对外暴露的接口)
n app→common→service-integration: 服务集成,如集成外部服务接口,配置中心,缓存,存储等服务
n app→core→model:领域模型层,主要功能为建立领域模型
n app→core→service:领域服务层。领域服务解决本领域的问题,不直接对外部系统外提供服务,这是与facade接口层的最主要区别
2.1.1.17 修改父工程的pom文件
打开pom文件,我们可以看到之前直接配置的Modules还存在,如下图所示:
我们只保留最新创建的Modules,之前配置的都删除即可,如下图所示:
2.1.1.18 到此服务提供方的分布式架构已经创建完成,此时我们将工程【a-platform-test-app】与eclipse进行分离,然后再重新导入
如下图所示:
n 分离
n 重新导入
n 点击【Next>】进入到导入页面,选择要导入的工程,如下图所示:
n 点击【Finish】完成导入,如下图所示:
注1:如图所示,这也就是我们为什么要这么创建多层级目录分类的多工程聚合分布式Maven工程的原因(开发清晰、各工程包独立)
注2:通过此方式的创建,每个子工程下都会生成样例类,这些类没有什么用,我们直接删除即可。
2.1.1.19 服务提供方创建完成后,我们创建样例进行服务端验证和注册
1) 首先创建对外接口,如下图所示:
2) 创建对应的实现类:
n 对接口进行依赖注入:
n 创建实现类:
3) 添加配置文件dubbo-application.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd "> <!-- 具体的实现bean --> <bean id="appTestService" class="com.test.dap.service.impl.AppTestServiceImpl" /> <!-- 提供方应用信息,用于计算依赖关系 --> <dubbo:application name="provider" /> <!-- 使用zookeeper注册中心暴露服务地址 --> <dubbo:registry address="zookeeper://127.0.0.1:2181" /> <!-- 用dubbo协议在20880端口暴露服务 --> <dubbo:protocol name="dubbo" port="29014" /> <!-- 声明需要暴露的服务接口 --> <dubbo:service interface="com.test.dap.facade.AppTestService" ref="appTestService" /> </beans> |
如下图所示:
4) 创建服务端验证和注册类
5) 运行,验证
注:运行/验证的前提是Zookeeper与dubbo-admin都已经启动了。
运行结果显示如下图所示:
6) 此时我们在dubbo-admin中对注册的服务接口进行查找,如下图所示:
7) 到此,我们完成了服务端接口的注册及验证
2.1.1.20 将接口发布到maven中
1) 鼠标右键接口工程,如下图所示:
2) 点击【Maven install】,显示如下:
表示已经打包成jar,并发布到maven中,如下图所示:
2.1.2 搭建调用远程服务的服务消费方(Consumer)
2.1.2.1 在eclipse中右键【new→Other→Maven→MavenProject】新建Maven Project:
如下图所示:
注:创建过程同服务提供方父工程创建过程相同,在此只对特殊地方进行阐述
2.1.2.2 配置pom文件
在此pom文件中就比服务提供方的pom文件多了一个【provider的jar包】
<dependency> <groupId>com.test.dap</groupId> <artifactId>a-platform-test-app-common-service-facade</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> |
以及子工程配置的目录的变化
<modules> <module>consumer/web</module> </modules> |
2.1.2.3 创建子工程
注:创建过程同服务提供方相同,在此不再进行阐述,只对差异点进行描述。
在创建子工程时,因为是web工程,因此在创建时要做如下选择:
注:因创建的是web工程,所以Packagin为【war】,可以部署在应用服务器中。如下图所示:
创建好如下图所示:
2.1.2.4 到此调用远程服务的服务消费方已经创建完成,创建完成后我们创建样例进行消费方的注册和调用服务方的验证
n 创建配置文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd "> <!-- 消费方应用名,用于计算依赖关系,不是匹配条件,不要与提供方一样 --> <dubbo:application name="consumer" /> <!-- 使用multicast广播注册中心暴露发现服务地址 --> <dubbo:registry protocol="zookeeper" address="zookeeper://127.0.0.1:2181" /> <!-- 生成远程服务代理,可以和本地bean一样使用demoService --> <dubbo:reference id="appTestService" interface="com.test.dap.facade.AppTestService" /> </beans> |
n 创建验证java类
n 运行类【ConsumerServiceWebTest.java】,运行结果如图所示:
n 此结果与服务端接口实现工程中所配置的相同,如图所示:
n 此时,我们再回到dubbo-admin中,查看一下消费方注册的情况
到此完成了基于dubbo的分布式架构的搭建。后续还可以针对此架构进行内容上的丰富,比如引入springmvc或者其他。
源码下载地址:https://download.csdn.net/download/josong/10502171