快速开始:http://dubbo.apache.org/en-us/docs/user/quick-start.html
依赖:http://dubbo.apache.org/en-us/docs/user/dependencies.html
Dubbo官方文档提供了一个最简单的快速入门示例,但它存在一点问题。本文从无到有,演示如何把这个最简单的示例运行起来。
创建名为dubbo-demo的项目,其中包括三个模块:
dubbo-demo-api,定义服务接口接口dubbo-demo-provider,实现服务接口dubbo-demo-consumer,引用服务接口新创建一个Maven简单项目,下一步:
填写Group Id、Artifact Id、Version、Packaging,其中Packaging是pom,点Finish按钮,生成的项目如下图所示:
把其中的src目录删除,接下来修改一下pom,修改后内容如下:
<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>aaa.bbb.ccc</groupId> <artifactId>dubbo-demo</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>pom</packaging> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <jdk.version>10</jdk.version> <maven.compiler.source>10</maven.compiler.source> <maven.compiler.target>10</maven.compiler.target> </properties> </project>只是增加properties属性,因为我本机安装的jdk是10.0.2,所以设置的值都是10,这个根据自己环境自行调整,但是Dubbo规定jdk的版本要1.6+。
接下来添加dubbo-demo-api模块。用鼠标右击项目dubbo-demo,从弹出的菜单中选择Maven,再从弹出的菜单中选择新建Maven模块,如下图,写上模块名、选上创建简单项目即可,其它使用默认值。
重复此操作,创建dubbo-demo-provider、dubbo-demo-consumer两个模块。最后结果如下图:
Eclipse自动向pom添加与Module有关的内容,现在dubbo-demo的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>aaa.bbb.ccc</groupId> <artifactId>dubbo-demo</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>pom</packaging> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <jdk.version>10</jdk.version> <maven.compiler.source>10</maven.compiler.source> <maven.compiler.target>10</maven.compiler.target> </properties> <modules> <module>dubbo-demo-api</module> <module>dubbo-demo-provider</module> <module>dubbo-demo-consumer</module> </modules> </project>按官方参考文档,向dubbo-demo-api模块中添加包org.apache.dubbo.demo,在包下边添加接口DemoService,结果如下图:
DemoService.java中的代码,直接从官网复制:
package org.apache.dubbo.demo; public interface DemoService { String sayHello(String name); }本模块只是定义共享接口供provider与consumer使用,没有其它额外的依赖,也不用修改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> <parent> <groupId>aaa.bbb.ccc</groupId> <artifactId>dubbo-demo</artifactId> <version>0.0.1-SNAPSHOT</version> </parent> <artifactId>dubbo-demo-api</artifactId> </project>然后运行一下Maven的install命令,把这个接口打包安装到本地的Maven仓库,以便在其它模块中引用它。
右击模块名称,选择Run As,再选择Maven build...,如下图所示,在Goals中写入install:
然后点一下run按钮,从console确认一下jar包已经安装到本地仓库。
因为实现接口时要依赖定义接口的jar包、dubbo的jar包、日志模块的jar包等,因此先修改其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> <parent> <groupId>aaa.bbb.ccc</groupId> <artifactId>dubbo-demo</artifactId> <version>0.0.1-SNAPSHOT</version> </parent> <artifactId>dubbo-demo-provider</artifactId> <dependencies> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.6.6</version> <exclusions> <exclusion> <groupId>org.jboss.netty</groupId> <artifactId>netty</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>io.netty</groupId> <artifactId>netty-all</artifactId> <version>4.0.35.Final</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.16</version> </dependency> <dependency> <groupId>aaa.bbb.ccc</groupId> <artifactId>dubbo-demo-api</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> </dependencies> </project>官方文档中用的dubbo版本为2.5,9,如果用这个版本程序将无法运行(可能是向前兼容问题。定义配置文件的xsd应该修改过,2.5.9用这个xsd时会报配置文件格式错误)。我这里用的是2.6.6,发布版中的最新版本。本来在依赖dubbo时,项目会间接的依赖netty包,但是这个默认依赖的包好像缺东西,程序无法正常运行,因此强制排除,然后显式依赖netty-all这个包,这个包比较全。
然后是log4j,用来输出日志。再然后就是刚才定义的共享接口的包。
修改好pom后更新一下模块,看一下本模块的依赖状态,如下图所示:
其中spring、commons-logging、javassist等是dubbo间接依赖进来的,文档里有介绍。如果想使用其它版本的话可以像netty一样强制排除,然后再显式加入自己依赖的版本。
另外像netty-all、log4j等版本是官方考虑稳定性、性能等推荐选用的,文档上有说明,就按这个来。
接下来向模块中添加自定义包、添加接口实现代码、服务启动代码等:
DemoServiceImpl.java从文档中直接复制,内容如下:
package org.apache.dubbo.demo.provider; import org.apache.dubbo.demo.DemoService; public class DemoServiceImpl implements DemoService { @Override public String sayHello(String name) { return "Hello " + name; } }Provider.java代码:
package org.apache.dubbo.demo.provider; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Provider { public static void main(String[] args) throws Exception { System.setProperty("java.net.preferIPv4Stack", "true"); @SuppressWarnings("resource") ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( new String[] { "META-INF/spring/dubbo-demo-provider.xml" }); context.start(); System.out.println("Provider started."); System.in.read(); // press any key to exit } }接下来按文档在src/main/resources目录下添加配置文件,一个与dubbo有关,一个与日志有关。最后目录结构如下:
dubbo-demo-provider.xml内容,从文档复制的,不用修改:
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://dubbo.apache.org/schema/dubbo" xmlns="http://www.springframework.org/schema/beans" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd"> <!-- provider's application name, used for tracing dependency relationship --> <dubbo:application name="demo-provider"/> <!-- use multicast registry center to export service --> <dubbo:registry address="multicast://224.5.6.7:1234"/> <!-- use dubbo protocol to export service on port 20880 --> <dubbo:protocol name="dubbo" port="20880"/> <!-- service implementation, as same as regular local bean --> <bean id="demoService" class="org.apache.dubbo.demo.provider.DemoServiceImpl"/> <!-- declare the service interface to be exported --> <dubbo:service interface="org.apache.dubbo.demo.DemoService" ref="demoService"/> </beans>log4j.properties也是从文档复制,不用修改,内容如下:
###set log levels### log4j.rootLogger=info, stdout ###output to the console### log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.Target=System.out log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=[%d{dd/MM/yy hh:mm:ss:sss z}] %t %5p %c{2}: %m%n运行一下代码,从控制台确认一下输出:
会有一些警告,不用在意。这样Provider已经运行起来,可以对外提供服务了。
我们知道Dubbo有一个Registry用来发布、定阅服务,推荐的Registry是Zookeeper。这个例子中用的是Multicast方式,非常简单,不用依赖额外的包,也不用启动额外的服务,测试的话没有问题。
Consumer的依赖与Provider一样,把Provider中的dependency配置复制过来就行,内容如下:
<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> <parent> <groupId>aaa.bbb.ccc</groupId> <artifactId>dubbo-demo</artifactId> <version>0.0.1-SNAPSHOT</version> </parent> <artifactId>dubbo-demo-consumer</artifactId> <dependencies> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.6.6</version> <exclusions> <exclusion> <groupId>org.jboss.netty</groupId> <artifactId>netty</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>io.netty</groupId> <artifactId>netty-all</artifactId> <version>4.0.35.Final</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.16</version> </dependency> <dependency> <groupId>aaa.bbb.ccc</groupId> <artifactId>dubbo-demo-api</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> </dependencies> </project>然后是配置文件,目录结构与Provider相同,其中日志的配置相同。直接把Provider中src/main/resources目录下的内容全部复制过来,然后将dubbo-demo-provider.xml改成dubbo-demo-consumer.xml,把内容按文档改一下就可以。最后目录结构如下:
dubbo-demo-consumer.xml内容如下:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://dubbo.apache.org/schema/dubbo" xmlns="http://www.springframework.org/schema/beans" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd"> <!-- consumer's application name, used for tracing dependency relationship (not a matching criterion), don't set it same as provider --> <dubbo:application name="demo-consumer"> <dubbo:parameter key="qos.enable" value="true" /> <dubbo:parameter key="qos.accept.foreign.ip" value="false" /> <dubbo:parameter key="qos.port" value="33333" /> </dubbo:application> <!-- use multicast registry center to discover service --> <dubbo:registry address="multicast://224.5.6.7:1234" /> <!-- generate proxy for the remote service, then demoService can be used in the same way as the local regular interface --> <dubbo:reference id="demoService" check="false" interface="org.apache.dubbo.demo.DemoService" /> </beans>这个文件的内容与官方文档稍有差别,增加了如下几行内容:
<dubbo:parameter key="qos.enable" value="true"/> <dubbo:parameter key="qos.accept.foreign.ip" value="false"/> <dubbo:parameter key="qos.port" value="33333"/>Dubbo在启动Provider与Consumer时,同时还会启动一个telnet服务,这个服务用来远程管理、运维Provider与Consumer实例。默认这个服务占用22222端口。因为在本例中Provider与Consumer启动在同一台主机上,因此22222端口已经被Provider占用,所以要为consumer显式的配置另外一个端口,否则会报端口已绑定的错误。
接下来按文档向项目中添加package、代码,结果如下:
Consumer.java内容:
package org.apache.dubbo.demo.consumer; import org.apache.dubbo.demo.DemoService; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Consumer { public static void main(String[] args) { @SuppressWarnings("resource") ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( new String[] { "META-INF/spring/dubbo-demo-consumer.xml" }); context.start(); // Obtaining a remote service proxy DemoService demoService = (DemoService) context.getBean("demoService"); // Executing remote methods String hello = demoService.sayHello("world"); // Display the call result System.out.println(hello); } }运行一下程序,输出如下:
这样一个最简单的Dubbo实例就运行起来了。