使用 Java 接口方式开发 triple 通信服务

POJO 方式使用 Triple

不同于 gRPC 框架,Dubbo 实现的 triple 协议易用性更好,triple 不绑定 Protobuf,你可以继续使用 Java 接口直接定义服务。对于期望平滑升级、没有多语言业务或者不熟悉 Protobuf 的用户而言,Java 接口方式是最简单的使用 triple 的方式。

以下是一个使用Java 接口开发 Dubbo 服务的基本示例,示例使用 triple 协议通信,可在此查看 本示例的完整代码

运行示例

首先,可通过以下命令下载示例源码

git clone --depth=1 https://github.com/apache/dubbo-samples.git

进入示例源码目录:

cd dubbo-samples/1-basic/dubbo-samples-api

启动Server

运行以下命令启动 server

mvn -Dexec.mainClass=org.apache.dubbo.samples.provider.Application exec:java

启动Client

有两种方式可以调用 server 发布的服务

  • 使用标准的 http 工具,如 cURL
  • 使用 Dubbo SDK 开发一个 client

cURL

curl \
    --header "Content-Type: application/json" \
    --data '["Dubbo"]' \
    http://localhost:50052/org.apache.dubbo.samples.api.GreetingsService/sayHi/

SDK Client

mvn -Dexec.mainClass=org.apache.dubbo.samples.client.Application exec:java

源码讲解

如果您是 Dubbo 老用户,你会发现以下内容与之前 Dubbo2 的开发模式基本一样,只是协议名称从 dubbo 换成了 tri

定义服务

首先是服务定义,使用 Java 接口定义 Dubbo 服务。

服务提供者

其次,对于提供者一侧而言,需要提供服务的具体实现:

配置使用 triple 协议:

最后,是将服务发布出去:

服务消费者

配置服务引用,如下所示:

接下来,就可以发起对远程服务的 RPC 调用了:

注意事项

编码

通过上面介绍的升级过程,我们可以很简单的通过修改协议类型来完成升级。框架是怎么帮我们做到这些的呢?

通过对 Triple 协议的介绍,我们知道Dubbo3的 Triple 的数据类型是 protobuf 对象,那为什么非 protobuf 的 java 对象也可以被正常传输呢。

这里 Dubbo3 使用了一个巧妙的设计,首先判断参数类型是否为 protobuf 对象,如果不是。用一个 protobuf 对象将 requestresponse 进行 wrapper,这样就屏蔽了其他各种序列化带来的复杂度。在 wrapper 对象内部声明序列化类型,来支持序列化的扩展。

wrapper 的protobuf的 IDL如下:

syntax = "proto3";

package org.apache.dubbo.triple;

message TripleRequestWrapper {
    // hessian4
    // json
    string serializeType = 1;
    repeated bytes args = 2;
    repeated string argTypes = 3;
}

message TripleResponseWrapper {
    string serializeType = 1;
    bytes data = 2;
    string type = 3;
}

对于请求,使用TripleRequestWrapper进行包装,对于响应使用TripleResponseWrapper进行包装。

对于请求参数,可以看到 args 被repeated修饰,这是因为需要支持 java 方法的多个参数。当然,序列化只能是一种。序列化的实现沿用 Dubbo2 实现的 spi

性能表现

由于链路上传输的数据额外经过了一层序列化编码(如hessian2),同时,server 端的方法调用基于反射,因此相比于 protobuf+triple 的编码模式,Java接口方式在性能上会存在一定的下降。

Protobuf 模式固然有一定的性能优势,但易用性与使用成本也会陡然增加,我们建议还是优先考虑业务场景,如果没有多语言业务、dubbo2老用户,则继续保持 Java 接口模式是一个比较好、低成本的选择。

gRPC兼容性

由于 gRPC 仅支持 protobuf 模式,因此 接口+triple 的模式无法与谷歌官方原生的 gRPC 协议互调。同时,在这种模式下,如果对于来自前端的 HTTP 流量(比如浏览器),要想通过网关接入 triple,就要走 triple 内置的 application/json 模式,具体请参见【进阶学习-HTTP网关接入】。


最后修改 January 8, 2024: Update java sdk doc (#2895) (e3d2c12de7)