Dubbo的使用入门

项目工程结构

建议采用同一个父工程的多个模块module.

服务提供者包括api和provider.

api:存放服务接口(interface)和服务模型(pojo,输入参数和返回值,所有的pojo都需要实现Serializable接口,因为需要进行网络传输?),服务异常(Exception,服务抛出的异常),一般是jar工程。

provider:存放服务接口的实现以及暴露服务的配置,依赖api模块,一般是war工程。

服务消费者

consumer:存放引用远程服务的配置和调用远程服务实现,依赖api模块,一般是war工程。

Dubbo采用全Spring配置方式,透明化接入应用,对应用没有任何API侵入,只需用Spring加载Dubbo的配置即可,Dubbo基于Spring的Schema扩展进行加载。

下面简单说明一下Dubbo的用法,

服务接口

定义服务接口

public interface DemoService {
    String sayHello(String name);
}

 Dubbo的使用入门

该接口需要单独打包,以便在服务提供方和消费方之间共享。

服务提供者

在服务提供者处实现接口(消费者引用的只有接口,对服务消费者隐藏接口实现细节)

package com.winner.dubbo.demo.provider.service;

import com.alibaba.dubbo.rpc.RpcContext;
import com.winner.dubbo.demo.api.service.DemoService;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @author winner_0715
 * @date 2017/12/17
 */
public class DemoServiceImpl implements DemoService {
    @Override
    public String sayHello(String name) {
        System.out.println("[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "] Hello "
                + name + ", request from consumer: " + RpcContext.getContext().getRemoteAddress());
        return "Hello " + name + ", response form provider: " + RpcContext.getContext().getLocalAddress();
    }
}

 在classpath下用spring配置声明暴露服务:spring-dubbo-provider.xml

<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:dubbo="http://code.alibabatech.com/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-2.5.xsd
        http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
    <!-- 提供方应用信息,用于计算依赖关系 -->
    <dubbo:application name="demo-provider" owner="winner_0715" organization="wireless"/>

    <!-- 使用zookeeper注册中心暴露服务地址 -->
    <dubbo:registry protocol="zookeeper" address="zk地址" group="/demo/group/default"/>

    <!-- 用dubbo协议在20880端口暴露服务 -->
    <dubbo:protocol name="dubbo" port="-1"/>

    <!-- 和本地bean一样实现服务 -->
    <bean id="demoService" class="com.winner.dubbo.demo.provider.service.DemoServiceImpl"/>

    <!-- 声明需要暴露的服务接口 -->
    <dubbo:service interface="com.winner.dubbo.demo.api.service.DemoService" ref="demoService" version="1.0" timeout="3000"/>
</beans>

(1)在根节点beans添加xml命名空间dubbo,xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"和dubbo标签遵循的规则地址。xsi:schemaLocation=".... 

(2)dubbo:application应用信息配置,@name应用的名称,用于注册中心计算应用之间的依赖关系,消费者和提供者应用名不要一样。@owner应用负责人,出问题的时候可以找到对应的人来解决。@organization组织名称,用于注册中心区分服务来源。

(3)dubbo:registry注册中心配置,@protocol 注册中心地址协议,一般都写zookeeper。@address 注册中心服务器地址,同一个集群内的多个地址使用逗号进行分隔,如ip:port,ip:port,不同集群的注册中心,配置多个<dubbo:registry>,@group 注册服务根节点。

(4)dubbo:protocol 服务提供者协议配置 @name 协议名称,缺省是dubbo,@port 服务端口,dubbo协议缺省端都是20880,如果配置是-1或者没有配置port,则会分配一个没有被占用的端口。建议写成-1,不容易产生端口冲突.

(5)dubbo:service 服务提供者暴露服务配置

@interface 服务接口名 @ref 服务对象实现引用 @version 服务版本,建议使用两位数字的版本@timeout服务超时时间

 Dubbo的使用入门

服务消费者

 通过spring配置引用远程服务

<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:dubbo="http://code.alibabatech.com/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-2.5.xsd
        http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
    <!-- 消费方应用名,用于计算依赖关系,不是匹配条件,不要与提供方一样 -->
    <dubbo:application name="demo-consumer" owner="winner_0715" organization="wireless"/>

    <!-- 使用zookeeper注册中心暴露服务地址 -->
    <dubbo:registry protocol="zookeeper" address="zk地址" group="/demo/group/default"/>

    <!-- 生成远程服务代理,可以和本地bean一样使用demoService -->
    <dubbo:reference id="demoService"interface="com.winner.dubbo.demo.api.service.DemoService" check="false"  version="1.0"/>
</beans>

dubbo:reference 服务消费者引用服务配置

@id服务引用bean id @interface服务接口名 @version服务版本,与服务提供者的版本一致,不然可能报no provider的错误 @check启动时检查提供者是否存在,true的话报错,false忽略,一般配置成false

服务消费者处只要通过Spring拿到demoService,即可像使用本地接口一样使用DemoService这个接口里面的方法:

import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.winner.dubbo.demo.api,service.DemoService;
 
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); // 显示调用结果
    }
}

看到整个过程中:

1、没有任何Dubbo的代码,使用Dubbo的时候全部都是Spring配置,这就是前面提到的Dubbo对应用没有任何API侵入

2、不需要考虑底层线程模型、序列化、反序列化、url解析等问题,这些都是Dubbo底层做好的

Dubbo的使用入门

上面是使用xml的方式,其实dubbo也支持api的方式

API类和配置标签一对一,比如:
com.alibaba.dubbo.config.ApplicationConfig 对应 <dubbo:application/>
com.alibaba.dubbo.config.RegistryConfig 对应 <dubbo:registry/>
com.alibaba.dubbo.config.ProtocolConfig 对应 <dubbo:protocol/>
com.alibaba.dubbo.config.ProviderConfig 对应 <dubbo:provider/>
com.alibaba.dubbo.config.ReferenceConfig对应 <dubbo:reference/>
API属性与配置项一对一,比如:ApplicationConfig.setName("xxx") 对应 <dubbo:application name="xxx" />