Dubbo3学习笔记-官方Demo

2023-09-18 23:46:08 浏览数 (2)

一. 初始化

官方生成项目模板:Initializer Dubbo (apache.org)

初始化界面初始化界面

1.1 关于版本

  • Dubbo版本选择3.2.6
  • Spring Boot选择3.1.2
  • JDK 17

既然是体验,那么都到最新可用版本,踩一遍坑,加深学习。

选择多模块、其他默认不动

1.2 目录展示

demo-api: 提供对外调用。

demo-service:实现api种的接口,提供服务。

没有经验的我,直接启动Application项目,发现一直报错

代码语言:Java复制
java.lang.IllegalArgumentException: Unable to canonicalize address 127.0.0.1/<unresolved>:2181 because it's not resolvable
	at org.apache.zookeeper.SaslServerPrincipal.getServerPrincipal(SaslServerPrincipal.java:65) ~[zookeeper-3.4.14.jar:3.4.14-4c25d480e66aadd371de8bd2fd8da255ac140bcf]
	at org.apache.zookeeper.SaslServerPrincipal.getServerPrincipal(SaslServerPrincipal.java:41) ~[zookeeper-3.4.14.jar:3.4.14-4c25d480e66aadd371de8bd2fd8da255ac140bcf]
	at org.apache.zookeeper.ClientCnxn$SendThread.startConnect(ClientCnxn.java:1001) ~[zookeeper-3.4.14.jar:3.4.14-4c25d480e66aadd371de8bd2fd8da255ac140bcf]
	at org.apache.zookeeper.ClientCnxn$SendThread.run(ClientCnxn.java:1060) ~[zookeeper-3.4.14.jar:3.4.14-4c25d480e66aadd371de8bd2fd8da255ac140bcf]

看起来需要单独启动Zookeeper服务

1.3 第一个坑:ZK与JDK17 的版本问题

即使启动了ZK,也依然出现问题,一顿调查发现

Dubbo官方Demo提供的ZK

代码语言:html复制
    <dependency>
        <groupId>org.apache.dubbo</groupId>
        <artifactId>dubbo-dependencies-zookeeper</artifactId>
        <version>${dubbo.version}</version>
        <type>pom</type>
        <scope>import</scope>
    </dependency>

没有显示具体版本

打卡IDEA的Maven仓库查看是3.4.X

github的相关Issue是:https://github.com/apache/kyuubi/issues/1941

解决方案为使用3.6.2(最新的版本是3.9)

到此为止,算是成功启动,并连接ZK。

1.4 第一个Demo小结

官方第一个Demo并没有运用到什么复杂的应用,最神奇的在于

代码语言:java复制
@Component
public class Consumer implements CommandLineRunner {
    @DubboReference
    private DemoService demoService;

    @Override
    public void run(String... args) throws Exception {

        String result = demoService.sayHello("world");
        System.out.println("Receive result ======> "   result);
    }
}

平常在使用Spring Boot的时候,依赖注入的注解是@AutoWired@Resource

Dubbo 则使用 @DubboReference

替换成原先的也好用,因为Demo还没完全分离

再来看看配置文件

代码语言:yaml复制
dubbo:
  application:
    logger: slf4j
    name: DemoApplication
  registry:
    address: zookeeper://${zookeeper.address:127.0.0.1}:2181
  protocol:
    name: tri
    port: 50051

根据昨天所学,勉强可以看懂

registry:自定义注册中心,这里选ZK

protocol:通信协议

最后是启动类

代码语言:java复制
@SpringBootApplication
@EnableDubbo
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

}

这里也是有特色的@EnableDubbo注解。

体验下来,这个Initializer除了一些基本导入外,没什么亮点。


二. 发布和调用Dubbo服务

官方教程:https://cn.dubbo.apache.org/zh-cn/overview/tasks/develop/service_reference/

官方代码地址:https://github.com/apache/dubbo-samples/tree/master/10-task/dubbo-samples-develop

教程内容有点奇怪,除了开头全文在解释上一个脚手架,而且配置文件格式又回到了.properties

以为在下一个阶段使用,结果开头又是新的Demo。

那就来分析一下现在的Demo

第二个Demo第二个Demo

好嘛,版本和异步都有了,那这样就混着看吧。

2.1 版本与分组

看到图,可以猜个大概,自定义依赖注解种加参数

代码语言:java复制
    @DubboReference(group = "group1",version = "1.0")
    private DevelopService developService;

点击去,看下具体描述

代码语言:java复制
public @interface DubboReference{
...
    /**
     * Service group, default value is empty string
     */
    String group() default "";
...
     /**
     * Service version, default value is empty string
     */
    String version() default "";
...

看到这里简直发现了新天地,昨天所见识到的东西很多都在这里可以配置。

2.2 异步

这些Task 啦,Async啦都是同步异步的标志。

接口定义,返回值是CompletableFuture<T> 即是异步。

代码语言:java复制
    /**
     * 同步调用方法
     */
    String invoke(String param);
    /**
     * 异步调用方法
     */
    CompletableFuture<String> asyncInvoke(String param);

实现的话,直接return这个

代码语言:java复制
CompletableFuture.supplyAsync(() -> {
    // dosomething
}

上面发现的是普通写法,官方还有另一种

Dubbo 提供了一个类似 Servlet 3.0 的异步接口AsyncContext,在没有 CompletableFuture 签名接口的情况下,也可以实现 Provider 端的异步执行。

具体就是在实现类里加入

代码语言:java复制
 final AsyncContext asyncContext = RpcContext.startAsync();
        new Thread(() -> {
            // 如果要使用上下文,则必须要放在第一句执行
            asyncContext.signalContextSwitch();
            try {
                // do something
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            // 写回响应
            asyncContext.write("Hello "   name   ", response from provider.");
        }).start();
        return null;

两者区别不大,但后者单独创建线程感觉有点“违规”。

总结

整体使用下来,Dubbo引用很简洁,除了一点额外的配置外,几乎与正常开发无感。然后比较有趣的是分组和版本的同步异步。当然,向普通的依赖注入一样的注解也带来了更多便捷,期待一下以后的实战体验。


我正在参与2023腾讯技术创作特训营第二期有奖征文,瓜分万元奖池和键盘手表

0 人点赞