作为一个分布式框架Dubbo在项目中使用逐步越来越多,通过该框架很容易实现分布式,之前已经写了一个大致步骤,今天有时间就整理一下,写一个完整的实例作为记录一下过程,
在项目进行之前,首先下载并搭建maven服务,建立maven本地仓库,然后在eclipse中配置maven,步骤如下,
Eclipse -> Window -> Preferences
一,分布式项目框架建立;
因为是分布式项目,所以可以是相互分散在不同的物理机上,通过dubbo框架建立通信,项目有些公共的东西,也有些是相互不同,所以这里项目建立一个父子工程,父工程用于整合各个子项目,子项目分别完成各自的功能,最终完成如下图;
其中 dubbo03为父工程,子工程dubbo03api为提供公共项工程,如api和model,子工程dubbo03provider为服务提供端工程,子工程dubbo03consumer为服务消费端工程,需要注意的是建立父工程后,先不要修改对应pom.xml文件(否则添加子模块时该文件出现莫名其妙的异常),而是紧接着添加各个子工程,完成之后,这样父工程的 pom.xml 就自动增加了各个子模块,然后再对各个工程进行修改;注意在所有项目增加之前,
二,父工程建立;
父工程主要作为管理工程,
Eclipse -> File -> New -> Maven Project
注意图中红框之处,把其中的src目录删除,只留下 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.qyh01</groupId> <artifactId>dubbo03</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>pom</packaging> <name>dubbo03</name> <description>dubbo03实例</description> <properties> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <!-- spring版本号 --> <spring.version>4.2.5.RELEASE</spring.version> <!-- log4j日志包版本号 --> <slf4j.version>1.7.18</slf4j.version> <log4j.version>1.2.17</log4j.version> </properties> <dependencyManagement> <dependencies> <!-- start: 添加spring 和 junit4依赖 --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>${spring.version}</version> </dependency> <!-- end: 添加spring 和 junit4依赖 --> <!-- start: 添加日志相关jar包 --> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>${log4j.version}</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>${slf4j.version}</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>${slf4j.version}</version> </dependency> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.2</version> </dependency> <!-- start: 添加日志相关jar包 --> <!-- start: dubbo依赖相关 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.5.3</version> <exclusions> <exclusion> <groupId>org.springframework</groupId> <artifactId>spring</artifactId> </exclusion> </exclusions> </dependency> <!-- end: dubbo依赖相关 --> <!-- start: 注册中心Zookeeper zkclient依赖--> <dependency> <groupId>com.github.sgroschupf</groupId> <artifactId>zkclient</artifactId> <version>0.1</version> </dependency> <!-- end: 注册中心Zookeeper zkclient依赖--> </dependencies> </dependencyManagement> <modules> <module>dubbo03api</module> <module>dubbo03provider</module> <module>dubbo03consumer</module> </modules> </project>
三,公共子项目API建立;
API工程注意是定义服务接口和对应的model模型,服务的提供端和消费端将都是用到,
右键单击 dubbo03工程 -> New -> Other,弹出的窗口,左边选中 maven 展开后选择 Maven Module,如下图,
点击下一步,
Next(下一步),
Next(下一步),
最后点击 Finish 完成,最后如下图,
在api工程的 src/main/ 建立java文件夹,然后在其上分别建立两个包 org.dubbo03.api 和 org.dubbo03.model ,右键点击src/main -> New -> Package,如下图,
同样方式建立 org.dubbo03.model,如下图,
1,公共API接口定义;
这里定义的接口就是提供服务的接口,在 org.dubbo03.api 定义一个接口,如下,
/** * dubbo 实例 * @author shenzhenNBA */ package org.dubbo03.api; import org.dubbo03.model.Product; /** * 接口定义 * @since 2018.05.18. */ public interface ProductService { public Product getProductByCode(String productCode); }
最终如下图,
2,公共model建立
同样在 org.dubbo03.model 定义一个Product的模型,如下,
/** * dubbo 实例 * @author shenzhenNBA */ package org.dubbo03.model; /** * @author shenzhenNBA * @since 2018.05.18. */ public class Product implements java.io.Serializable { private static final long serialVersionUID = 2018051801000L; private String productCode; private String productName; private Integer productNumber; private String userName; public Product() { super(); } public Product(String productCode, String productName, Integer productNumber, String userName) { super(); this.productCode = productCode; this.productName = productName; this.productNumber = productNumber; this.userName = userName; } public String getProductCode() { return productCode; } public void setProductCode(String productCode) { this.productCode = productCode; } public String getProductName() { return productName; } public void setProductName(String productName) { this.productName = productName; } public Integer getProductNumber() { return productNumber; } public void setProductNumber(Integer productNumber) { this.productNumber = productNumber; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } }最终如下图,
3,修改 api 工程的 pom.xml,如下,
<?xml version="1.0"?> <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>com.qyh01</groupId> <artifactId>dubbo03</artifactId> <version>0.0.1-SNAPSHOT</version> </parent> <groupId>com.qyh01</groupId> <artifactId>dubbo03api</artifactId> <version>0.0.1-SNAPSHOT</version> <name>dubbo03api</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> </dependency> </dependencies> </project>
四,服务提供端Provider子项目建立;
参照 api 工程的方式,在本工程中本分别建立 src/main/java 和 src/main/resources 文件夹,然后在 src/main/java 上建立 org.dubbo03.provider 和 org.dubbo03.service.impl 两个包,在 src/main/resources 下建立 dubboProvider.xml 和 日志的 log4j.xml 文件,最终如下图,
1,实现API接口,完成接口具体业务功能;
/** * dubbo 实例 * @author shenzhenNBA */ package org.dubbo03.service.impl; import org.dubbo03.api.ProductService; import org.dubbo03.model.Product; /** * 接口实现类 * @since 2018.05.18. */ public class ProductServiceImpl implements ProductService { @Override public Product getProductByCode(String productCode) { //query from DB system, more operation in here if (null == productCode || productCode.trim().isEmpty()) { return null; } else { return new Product("product001","优质大米001号",120,"张三"); } } }
2,建立服务提供端的启动类;
/** * dubbo 实例 * @author shenzhenNBA */ package org.dubbo03.provider; import java.io.IOException; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * provider main启动类 * @since 2018.05.18. * zookeeper地址 F:\SoftwareTool\zookeeper\zookeeper-3.5.2-alpha\bin\zkServer.cmd */ public class ProviderMain { public static void main(String[] args) throws IOException{ ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("classpath:dubboProvider.xml"); System.out.println(context.getDisplayName() + ": show name here"); context.start(); System.out.println("======================================================="); System.out.println("Dubbo provider run//Dubbo服务提供端已经启动..."); System.out.println("======================================================="); System.out.println("注意:依次按如下顺序启动"); System.out.println("1,首先运行 zookeeper 启动服务注册服务中心,根据情况可以不使用zk服务注册中心"); System.out.println("2,其次运行 provider 服务提供端"); System.out.println("3,最后运行 consumer 服务消费端"); System.out.println("======================================================="); System.in.read(); context.close(); } }
3,建立dubbo相关的配置文件,提供对外服务;
<?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-admin 或 dubbo-monitor 会显示该名字,方便识别--> <dubbo:application name="dubboProvider" owner="programmer" organization="dubbox"/> <!--使用 zookeeper 注册中心暴露服务,注意要先开启 zookeeper,配置见conf文件夹下,默认zoo.cfg--> <!-- <dubbo:registry address="zookeeper://localhost:2181"/> --> <!-- 如果不使用 zookeeper 等服务注册中心,则启动如下配置即可,注意不能省去 --> <dubbo:registry address="N/A" /> <!-- 用dubbo协议在20880端口暴露服务,当不用 zk 注册服务中心是必须定义该协议和端口,消费端方可使用 --> <dubbo:protocol name="dubbo" port="20880" /> <!--使用 dubbo 协议实现定义好的 api工程的 ProductService 接口--> <dubbo:service interface="org.dubbo03.api.ProductService" ref="productService" protocol="dubbo" /> <!--具体实现该接口的 bean,见provider工程的实践类--> <bean id="productService" class="org.dubbo03.service.impl.ProductServiceImpl"/> </beans>
注意,有时看到配置文件左边出现几个红叉,这个是对应的 xsd 文件无法找到引起出现的,注意dubbo的 jar 里面含有这个文件,Eclipse -> Window -> Preferences 弹出如下窗口,
按图中顺序选中 xsd 文件,然后在第5不中对应key输入对应的值即可,其实如果正确引入dubbo的 jar 包,出现红叉也不影响运行的,我这里就是引入 xsd 文件同样出现红叉,但是不影响运行;
相关的 log4j.xml 日志的配置文件如下,
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="false"> <appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender"> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="[%d{dd/MM/yy hh:mm:ss:sss z}] %t %5p %c{2}: %m%n" /> </layout> </appender> <root> <level value="INFO" /> <appender-ref ref="CONSOLE" /> </root> </log4j:configuration>
4,修改工程的 pom.xml 文件,
<?xml version="1.0"?> <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>com.qyh01</groupId> <artifactId>dubbo03</artifactId> <version>0.0.1-SNAPSHOT</version> </parent> <groupId>com.qyh01</groupId> <artifactId>dubbo03provider</artifactId> <version>0.0.1-SNAPSHOT</version> <name>dubbo03provider</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <!-- start: 相关接口jar包依赖增加 --> <dependency> <groupId>com.qyh01</groupId> <artifactId>dubbo03api</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> <!-- end: 相关接口jar包依赖增加 --> <!-- start: 添加spring 和 junit4依赖 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> </dependency> <!-- end: 添加spring 和 junit4依赖 --> <!-- start: 添加日志相关jar包 --> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> </dependency> <!-- start: 添加日志相关jar包 --> <!-- start: dubbo相关依赖增加 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <exclusions> <exclusion> <groupId>org.springframework</groupId> <artifactId>spring</artifactId> </exclusion> </exclusions> </dependency> <!-- start: dubbo相关依赖增加 --> <!-- start: 服务注册中心Zookeeper zkclient依赖增加--> <dependency> <groupId>com.github.sgroschupf</groupId> <artifactId>zkclient</artifactId> </dependency> <!-- end: 服务注册中心Zookeeper zkclient依赖增加--> </dependencies> </project>
五,服务消费端Consumer子项目建立;
参照 Provider 工程的方式,在本工程中分别建立 src/main/java 和 src/main/resources 文件夹,然后在 src/main/java 上建立 org.dubbo03.consumer 包,在 src/main/resources 下建立 dubboConsumer.xml 和 日志的 log4j.xml 文件,最终如下图,
1,建立dubbo相关的配置文件,去哪获取服务;
<?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-admin 或 dubbo-monitor 会显示该名字,方便识别--> <dubbo:application name="dubboConsumer" owner="programmer" organization="dubbox"/> <!--使用 zookeeper 注册中心暴露服务,注意要先开启 zookeeper,配置见conf文件夹下,默认zoo.cfg--> <!-- <dubbo:registry address="zookeeper://localhost:2181"/> --> <!-- 如果不使用 zookeeper 等服务注册中心,则启动如下配置即可,注意不能省去 --> <dubbo:registry address="N/A" /> <!--使用 dubbo 协议实现定义好的 api 工程的 ProductService 接口--> <!-- <dubbo:reference id="productService" interface="org.dubbo03.api.ProductService"/> --> <!-- 当不使用 zookeeper 等服务注册中心时使用如下配置,其实关键是需指定url以及指定dubbo协议,url格式如下: url="dubbo://ip:port/provider工程的dubbo配置文件中相关dubbo:service标签的interface属性值" --> <dubbo:reference id="consumerService" interface="org.dubbo03.api.ProductService" url="dubbo://localhost:20880/org.dubbo03.api.ProductService"/> </beans>
如果正确引入dubbo的 jar 包,配置文件左边出现红叉也不影响运行的;
与之相关的 log4j.xml 日志的配置文件如下,
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="false"> <appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender"> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="[%d{dd/MM/yy hh:mm:ss:sss z}] %t %5p %c{2}: %m%n" /> </layout> </appender> <root> <level value="INFO" /> <appender-ref ref="CONSOLE" /> </root> </log4j:configuration>
2,修改工程的 pom.xml 文件,
<?xml version="1.0"?> <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>com.qyh01</groupId> <artifactId>dubbo03</artifactId> <version>0.0.1-SNAPSHOT</version> </parent> <groupId>com.qyh01</groupId> <artifactId>dubbo03consumer</artifactId> <version>0.0.1-SNAPSHOT</version> <name>dubbo03consumer</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <!-- start: 相关接口jar包依赖增加 --> <dependency> <groupId>com.qyh01</groupId> <artifactId>dubbo03api</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> <!-- end: 相关接口jar包依赖增加 --> <!-- start: 添加spring 和 junit4依赖 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> </dependency> <!-- end: 添加spring 和 junit4依赖 --> <!-- start: dubbo相关依赖增加 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <exclusions> <exclusion> <groupId>org.springframework</groupId> <artifactId>spring</artifactId> </exclusion> </exclusions> </dependency> <!-- start: dubbo相关依赖增加 --> <!-- start: 服务注册中心Zookeeper zkclient依赖增加--> <dependency> <groupId>com.github.sgroschupf</groupId> <artifactId>zkclient</artifactId> </dependency> <!-- end: 服务注册中心Zookeeper zkclient依赖增加--> </dependencies> </project>
3,消费端获取并使用对应的分布式服务,
/** * dubbo 实例 * @author shenzhenNBA */ package org.dubbo03.consumer; import org.dubbo03.api.ProductService; import org.dubbo03.model.Product; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * 消费端 * @since 2018.05.18. */ public class ConsumerMain { public static void main(String[] args) { ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("dubboConsumer.xml"); context.start(); System.out.println("dubbo consumer start here"); ProductService productService = (ProductService) context.getBean(ProductService.class); Product product = productService.getProductByCode("pro01"); System.out.println("Dubbo consumer//Dubbo服务消费端运行"); System.out.println("======================================================="); if (null == product) { System.out.println("product empty "); } else { System.out.println("product name: " + product.getProductName()); System.out.println("product code: " + product.getProductCode()); System.out.println("product num: " + product.getProductNumber()); System.out.println("product user: " + product.getUserName()); } System.out.println("======================================================="); context.close(); } }
六,启动,
启动问题,启动有先后顺序,
(1)如果使用 zookeeper 作为注册服务中心,一般是上线时会用到,则需要首先到网上下载该软件,根据需要自己修改配置,需要首先启动 zk ,然后在启动服务提供端 Provider ,再次启动服务消费端 Consumer;
(2)如果不使用 zookeeper 其实也可以,这一般是在开发阶段,这个时候就必须先启动服务提供端 Provider ,其次启动服务消费端 Consumer,否则顺序倒了启动出问题;
例如不使用 zk 启动时:右键单击 ProviderMain 类 -> Run as -> Java application,如下图所示,
同样,右键单击 ConsumerMain 类 -> Run as -> Java application,首先切换一下,如下图所示,
然后看到消费端运行的结果,如下图所示,
这里可以看到消费端确实调用了服务提供端的功能;
七,注意;
一般服务提供端端实现了相关功能,并配置提供对外服务,消费端才能通过相关配置,才知道去哪里获取服务然后使用,所以服务的提供端和消费端的配置文件相应的端口或暴露的服务接口要一样,否则就找不到;当上线时一般使用 zookeeper 作为服务注册中心,需先启动,然后才启动提供端和消费端;当开发过程不使用 zk 时,则必须首先启动服务提供端,然后再启动消费端,在服务提供端的 dubbo 配置文件必须增加
<dubbo:protocol name="dubbo" port="指定端口" />
配置 dubbo 协议相关信息,然后消费端的 dubbo 配置文件可以通过
<dubbo:reference id="consumerService" interface="api工程的接口xxx.yyy.kkk.zzzService"
url="dubbo://ip:指定端口/api工程的接口xxx.yyy.kkk.zzzService"/>
该配置 dubbo 找到,完整例子请到这里下载 https://download.csdn.net/download/shenzhennba/10440019
好了,写了蛮久,就到此吧,欢迎拍砖...