一. 初始化
官方生成项目模板: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
好嘛,版本和异步都有了,那这样就混着看吧。
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>
即是异步。
/**
* 同步调用方法
*/
String invoke(String param);
/**
* 异步调用方法
*/
CompletableFuture<String> asyncInvoke(String param);
实现的话,直接return
这个
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腾讯技术创作特训营第二期有奖征文,瓜分万元奖池和键盘手表