Dubbo的自我入门记录

一、 前言

其实我没在项目中使用过Dubbo,所以才想去看一看。这篇就是自己的入门教程,里面可能有些概念不对或者不清晰,如有错误,感谢指正。

二、简介

Dubbo是阿里巴巴公司开源的一个高性能优秀的服务框架,使得应用可通过高性能的 RPC 实现服务的输出和输入功能,可以和 Spring框架无缝集成。Dubbo是一款高性能、轻量级的开源Java RPC框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。

三、项目搭建

1. 项目概述

项目搭建成如下三个项目模块, 见名知意,dubbo-consumer 是服务消费者,dubbo-provider1和2是服务提供者。dubbo-interface是RPC调用的接口。
在这里插入图片描述

  1. 首先需要启动Zookeeper。和可视化工具。准备工作到此为止
    在这里插入图片描述

2. dubbo-interface

dubbo 根据引用类型的全路径类名 + 版本号 作为唯一服务id
这是提供给调用方的接口列表,就创建了一个provider接口。
在这里插入图片描述
1. ServerProvider 接口

/**
 * @Data: 2019/12/10
 * @Des: RPC提供的接口
 */
public interface ServerProvider {
    String provider(String msg);
}

3. dubbo-provider-1、dubbo-provider-2

两个项目完全一样,只是端口不同,所以这里拿 dubbo-provider-1 模块讲解。
在这里插入图片描述
ServerProvierImpl 代码

import com.alibaba.dubbo.config.annotation.Service;
import com.kingfish.service.ServerProvider;
import org.springframework.beans.factory.annotation.Value;

/**
 * @Data: 2019/12/10
 * @Des:
 */
// 注意service注解是阿里的注解,不是spring的
// 配上版本号1.0.0说明向zookeeper注册的是版本为1.0.0的TestService接口,超时时长为3000ms等信息。
@Service(version = "1.0.0")
public class ServerProvierImpl implements ServerProvider {
    @Value("${server.port}")
    private int port;

    @Override
    public String provider(String msg) {
        return "端口号 :" + port + " 提供了服务 : " + msg;
    }
}

application.yml文件。 dubbo-provider-2 的端口号是8092和10002

server:
  port: 8091
spring:
  dubbo:
    application:
      name: dubbo-provider # 应用名
    registry:
      address: zookeeper://localhost #zookeeper地址
      port: 2181
    protocol:
      name: dubbo
      port: 10001  #dubbo服务暴露的端口
    scan: com.kingfish.service #扫描的包

注意,这里引入的是 io.dubbo.springboot 的包,所以可以在yml中配置dubbo,但是引用这个包在使用Aop时会出现问题,这个后面再说。

4. dubbo-consumer

在这里插入图片描述
1. ServerConsumerController

import com.alibaba.dubbo.config.annotation.Reference;
import com.kingfish.service.ServerProvider;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("server")
public class ServerConsumerController {
	// 引用dubbo中的注解。版本号1.0.0, 超时时间10s, 采用异步调用
    @Reference(version = "1.0.0", timeout = 10000, async = true)
    private ServerProvider serverProvider;

    @RequestMapping("consumer")
    public String consumer() {
        String str = serverProvider.provider("哈哈哈哈");
        System.out.println(str);
        return str;
    }
}
  1. application.yml
server:
  port: 8090
spring:
  dubbo:
    application:
      name: dubbo-provider # 应用名
    registry:
      address: zookeeper://localhost #zookeeper地址
      port: 2181
    protocol:
      name: dubbo
      port: 10000 #dubbo服务暴露的端口
    scan: com.kingfish.controller #扫描的包名

5. 启动项目

千万不要把这个看做一个jar包间的调用!!!实际上,把这个三个服务剥离开,只需要改一下配置就可以继续访问了。

  1. 查看zk中的节点发现,服务提供者和服务消费者都已经注册进去
    在这里插入图片描述
  2. 调用 http://localhost:8090/server/consumer 返回如下:
    在这里插入图片描述

四、其它

1. dubbo 异步调用

这里写的比较简单,详细可以看 https://www.jianshu.com/p/3a706e544874

服务端在引用 @Reference注解时可以 async = true 参数通过开启异步调用,默认会返回null,如下。
在这里插入图片描述

1. 通过RpcContext获取Future对象,调用get方法时阻塞知道返回结果。
这种方式调用get方法会阻塞到返回

    // 设置异步,超时10s
    @Reference(version = "1.0.0", async = true, timeout = 10000)
    private ServerProvider serverProvider;

    @RequestMapping("consumer")
    public String consumer() throws ExecutionException, InterruptedException {
       serverProvider.provider("哈哈哈哈");
       // 如果开启异步,默认会直接返回null。下面两种方式可以获取到结果
        // 方式1 : 异步调用时使用
        Future<String> future = RpcContext.getContext().getFuture();
        // 会一直阻塞到异步调用返回结果
        String str = future.get();
        System.out.println(str);
        return str;
    }

