在谈及Dubbo之前,需要先对远程RPC调用了解:
1.什么是远程RPC调用?
回忆我们在本地调用一个方法:
public class MainClass{
public void main(String[] args){
new AClass().aMethod(params...);
}
}
AClass类的具体信息必须是对本地可见的。这样就会出现一个问题:如果本地希望调用一个异地方法,该怎么做?方法的细节已经不再对本地暴露,这样要如何实现呢?远程RPC调用给了我们一个本地调用远程服务的方法:
远程服务方:提供一个暴露服务(但是不暴露具体细节)的接口,一个实现该接口的实现类:
public interface IAClass {
public obj... aMethod(params...);
}
public class AClass implements IAClass{
public obj... aMethod(params...){
...
}
}
本地消费方:提供一个暴露服务的接口,直接调用接口的方法:
public interface IAClass {
public obj... aMethod(params...);
}
public class MainClass{
public void main(String[] args){
IAClass iAClass=获取一个代理对象;
iAClass.aMethod(params...);
}
}
通常的流程是:服务方像注册中心注册自己的服务,消费方在需要服务的时候向注册中心请求。注册中心找到匹配的服务方。消费方连接服务方发送请求,服务方提供方法(wsdl),消费者再与服务方发送请求获取结果(soap)。
2.Dubbo
Dubbo是一款分布式框架,其基本流程可以用下图表示:
服务提供方向注册中心(推荐是zookeeper)注册服务。
消费方在需要服务的时候,向注册中心请求,注册中心找到某一个提供服务的服务端(该过程对消费者来说,不可知会分配给哪一个服务端,zookeeper内置负载均衡和分配策略)。
消费方像服务端发送请求,携带接口信息、方法信息、参数列表、requestID(异步发送请求时,需要一个ID来告知这个结果是哪一个线程所需要的)。服务端处理结果返回给消费方。(传递数据时,需要序列化。)
3.Spring-Dubbo的配置:(使用xml文件配置bean)
服务方配置:
<!-- 提供方应用信息,用于计算依赖关系 -->
<dubbo:application name="${dubbo.applicationName}" />
<!-- 使用zookeeper广播注册中心暴露服务地址 -->
<dubbo:registry protocol="${dubbo.registryProtocol}" address="${dubbo.registryAddress}" />
<!-- 用dubbo协议在20880端口暴露服务 -->
<dubbo:protocol name="dubbo" port="${dubbo.port}" />
<!-- 和本地bean一样实现服务 -->
<bean id="..." class="..." />
<!-- 声明需要暴露的服务接口 -->
<dubbo:service interface="..." ref="..." retries="${dubbo.retries}" timeout="${dubbo.serverTimeout}" />
消费者配置
<!-- 消费方应用名,用于计算依赖关系,不是匹配条件,不要与提供方一样 -->
<dubbo:application name="${dubbo.applicationName}" />
<!-- 使用dubbo协议 注册中心暴露服务地址 -->
<dubbo:registry protocol="${dubbo.registryProtocol}" address="${dubbo.registryAddress}" />
<!-- 生成远程服务代理,可以像使用本地bean一样使用demoService -->
<dubbo:reference id="..." interface="..." retries="${dubbo.retries}" timeout="${dubbo.clientTimeout}" />