梳理这篇文章的目的很简单,duboo官方已经不在维护,里面的各种第三方库依赖的版本很老。dubbox的官方demo又太复杂,因此结合dubbox的新版本和duboo官方的demo文档梳理了一个最简单入门程序,目的是能让没用过duboo的同学,可以快速的体验一下。
创建maven工程
dubbo-deom-parent:父项目,主要用来统一管理包的版本,是一个pom工程
dubbo-demo-api:子项目,定义了服务接口,本列中是一个jar工程
dubbo-demo-provider:子项目,定义了服务的提供者,有些地方称为服务端,本列中是一个jar工程
dubbo-demo-consumer:子项目,定义了服务消费者,有些地方称为客户端,本列中是一个jar工程
为了快速体验,注册中心采用multicast,之后的文章,会切换到zookeeper。
由于dubbo官方的版本停留在2.5.3,且停止了维护,所以这里我采用自己在本地编译dubbox最新的版本2.8.4,编译很简单:
git clone https://github.com/dangdangdotcom/dubbox
mvn clean install -Dmaven.test.skip=true
到此,所有的准备工作就做好了,接下来一步一步的实现每个工程,每个工程都以pom文件->代码->配置文件的
注意:
父工程就是一个pom工程,其中dependencyManagement主要是包管理的目的,以便在子项目中不用再指定版本号。
虽然我们指定了spring版本为4.3.8.RELEASE,但是由于通过spring-framework-bom,最终我们得到还是dubbo工程里用到的spring3版本
demo非常简单,所以只需要引入dubbo就可以了,其他的maven会自动通过依赖传递引入
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.mocoline.demo</groupId>
<artifactId>dubbo-demo-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>dubbo-demo-api</module>
<module>dubbo-demo-consumer</module>
<module>dubbo-demo-provider</module>
</modules>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-framework-bom</artifactId>
<version>4.3.8.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.8.4</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.1</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
接口定义,这一层通常都是定义业务需要调用的实体和方法,不包含具体的业务逻辑。
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>com.mocoline.demo</groupId>
<artifactId>dubbo-demo-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>dubbo-demo-api</artifactId>
</project>
接口定义:
package com.mocoline.demo.dubbo;
public interface DemoService {
String sayHello(String name);
}
接口非常简单,就是返回一句话,没有其他的配置依赖。
接口的实现,这一层通常是实现具体的业务逻辑的地方,由于要暴露服务接口,所以需要依赖dubbo的接口,具体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>
<parent>
<groupId>com.mocoline.demo</groupId>
<artifactId>dubbo-demo-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>dubbo-demo-provider</artifactId>
<dependencies>
<dependency>
<groupId>com.mocoline.demo</groupId>
<artifactId>dubbo-demo-api</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
</dependency>
</dependencies>
</project>
实现服务接口:
package com.mocoline.demo.dubbo.impl;
import java.text.SimpleDateFormat;
import java.util.Date;
import com.mocoline.demo.dubbo.DemoService;
public class DemoServiceImpl implements DemoService {
public String sayHello(String name) {
System.out.println("[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "] Hello " + name);
return "Hello " + name;
}
}
通过dubbo将服务发布出去:
package com.mocoline.demo.dubbo;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Provider {
public static void main(String[] args) throws Exception {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] { "provider.xml" });
context.start();
System.out.println("provider is running, press any key to exit");
System.in.read();
System.out.println("provider exits");
}
}
依赖关系和dubbo信息的配置都在provider.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">
<!-- 提供方应用信息,用于计算依赖关系 -->
<dubbo:application name="hello-world-app" />
<!-- 使用multicast广播注册中心暴露服务地址 -->
<dubbo:registry address="multicast://224.5.6.7:1234" />
<!-- 用dubbo协议在20880端口暴露服务 -->
<dubbo:protocol name="dubbo" port="20880" />
<!-- 声明需要暴露的服务接口 -->
<dubbo:service interface="com.mocoline.demo.dubbo.DemoService" ref="demoService" />
<!-- 和本地bean一样实现服务 -->
<bean id="demoService" class="com.mocoline.demo.dubbo.impl.DemoServiceImpl" />
</beans>
直接运行Provider,看到如下提示说明服务已经运行,处于等待消费的状态:
接口的调用者,由于要通过duboo调用服务提供者,所以要依赖duboo,具体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>
<parent>
<groupId>com.mocoline.demo</groupId>
<artifactId>dubbo-demo-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>dubbo-demo-consumer</artifactId>
<dependencies>
<dependency>
<groupId>com.mocoline.demo</groupId>
<artifactId>dubbo-demo-api</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
</dependency>
</dependencies>
</project>
具体的调用过程:
package com.mocoline.demo.dubbo;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Consumer {
public static void main(String[] args) throws Exception {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"consumer.xml"});
context.start();
DemoService demoService = (DemoService)context.getBean("demoService"); // 获取远程服务代理
String hello = demoService.sayHello("world"); // 执行远程方法
System.out.println( hello ); // 显示调用结果
}
}
可以看出,调用远程服务的时候,和普通本地调用完全一样。具体的依赖关系通过配置文件consumer.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">
<!-- 消费方应用名,用于计算依赖关系,不是匹配条件,不要与提供方一样 -->
<dubbo:application name="consumer-of-helloworld-app" />
<!-- 使用multicast广播注册中心暴露发现服务地址 -->
<dubbo:registry address="multicast://224.5.6.7:1234" />
<!-- 生成远程服务代理,可以和本地bean一样使用demoService -->
<dubbo:reference id="demoService" interface="com.mocoline.demo.dubbo.DemoService" />
</beans>
代码完成,如果刚才的provider还没退出,那么运行Consumer可以看到:
从上面的例子可以看到:
Consumer成功调用了Provider实现的api接口。
在代码结构上,Consumer和Provider是完全独立的,这一点通过pom的配置文件可以看出,两个工程是没有任何依赖,他们共同依赖的只有api的声明和dubbo相关的内容。
dubbo会将服务提供着的业务实现发布到指定的端口;同时在消费者本地创建一个远程调用的代理,具体的调用过程,完全由dubbo去完成。