-
Notifications
You must be signed in to change notification settings - Fork 225
feat(async): Add Java interoperability with async RPC support #992
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
ffe31d2
7b833d8
31b72a6
312aed6
80e885a
4f25a10
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,22 +1,96 @@ | ||||||||||||||||
| # 异步 RPC Dubbo for Dubbo-go | ||||||||||||||||
| # Dubbo-go 异步 RPC | ||||||||||||||||
|
|
||||||||||||||||
| [[English](README.md) | [中文](README_zh.md)] | ||||||||||||||||
|
|
||||||||||||||||
| 该示例基于新版 `client` / `server` API 展示 Triple 协议下的 Dubbo 异步调用:客户端 | ||||||||||||||||
| 在发送 `GetUser` 请求后可以继续执行其他逻辑(非阻塞调用),同时也包含 `SayHello` 的单向调用示例。注意:本示例仅演示异步调用的非阻塞特性,实际响应可通过返回值获取。 | ||||||||||||||||
| 本示例展示了如何使用新的 `client`/`server` API 通过 Triple 协议异步调用 Dubbo 服务。 | ||||||||||||||||
| 演示了 Go 和 Java 之间的异步互操作。 | ||||||||||||||||
|
|
||||||||||||||||
| ## 运行步骤 | ||||||||||||||||
| ## 功能特性 | ||||||||||||||||
|
|
||||||||||||||||
| 1. **启动服务端** | ||||||||||||||||
| - **Go 客户端和服务端**: 使用 `client.WithAsync()` 实现异步调用 | ||||||||||||||||
| - **Java 客户端**: 使用 `CompletableFuture` API 实现异步调用 | ||||||||||||||||
| - **Java 服务端**: 使用 `CompletableFuture` 实现异步服务 | ||||||||||||||||
| - **互操作性**: Java 客户端可调用 Go 服务端,Go 客户端可调用 Java 服务端 | ||||||||||||||||
|
|
||||||||||||||||
| ## 运行 Go 到 Go 示例 | ||||||||||||||||
|
|
||||||||||||||||
| 1. **启动 Go 服务端** | ||||||||||||||||
|
|
||||||||||||||||
| ```bash | ||||||||||||||||
| go run ./async/go-server/cmd/main.go | ||||||||||||||||
| ``` | ||||||||||||||||
|
|
||||||||||||||||
| 2. **启动客户端** | ||||||||||||||||
| 2. **启动 Go 客户端**(默认连接 Go 服务端) | ||||||||||||||||
|
|
||||||||||||||||
| ```bash | ||||||||||||||||
| go run ./async/go-client/cmd/main.go | ||||||||||||||||
| ``` | ||||||||||||||||
|
|
||||||||||||||||
| 客户端会打印 "non-blocking before async callback resp: do something ... " 和 "test end" 日志,演示异步调用的非阻塞特性。 | ||||||||||||||||
|
|
||||||||||||||||
| ## 运行 Java-Go 互操作示例 | ||||||||||||||||
|
|
||||||||||||||||
| 演示**跨语言异步调用**: | ||||||||||||||||
|
|
||||||||||||||||
| - **Go 客户端** → **Java 服务端** | ||||||||||||||||
| - **Java 客户端** → **Go 服务端** | ||||||||||||||||
|
|
||||||||||||||||
| ### 前置条件 | ||||||||||||||||
|
|
||||||||||||||||
| - Java 11 或更高版本 | ||||||||||||||||
| - Maven 3.6+ | ||||||||||||||||
|
|
||||||||||||||||
| ### 构建 Java 模块 | ||||||||||||||||
|
|
||||||||||||||||
| 在 `async` 目录下执行: | ||||||||||||||||
|
|
||||||||||||||||
| ```bash | ||||||||||||||||
| mvn clean compile | ||||||||||||||||
| ``` | ||||||||||||||||
|
|
||||||||||||||||
| ### 测试:Go 客户端 → Java 服务端 | ||||||||||||||||
|
|
||||||||||||||||
| 1. **修改 Go 客户端 URL**,在 `go-client/cmd/main.go` 中修改: | ||||||||||||||||
|
|
||||||||||||||||
| ```go | ||||||||||||||||
|
Comment on lines
+53
to
+55
|
||||||||||||||||
| 1. **修改 Go 客户端 URL**,在 `go-client/cmd/main.go` 中修改: | |
| ```go | |
| 1. **修改 Go 客户端 URL**。Go 客户端默认配置为连接 Go 服务端(端口 `20000`),在 `go-client/cmd/main.go` 中通常如下: | |
| ```go | |
| client.WithClientURL("tri://127.0.0.1:20000"), |
为了让 Go 客户端连接到 Java 服务端,请将上述行修改为:
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,79 @@ | ||
| <?xml version="1.0" encoding="UTF-8"?> | ||
| <!-- | ||
| Licensed to the Apache Software Foundation (ASF) under one or more | ||
| contributor license agreements. See the NOTICE file distributed with | ||
| this work for additional information regarding copyright ownership. | ||
| The ASF licenses this file to You under the Apache License, Version 2.0 | ||
| (the "License"); you may not use this file except in compliance with | ||
| the License. You may obtain a copy of the License at | ||
|
|
||
| http://www.apache.org/licenses/LICENSE-2.0 | ||
|
|
||
| Unless required by applicable law or agreed to in writing, software | ||
| distributed under the License is distributed on an "AS IS" BASIS, | ||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| See the License for the specific language governing permissions and | ||
| limitations under the License. | ||
| --> | ||
| <project xmlns="http://maven.apache.org/POM/4.0.0" | ||
| xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
| xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
| <parent> | ||
| <groupId>org.apache.dubbo.samples</groupId> | ||
| <artifactId>async-parent</artifactId> | ||
| <version>1.0.0</version> | ||
| <relativePath>../pom.xml</relativePath> | ||
| </parent> | ||
|
|
||
| <modelVersion>4.0.0</modelVersion> | ||
| <artifactId>java-async-client</artifactId> | ||
| <name>java-async-client</name> | ||
| <description>Java client module for async RPC sample</description> | ||
|
|
||
| <dependencies> | ||
| <dependency> | ||
| <groupId>com.google.protobuf</groupId> | ||
| <artifactId>protobuf-java</artifactId> | ||
| <version>${protobuf.version}</version> | ||
| </dependency> | ||
| <dependency> | ||
| <groupId>org.apache.dubbo</groupId> | ||
| <artifactId>dubbo</artifactId> | ||
| <version>${dubbo.version}</version> | ||
| </dependency> | ||
| </dependencies> | ||
|
|
||
| <build> | ||
| <plugins> | ||
| <plugin> | ||
| <groupId>org.xolstice.maven.plugins</groupId> | ||
| <artifactId>protobuf-maven-plugin</artifactId> | ||
| </plugin> | ||
| <plugin> | ||
| <groupId>org.codehaus.mojo</groupId> | ||
| <artifactId>build-helper-maven-plugin</artifactId> | ||
| <executions> | ||
| <execution> | ||
| <phase>generate-sources</phase> | ||
| <goals> | ||
| <goal>add-source</goal> | ||
| </goals> | ||
| <configuration> | ||
| <sources> | ||
| <source>${project.build.directory}/generated-sources/protobuf/java</source> | ||
| </sources> | ||
| </configuration> | ||
| </execution> | ||
| </executions> | ||
| </plugin> | ||
| <plugin> | ||
| <groupId>org.codehaus.mojo</groupId> | ||
| <artifactId>exec-maven-plugin</artifactId> | ||
| <version>3.1.0</version> | ||
| <configuration> | ||
| <mainClass>org.apache.dubbo.samples.async.JavaAsyncClient</mainClass> | ||
| </configuration> | ||
| </plugin> | ||
| </plugins> | ||
| </build> | ||
| </project> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| #!/bin/bash | ||
| # | ||
| # Licensed to the Apache Software Foundation (ASF) under one or more | ||
| # contributor license agreements. See the NOTICE file distributed with | ||
| # this work for additional information regarding copyright ownership. | ||
| # The ASF licenses this file to You under the Apache License, Version 2.0 | ||
| # (the "License"); you may not use this file except in compliance with | ||
| # the License. You may obtain a copy of the License at | ||
| # | ||
| # http://www.apache.org/licenses/LICENSE-2.0 | ||
| # | ||
| # Unless required by applicable law or agreed to in writing, software | ||
| # distributed under the License is distributed on an "AS IS" BASIS, | ||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| # See the License for the specific language governing permissions and | ||
| # limitations under the License. | ||
| # | ||
|
|
||
| echo "Building Java async client..." | ||
| mvn -q clean package | ||
|
|
||
| echo "Starting Java async client..." | ||
| mvn -q exec:java -Dexec.mainClass=org.apache.dubbo.samples.async.JavaAsyncClient |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,79 @@ | ||
| /* | ||
| * Licensed to the Apache Software Foundation (ASF) under one or more | ||
| * contributor license agreements. See the NOTICE file distributed with | ||
| * this work for additional information regarding copyright ownership. | ||
| * The ASF licenses this file to You under the Apache License, Version 2.0 | ||
| * (the "License"); you may not use this file except in compliance with | ||
| * the License. You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
|
|
||
| package org.apache.dubbo.samples.async; | ||
|
|
||
| import org.apache.dubbo.config.ApplicationConfig; | ||
| import org.apache.dubbo.config.ReferenceConfig; | ||
| import org.apache.dubbo.config.bootstrap.DubboBootstrap; | ||
| import org.apache.dubbo.samples.async.proto.*; | ||
|
|
||
| import java.util.concurrent.CompletableFuture; | ||
| import java.util.concurrent.CountDownLatch; | ||
|
|
||
| public class JavaAsyncClient { | ||
|
|
||
| public static void main(String[] args) throws Exception { | ||
| ReferenceConfig<UserProvider> userProviderRef = new ReferenceConfig<>(); | ||
| userProviderRef.setInterface(UserProvider.class); | ||
| userProviderRef.setUrl("tri://127.0.0.1:20000"); | ||
|
|
||
| ReferenceConfig<UserProviderV2> userProviderV2Ref = new ReferenceConfig<>(); | ||
| userProviderV2Ref.setInterface(UserProviderV2.class); | ||
| userProviderV2Ref.setUrl("tri://127.0.0.1:20000"); | ||
|
|
||
| DubboBootstrap bootstrap = DubboBootstrap.getInstance(); | ||
| bootstrap.application(new ApplicationConfig("java-async-client")) | ||
| .reference(userProviderRef) | ||
| .reference(userProviderV2Ref) | ||
| .start(); | ||
|
|
||
| UserProvider userProvider = userProviderRef.get(); | ||
| UserProviderV2 userProviderV2 = userProviderV2Ref.get(); | ||
|
|
||
| CountDownLatch latch1 = new CountDownLatch(1); | ||
| GetUserRequest getUserReq = GetUserRequest.newBuilder().setId("003").build(); | ||
| CompletableFuture<GetUserResponse> future1 = userProvider.getUserAsync(getUserReq); | ||
|
|
||
| System.out.println("async request sent, doing other work..."); | ||
|
|
||
| future1.whenComplete((response, throwable) -> { | ||
| if (throwable != null) { | ||
| System.err.println("error: " + throwable.getMessage()); | ||
| } else { | ||
| User user = response.getUser(); | ||
| System.out.println("received user: " + user.getName() + ", age: " + user.getAge()); | ||
| } | ||
| latch1.countDown(); | ||
| }); | ||
|
|
||
| CountDownLatch latch2 = new CountDownLatch(1); | ||
| SayHelloRequest sayHelloReq = SayHelloRequest.newBuilder().setUserId("002").build(); | ||
| CompletableFuture<SayHelloResponse> future2 = userProviderV2.sayHelloAsync(sayHelloReq); | ||
|
|
||
| future2.whenComplete((response, throwable) -> { | ||
| if (throwable == null) { | ||
| System.out.println("sayHello completed"); | ||
| } | ||
| latch2.countDown(); | ||
| }); | ||
|
Comment on lines
+68
to
+73
|
||
|
|
||
| latch1.await(); | ||
| latch2.await(); | ||
| bootstrap.stop(); | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The documentation states that the Go client can be modified to connect to the Java server by changing the URL to "tri://127.0.0.1:50051", but the actual Go client code in go-client/cmd/main.go currently hardcodes "tri://127.0.0.1:20000". The README should clarify that this is the default configuration for Go-to-Go communication, and users need to manually change this line in the code to test Java interoperability as described.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@MrSibe Please consider copilot's suggestion.