在本系列教程中, 我们会动手实践快速构建一个完整的服务器和客户端程序。 应用程序很简单:服务器会接收客户端发来的消息, 然后将消息不做任何处理返回给客户端。 通过本示例程序来帮助读者熟悉Dubbo框架。 应用程序可以通过XML、 注解和API这3种方式来编写, 本节教程主要介绍基于XML的实现。
所有的Dubbo服务接口都可以直接通过配置对外暴露, 但用户不需要额外编写服务暴露的代码, 因为这些都被Dubbo框架隐藏了, 用于降低框架使用门槛, 用户只需要专注以下内容:
• 关注业务场景, 编写面向接口的业务代码;
• 少量的启动配置, 比如配置中心和暴露的协议等
那我们开始吧!
Dubbo框架是面向接口的RPC调用框架, 需要提供一个新的接口 Echoservice来作为服务暴露使用, 该接口会响应传入的消息。
下面我们来定义及实现这个接口, 首先是接口的定义, 代码如下:
代码清单 EchoService.java
package com.wondream.dubbo.samples.echo.api
public interface EchoService {
String echo(String message);
}
然后是接口的实现,代码如下:
代码清单 EchoServicelmpI.java
package com.wondream.dubbo.samples.echo.impl;
import com.alibaba.dubbo.rpc.RpcContext;
import com.wondream.dubbo.samples.echo.api.EchoService;
import java.text.SimpleDateFormat;
import java.util.Date;
public class EchoServicelmpI implements EchoService {
public String echo(String message) {
String now = new SimpleDateFormat("HH:mm:ss").format(new Date());
System.out.printin("[" + now + "] Hello " + message + ", request from consumer: " + RpcContext.getContext().getRemoteAddress());
return message;
}
}
以上就是我们需要关注的接口定义及接口实现。 其中Echoservice接口在后面章节中会用到。 如果要让这个接口能正常提供服务, 那么还需要做一些额外配置: 把配置文件echo-provider.xml 放到项目目录 src/main/resources/spring/下:
<?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.xsd
http://dubbo.apache.org/schema/dubbo
http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
<!--服务提供方应用名称, 方便用于依赖跟踪-->
<dubbo:application name="echo-provider"/>
< !--使用本地ZooKeeper作为注册中心-->
<dubbo:registry address=Hzookeeper://127.0.0.1:2181"/>
<!--只用Dubbo协议并且指定监听2088。 端口 -->
<dubbo:protocol name="dubbo" port="20880"/>
< !--通过XML方式把实现配置为Bean,让Spring托管和实例化-->
<bean id="echoService" class="com.alibaba.dubbo.samples.echo.impl.EchoServiceImpl"/>
< !--声明要暴露的接口 -- >
<dubbo:service interface="com.alibaba.dubbo.samples.echo.api.EchoService" ref="echoService"/>
</beans>
配置完成后, 我们还要动手编写一些代码来启动服务,代码如下:
代码清单 启动Dubbo服务
package com.wondream.dubbo.samples.echo;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class EchoProvider {
public static void main(String[] args) throws Exception {
// 指定服务暴露配置文件
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"spring/echo-provider.xml"});
// 启动Spring容器并暴露服务
context.start();
System.in.read();
}
}
在开始执行前请确保已经正确启动ZooKeeper服务器 。 后面会介绍通过Maven命令行启动服务, 本节我们直接在IDE中“Debug”这个EchoProvider服务并运行, 然后在终端中用Telnet模拟客户端调用。
// 使用Telnet连接本地20890端口
telnet localhost 20890
// 执行调用方法
invoke com.alibaba.dubbo.samples.echo.api.EchoService.echo("hello world!")
// 得到返回结果,共耗时3ms
"hello world!"
elapsed 3 ms.
其中, invoke指令会发起Dubbo服务调用, 该指令采用[接口 .方法] 格式调用, 采用JSON格式传递参数
注意:
通过手写启动代码, 可以帮助我们了解Dubbo框架在启动时做的事情。 Dubbo框架启动时默认
会通过Spring的容器来启动(本质上也是通过ClassPathXmlApplicationContext来启动服务的)o
一般生产环境中用shell脚本启动DubbOo对应的启动类是com.alibaba.dubbo. container.Main,
它的原理是利用扩展点加载Spring容器, 然后激活Spring框架加载配置。
在客户端只依赖服务暴露的接口的情况下, 使用Dubbo框架能够让我们把关注点放在编写服务消费逻辑上, 而不必去关心网络连接和序列化等底层技术, 但我们还是要提供一些框架依赖的配置, 这个配置echo-consumer .xml放到项目目录src/main/resources/spring中:
<?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.xsd
http://dubbo.apache.org/schema/dubbo
http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
<!--服务消费方应用名称, 方便用于依赖跟踪-->
<dubbo:application name="echo-consumer" />
< !--使用本地ZooKeeper作为注册中心-->
<dubbo:registry address="zookeeper://127.0.0.1:2181"/>
< !--指定要消费的服务-->
<dubbo:reference id="echoService" check="false" interface="com.alibaba.dubbo.samples.echo.api.EchoService"/>
</beans>
这些依赖配置主要告诉框架使用ZooKeeper作为注册中心, 并且基于XML配置要消费的服务, 消费的服务定义会被Spring托管。 和服务提供方类似, 我们需要动手编写服务消费启动代码, 代码如下:
代码清单 基于XML方式消费服务
package com.wondream.dubbo.samples.echo;
import com.alibaba.dubbo.samples.echo.api.EchoService;
import org.springframework.context.support,ClassPathXmlApplicationContext;
public class EchoConsumer {
public static void main(String[] args) {
// 加载配置
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]("spring/echo-consumer.xml"});
// 获取消费代理
context.start();
// 获取远程服务
EchoService echoService = (EchoService) context.getBean("echoService");
// 调用远程方法
String status = echoService.echo("Hello world!");
System.out.println("echo result: " + status);
}
}
通过简单的几行代码, 就可以完成分布式环境下的RPC调用。 上述代码成功运行后会输出
echo result: Hello world!