使用說明

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 Message 類別

    $ 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. 建立 Provider

        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. 建立 Consumer

    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. 執行 Provider 和 Consumer,您可以看到請求正常返回

    回覆:message: “name”

串流模式

  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. 建立 Consumer

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)