使用说明

Triple 协议是 Dubbo3 的主要协议,完全兼容 gRPC over HTTP/2,并在协议级别扩展了负载均衡和流量控制相关机制。本文档旨在指导用户正确使用 Triple 协议。

在开始之前,您需要确定服务使用的序列化方法。如果是新服务,建议默认使用 protobuf 作为序列化方式,这样会有更好的性能和跨语言效果。如果原服务想升级协议,Triple 协议已经支持了其他的序列化方式,例如 Hessian / JSON 等。

Protobuf

  1. 编写 IDL 文件

    syntax = "proto3";
    
    option java_multiple_files = true;
    option java_package = "org.apache.dubbo.hello";
    option java_outer_classname = "HelloWorldProto";
    option objc_class_prefix = "HLW";
    
    package helloworld;
    
    // The request message containing the user's name.
    message HelloRequest {
      string name = 1;
    }
    
    // The response message containing the greetings
    message HelloReply {
      string message = 1;
    }
    
  2. 添加用于编译 protobuf 的扩展和插件(以 maven 为例)

       <extensions>
                <extension>
                    <groupId>kr.motd.maven</groupId>
                    <artifactId>os-maven-plugin</artifactId>
                    <version>1.6.1</version>
                </extension>
            </extensions>
            <plugins>
                <plugin>
                    <groupId>org.xolstice.maven.plugins</groupId>
                    <artifactId>protobuf-maven-plugin</artifactId>
                    <version>0.6.1</version>
                    <configuration>
                        <protocArtifact>com.google.protobuf:protoc:3.7.1:exe:${os.detected.classifier}</protocArtifact>
                        <pluginId>triple-java</pluginId>
                        <outputDirectory>build/generated/source/proto/main/java</outputDirectory>
                    </configuration>
                    <executions>
                        <execution>
                            <goals>
                                <goal>compile</goal>
                                <goal>test-compile</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
    
  3. 构建/编译以生成 protobuf 消息类

    $ mvn clean install
    

单向模式

  1. 编写 Java 接口

    import org.apache.dubbo.hello.HelloReply;
    import org.apache.dubbo.hello.HelloRequest;
    
    public interface IGreeter {
        /**
         * <pre>
         * Sends a greeting
         * </pre>
         */
        HelloReply sayHello(HelloRequest request);
    
    }
    
  2. 创建提供者

        public static void main(String[] args) throws InterruptedException {
            ServiceConfig<IGreeter> service = new ServiceConfig<>();
            service.setInterface(IGreeter.class);
            service.setRef(new IGreeter1Impl());
            // Here you need to show that the protocol used by the declaration is triple
            service.setProtocol(new ProtocolConfig(CommonConstants.TRIPLE, 50051));
            service.setApplication(new ApplicationConfig("demo-provider"));
            service.setRegistry(new RegistryConfig("zookeeper://127.0.0.1:2181"));
            service. export();
            System.out.println("dubbo service started");
            new CountDownLatch(1). await();
        }
    
  3. 创建消费者

    public static void main(String[] args) throws IOException {
        ReferenceConfig<IGreeter> ref = new ReferenceConfig<>();
        ref. setInterface(IGreeter. class);
        ref. setCheck(false);
        ref.setProtocol(CommonConstants.TRIPLE);
        ref. setLazy(true);
        ref. setTimeout(100000);
        ref. setApplication(new ApplicationConfig("demo-consumer"));
        ref.setRegistry(new RegistryConfig("zookeeper://127.0.0.1:2181"));
        final IGreeter iGreeter = ref. get();
    
        System.out.println("dubbo ref started");
        try {
            final HelloReply reply = iGreeter.sayHello(HelloRequest.newBuilder()
                    .setName("name")
                    .build());
            TimeUnit. SECONDS. sleep(1);
            System.out.println("Reply:" + reply);
        } catch (Throwable t) {
            t. printStackTrace();
        }
        System.in.read();
    }
    
  4. 运行提供者和消费者,您可以看到请求正常返回

    回复:消息:“名称”