2. 通过ResponseFuture设置回调,执行完成会回调done方法,抛异常则会回调caught方法:
这种方式会开启一个新线程来等待回调

    // 设置异步,超时10s
    @Reference(version = "1.0.0", async = true, timeout = 10000)
    private ServerProvider serverProvider;

    @RequestMapping("consumer")
    public String consumer() throws ExecutionException, InterruptedException {
       serverProvider.provider("哈哈哈哈");
       // 如果开启异步,默认会直接返回null。下面两种方式可以获取到结果
        // 方式1 : 异步调用时使用

        ResponseFuture responseFuture = ((FutureAdapter)RpcContext.getContext().getFuture()).getFuture();
        responseFuture.setCallback(new ResponseCallback() {
            @Override
            public void done(Object response) {
            	// RPC结果在这里获取
                System.out.println("回调成功 : " + response);
            }
            @Override
            public void caught(Throwable exception) {
                System.out.println("回调成功 : " + exception.getMessage());
            }
        });

//        System.out.println(str);
        // 因为结果在回调中返回,所以这里随便返回
        return "111";
    }

2. io.dubbo.springboot 和 AOP 服务注册异常

在实际搭建这个项目过程中,加入Aop后会导致dubbo服务无法注册,网上搜索说是因为io.dubbo.springboot 所依赖的dubbo版本问题,但修改dubbo版本后会出现注册后节点加了一层代理对象节点的问题。下面提出上面两个问题的解决方案。

解决方案:

  1. 使用 io.dubbo.springboot 包,这时候duboo的配置就不能使用配置类方式,直接使用xml配置方式,xml 配置方式不会出现问题
  2. 不使用 io.dubbo.springboot 包,直接导入dubbo包,使用xml配置或者配置类方式配置都可。如下
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>dubbo</artifactId>
            <version>2.6.7</version>
        </dependency>
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-framework</artifactId>
            <version>2.12.0</version>
        </dependency>
        <!-- zookeeper客户端 -->
        <dependency>
            <groupId>com.101tec</groupId>
            <artifactId>zkclient</artifactId>
            <version>0.7</version>
        </dependency>

3. dubbo 配置类方式配置

@Configuration
@EnableDubbo(scanBasePackages = {"com.kingfish.business.service"})
public class DubboConfig {
    //<dubbo:application name="boot-user-service-provider"></dubbo:application>
    @Bean
    public ApplicationConfig applicationConfig() {
        ApplicationConfig applicationConfig = new ApplicationConfig();
        applicationConfig.setName("dubbo-consumer");
        return applicationConfig;
    }

    //<dubbo:registry protocol="zookeeper" address="127.0.0.1:2181"></dubbo:registry>
    @Bean
    public RegistryConfig registryConfig() {
        RegistryConfig registryConfig = new RegistryConfig();
        registryConfig.setProtocol("zookeeper");
        registryConfig.setAddress("127.0.0.1:2181");
        return registryConfig;
    }

    //<dubbo:protocol name="dubbo" port="20882"></dubbo:protocol>
    @Bean
    public ProtocolConfig protocolConfig() {
        ProtocolConfig protocolConfig = new ProtocolConfig();
        protocolConfig.setName("dubbo");
        protocolConfig.setPort(9999);
        return protocolConfig;
    }
}

4. dubbo xml 方式配置

<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="springboot-dubbo-provider"/>

    <!-- 注册中心配置,使用zookeeper注册中心暴露服务地址 -->
    <dubbo:registry address="zookeeper://127.0.0.1:2181" timeout="60000" />

    <!--关闭服务消费方所有服务的启动检查。dubbo缺省会在启动时检查依赖的服务是否可用,不可用时会抛出异常,阻止Spring初始化完成。-->
    <dubbo:consumer check="false" />
    <!-- 用dubbo协议在29014端口暴露服务 -->
    <dubbo:protocol name="dubbo" port="29014" />
    <!-- 使用注解方式暴露接口,会自动扫描package下所有包中dubbo相关的注解,这样就不用在xml中再针对每个服务接口配置dubbo:service interface-->
    <dubbo:annotation package="com.kingfish.business.service"/>
</beans>

以上:内容部分参考网络
https://www.jianshu.com/p/3a706e544874
如有侵扰,联系删除。 内容仅用于自我记录学习使用。如有错误,欢迎指正

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猫吻鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值