Dubbo入门

目录

RPC框架

Dubbo架构

Dubbo快速入门

Dubbo中的异步调用


RPC框架

RPC(Remote Procedure Call Protocol)——远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务的协议。

基本原理:

  1. 通过网络连接进行服务间的通信;
  2.  序列化与反序列化机制。

RPC调用过程:

  1. 客户端(client)以接口的方式调用服务;
  2. 客户端存根(client stub)接收到调用后,负责将方法、参数等组装成能够进行网络传输的消息体(将消息体对象序列化为二进制);
  3. 客户端通过sockets将消息发送到服务端;
  4. 服务端存根( server stub)收到消息后进行解码(将消息对象反序列化);
  5. 服务端存根( server stub)根据解码结果调用本地的服务;
  6. 本地服务执行并将结果返回给服务端存根( server stub);
  7. 服务端存根( server stub)将返回结果打包成消息(将结果消息对象序列化);
  8. 服务端(server)通过sockets将消息发送到客户端;
  9. 客户端存根(client stub)接收到结果消息,并进行解码(将结果消息发序列化);
  10. 客户端(client)得到最终结果。

Dubbo架构

 

Dubbo快速入门

  • 服务提供者

1. 定义服务接口

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

 2. 实现服务接口

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 from provider: " + RpcContext.getContext().getLocalAddress();
    }
}

3. 用spring配置声明暴露服务

<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" xmlns:context="http://www.springframework.org/schema/context"
       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 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
    <context:property-placeholder/>

    <!-- 提供方应用信息,用于计算依赖关系 -->
    <dubbo:application name="demo-provider"/>

    <dubbo:registry address="zookeeper://${zookeeper.address:127.0.0.1}:2181"/>

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

    <bean id="demoService" class="org.apache.dubbo.samples.basic.impl.DemoServiceImpl"/>

    <!-- 声明需要暴露的服务接口 -->
    <dubbo:service interface="org.apache.dubbo.samples.basic.api.DemoService" ref="demoService"/>

</beans>

4. 加载spring配置

public class BasicProvider {

    public static void main(String[] args) throws Exception {
        new EmbeddedZooKeeper(2181, false).start();
        // wait for embedded zookeeper start completely.
        Thread.sleep(1000);

        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring/dubbo-demo-provider.xml");
        context.start();

        System.out.println("dubbo service started");
        new CountDownLatch(1).await();
    }
}
  • 服务消费者

1. 通过 Spring 配置引用远程服务

<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" xmlns:context="http://www.springframework.org/schema/context"
       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 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
    <context:property-placeholder/>

    <!-- 消费方应用名,用于计算依赖关系,不是匹配条件,不要与提供方一样 -->
    <dubbo:application name="demo-consumer"/>

    <dubbo:registry address="zookeeper://${zookeeper.address:127.0.0.1}:2181"/>

    <!-- 生成远程服务代理,可以和本地bean一样使用demoService -->
    <dubbo:reference id="demoService" check="true" interface="org.apache.dubbo.samples.basic.api.DemoService"/>

</beans>

2. 加载Spring配置,并调用远程服务

public class BasicConsumer {

    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring/dubbo-demo-consumer.xml");
        context.start();
        DemoService demoService = (DemoService) context.getBean("demoService");
        String hello = demoService.sayHello("world");
        System.out.println(hello);
    }
}

代码链接:https://github.com/apache/dubbo-samples

Dubbo中的异步调用

异步通讯对于服务端响应时间较长的方法是必须的,能够有效地利用客户端的资源,在dubbo中,消费端<dubbp:method>通过 async="true"标识。

<dubbo:reference id="xxx" ....>
    <dubbo:method name="method1" async="true" />
</dubbo:reference>
  • 方式一:NIO future主动获取结果,返回结果放在RpcContext中。
        AsyncService asyncService = context.getBean("asyncService", AsyncService.class);
        asyncService.sayHello("world");

        CompletableFuture<String> helloFuture = RpcContext.getContext().getCompletableFuture();
        helloFuture.whenComplete((retValue, exception) -> {
            if (exception == null) {
                System.out.println("return value: " + retValue);
            } else {
                exception.printStackTrace();
            }
        });

        CompletableFuture<String> f = RpcContext.getContext().asyncCall(() -> asyncService.sayHello("async call request"));
        System.out.println("async call returned: " + f.get());
  • 方式二:通过回调(Callback)参数

(1)服务提供者需在方法中声明Callback参数,其后在Service实现中显示地调用Callback的方法;

    <dubbo:service interface="org.apache.dubbo.samples.callback.api.CallbackService" ref="callbackService"
                   connections="1" callbacks="1000"> # 标识第二个参数是callback类型
        <dubbo:method name="addListener">
            <dubbo:argument index="1" callback="true"/>
        </dubbo:method>
    </dubbo:service>

(2)Callback接口的实现类在消费端,当方法发生调用时,消费端会自动export一个Callback服务,在RPC调用完成后,不能立即结束线程。

  • 方式三:事件通知(推荐)

这种方式更简单,对服务提供方来讲是透明的,在配置和代码上无需做任何改动。只要在消费端定义一个“通知者”的Spring Bean,指定方法的onreturn和onthrow事件即可。

    <bean id="demoCallback" class="org.apache.dubbo.samples.notify.impl.NotifyImpl"/>
    <dubbo:reference id="demoService" check="false" interface="org.apache.dubbo.samples.notify.api.DemoService"
                     version="1.0.0" group="cn">
    <dubbo:method name="sayHello" async="false" onreturn="demoCallback.onReturn" onthrow="demoCallback.onThrow"/>
    </dubbo:reference>
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值