流模式

  1. 编写 Java 接口
    import org.apache.dubbo.hello.HelloReply;
    import org.apache.dubbo.hello.HelloRequest;
    
    public interface IGreeter {
        /**
     * <pre>
     * Sends greeting by stream
     * </pre>
    */
    

StreamObserversayHello(StreamObserverreplyObserver);

}
```
  1. 编写实现类

public class IStreamGreeterImpl implements IStreamGreeter {

@Override public StreamObserversayHello(StreamObserverreplyObserver) {

return new StreamObserver() { private ListreplyList = new ArrayList<>();

@Override public void onNext(HelloRequest helloRequest) { System.out.println(“onNext 收到请求名称:” + helloRequest.getName()); replyList.add(HelloReply.newBuilder() .setMessage(“收到名称:” + helloRequest.getName()) .build()); }

@Override public void onError(Throwable cause) { System.out.println(“onError”); replyObserver.onError(cause); }

@Override public void onCompleted() { System.out.println(“onComplete 收到请求大小:” + replyList.size()); for (HelloReply reply : replyList) { replyObserver.onNext(reply); } replyObserver.onCompleted(); } }; } }


10. Create a Provider

    ```java
public class StreamProvider {
public static void main(String[] args) throws InterruptedException {
ServiceConfig<IStreamGreeter> service = new ServiceConfig<>();
service.setInterface(IStreamGreeter.class);
service.setRef(new IStreamGreeterImpl());
service.setProtocol(new ProtocolConfig(CommonConstants.TRIPLE, 50051));
service.setApplication(new ApplicationConfig("stream-provider"));
service.setRegistry(new RegistryConfig("zookeeper://127.0.0.1:2181"));
service. export();
System.out.println("dubbo service started");
new CountDownLatch(1). await();
}
}
  1. 创建消费者

public class StreamConsumer { public static void main(String[] args) throws InterruptedException, IOException { ReferenceConfigref = new ReferenceConfig<>(); ref. setInterface(IStreamGreeter. class); ref. setCheck(false); ref.setProtocol(CommonConstants.TRIPLE); ref. setLazy(true); ref. setTimeout(100000); ref. setApplication(new ApplicationConfig(“stream-consumer”)); ref.setRegistry(new RegistryConfig(“zookeeper://mse-6e9fda00-p.zk.mse.aliyuncs.com:2181”)); final IStreamGreeter iStreamGreeter = ref. get();

System.out.println(“dubbo ref started”); try {

StreamObserverstreamObserver = iStreamGreeter.sayHello(new StreamObserver() { @Override public void onNext(HelloReply reply) { System.out.println(“onNext”); System.out.println(reply.getMessage()); }

@Override public void onError(Throwable throwable) { System.out.println(“onError:” + throwable.getMessage()); }

@Override public void onCompleted() { System.out.println(“onCompleted”); } });

streamObserver.onNext(HelloRequest.newBuilder() .setName(“tony”) .build());

streamObserver.onNext(HelloRequest.newBuilder() .setName(“nick”) .build());

streamObserver.onCompleted(); } catch (Throwable t) { t. printStackTrace(); } System.in.read(); } }


12. Run Provider and Consumer, you can see that the request returns normally
    > onNext\
    > receive name:tony\
    > onNext\
    > receive name:nick\
    > onCompleted

### Other serialization methods
Omit steps 1-3 above, and specify the protocol used by Provider and Consumer to complete the protocol upgrade.

### Example program
The sample program of this article can be found in [triple-samples](https://github.com/apache/dubbo-samples/tree/master/3-extensions/protocol/dubbo-samples-triple)

上次修改时间:2023 年 1 月 2 日: 增强英文文档 (#1798) (95a9f4f6c1c)