快速开始

使用 Rust 快速开发 Dubbo 服务。

请在此查看完整 示例

1 前置条件

2 使用 IDL 定义 Dubbo 服务

Greeter 服务定义如下,包含一个 Unary(request-response) 模型的 Dubbo 服务。

  1. // ./proto/greeter.proto
  2. syntax = "proto3";
  3. option java_multiple_files = true;
  4. package org.apache.dubbo.sample.tri;
  5. // The request message containing the user's name.
  6. message GreeterRequest {
  7. string name = 1;
  8. }
  9. // The response message containing the greetings
  10. message GreeterReply {
  11. string message = 1;
  12. }
  13. service Greeter{
  14. // unary
  15. rpc greet(GreeterRequest) returns (GreeterReply);
  16. }

3 添加 Dubbo-rust 及相关依赖到项目

  1. # ./Cargo.toml
  2. [package]
  3. name = "example-greeter"
  4. version = "0.1.0"
  5. edition = "2021"
  6. [[bin]]
  7. name = "greeter-server"
  8. path = "src/greeter/server.rs"
  9. [[bin]]
  10. name = "greeter-client"
  11. path = "src/greeter/client.rs"
  12. [dependencies]
  13. http = "0.2"
  14. http-body = "0.4.4"
  15. futures-util = {version = "0.3", default-features = false}
  16. tokio = { version = "1.0", features = [ "rt-multi-thread", "time", "fs", "macros", "net", "signal"] }
  17. prost-derive = {version = "0.10", optional = true}
  18. prost = "0.10.4"
  19. async-trait = "0.1.56"
  20. tokio-stream = "0.1"
  21. dubbo = "0.1.0"
  22. dubbo-config = "0.1.0"
  23. [build-dependencies]
  24. dubbo-build = "0.1.0"

4 配置 dubbo-build 编译 IDL

在项目根目录创建 (not /src),创建 build.rs 文件并添加以下内容:

  1. // ./build.rs
  2. fn main() {
  3. dubbo_build::prost::configure()
  4. .compile(&["proto/greeter.proto"], &["proto/"])
  5. .unwrap();
  6. }

这样配置之后,编译项目就可以生成 Dubbo Stub 相关代码,路径一般在./target/debug/build/example-greeter-<id>/out/org.apache.dubbo.sample.tri.rs

5 编写 Dubbo 业务代码

5.1 编写 Dubbo Server

  1. // ./src/greeter/server.rs
  2. use ...
  3. #[tokio::main]
  4. async fn main() {
  5. register_server(GreeterServerImpl {
  6. name: "greeter".to_string(),
  7. });
  8. // Dubbo::new().start().await;
  9. Dubbo::new()
  10. .with_config({
  11. let r = RootConfig::new();
  12. match r.load() {
  13. Ok(config) => config,
  14. Err(_err) => panic!("err: {:?}", _err), // response was droped
  15. }
  16. })
  17. .start()
  18. .await;
  19. }
  20. #[allow(dead_code)]
  21. #[derive(Default, Clone)]
  22. struct GreeterServerImpl {
  23. name: String,
  24. }
  25. // #[async_trait]
  26. #[async_trait]
  27. impl Greeter for GreeterServerImpl {
  28. async fn greet(
  29. &self,
  30. request: Request<GreeterRequest>,
  31. ) -> Result<Response<GreeterReply>, dubbo::status::Status> {
  32. println!("GreeterServer::greet {:?}", request.metadata);
  33. Ok(Response::new(GreeterReply {
  34. message: "hello, dubbo-rust".to_string(),
  35. }))
  36. }
  37. }

5.2 配置dubbo.yaml

dubbo.yaml指示server端的配置,包括暴露的服务列表、协议配置、监听配置等。

  1. # ./dubbo.yaml
  2. name: dubbo
  3. service:
  4. org.apache.dubbo.sample.tri.Greeter:
  5. version: 1.0.0
  6. group: test
  7. protocol: triple
  8. registry: ''
  9. serializer: json
  10. protocol_configs:
  11. triple:
  12. ip: 0.0.0.0
  13. port: '8888'
  14. name: triple
  15. protocols:
  16. triple:
  17. ip: 0.0.0.0
  18. port: '8888'
  19. name: triple

5.3 编写 Dubbo Client

  1. // ./src/greeter/client.rs
  2. use ...
  3. #[tokio::main]
  4. async fn main() {
  5. let mut cli = GreeterClient::new().with_uri("http://127.0.0.1:8888".to_string());
  6. println!("# unary call");
  7. let resp = cli
  8. .greet(Request::new(GreeterRequest {
  9. name: "message from client".to_string(),
  10. }))
  11. .await;
  12. let resp = match resp {
  13. Ok(resp) => resp,
  14. Err(err) => return println!("{:?}", err),
  15. };
  16. let (_parts, body) = resp.into_parts();
  17. println!("Response: {:?}", body);
  18. }

6 运行并总结

  1. 编译

执行cargo build来编译server和client。

  1. 运行server

执行./target/debug/greeter-server来运行server,如上文dubbo.yaml所配置,server会监听8888端口,并以triple协议提供RPC服务:

  1. $ ./target/debug/greeter-server
  2. 2022-09-28T23:33:28.104577Z INFO dubbo::framework: url: Some(Url { uri: "triple://0.0.0.0:8888/org.apache.dubbo.sample.tri.Greeter", protocol: "triple", location: "0.0.0.0:8888", ip: "0.0.0.0", port: "8888", service_key: ["org.apache.dubbo.sample.tri.Greeter"], params: {} })
  1. 运行client,验证调用是否成功

执行./target/debug/greeter-client来运行client,调用triple://127.0.0.1:8888/org.apache.dubbo.sample.tri.Greeter下的各种方法:

  1. $ ./target/debug/greeter-client
  2. Response: GreeterReply { message: "hello, dubbo-rust" }

最后修改 December 16, 2022: Fix check (#1736) (97972c1)