| <rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Apache Dubbo – Triple协议</title><link>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/triple/</link><description>Recent content in Triple协议 on Apache Dubbo</description><generator>Hugo -- gohugo.io</generator><language>zh-cn</language><atom:link href="https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/triple/index.xml" rel="self" type="application/rss+xml"/><item><title>Overview: 协议概述</title><link>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/triple/overview/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/triple/overview/</guid><description> |
| <h2 id="概述说明">概述说明</h2> |
| <p><code>Triple</code> 协议的格式和原理请参阅 <a href="https://dubbo.apache.org/zh-cn/docs/concepts/rpc-protocol/">RPC 通信协议</a></p> |
| <p>根据 Triple 设计的目标,<code>Triple</code> 协议有以下优势</p> |
| <ul> |
| <li>具备跨语言交互的能力,传统的多语言多 SDK 模式和 Mesh 化跨语言模式都需要一种更通用易扩展的数据传输协议。</li> |
| <li>提供更完善的请求模型,除了支持传统的 Request/Response 模型(Unary 单向通信),还支持 Stream(流式通信) 和 Bidirectional(双向通信)。</li> |
| <li>易扩展、穿透性高,包括但不限于 Tracing / Monitoring 等支持,也应该能被各层设备识别,网关设施等可以识别数据报文,对 Service Mesh 部署友好,降低用户理解难度。</li> |
| <li>完全兼容 grpc,客户端/服务端可以与原生grpc客户端打通。</li> |
| <li>可以复用现有 grpc 生态下的组件, 满足云原生场景下的跨语言、跨环境、跨平台的互通需求。</li> |
| </ul> |
| <p>当前使用其他协议的 Dubbo 用户,框架提供了兼容现有序列化方式的迁移能力,在不影响线上已有业务的前提下,迁移协议的成本几乎为零。</p> |
| <h3 id="grpc">GRPC</h3> |
| <p>需要新增对接 grpc 服务的 Dubbo 用户,可以直接使用 Triple 协议来实现打通,不需要单独引入 grpc client 来完成,不仅能保留已有的 Dubbo 易用性,也能降低程序的复杂度和开发运维成本,不需要额外进行适配和开发即可接入现有生态。</p> |
| <h3 id="网关接入">网关接入</h3> |
| <p>对于需要网关接入的 Dubbo 用户,Triple 协议提供了更加原生的方式,让网关开发或者使用开源的 grpc 网关组件更加简单。网关可以选择不解析 payload ,在性能上也有很大提高。在使用 Dubbo 协议时,语言相关的序列化方式是网关的一个很大痛点,而传统的 HTTP 转 Dubbo 的方式对于跨语言序列化几乎是无能为力的。同时,由于 Triple 的协议元数据都存储在请求头中,网关可以轻松的实现定制需求,如路由和限流等功能。</p> |
| <h2 id="常见问题">常见问题</h2> |
| <h3 id="q1">Q1</h3> |
| <p>protobuf 类找不到</p> |
| <p>由于 Triple 协议底层需要依赖 protobuf 协议进行传输,即使定义的服务接口不使用 protobuf 也需要在环境中引入 protobuf 的依赖。</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-xml" data-lang="xml"><span style="display:flex;"><span> <span style="color:#268bd2">&lt;dependency&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;groupId&gt;</span>com.google.protobuf<span style="color:#268bd2">&lt;/groupId&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;artifactId&gt;</span>protobuf-java<span style="color:#268bd2">&lt;/artifactId&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;version&gt;</span>3.19.4<span style="color:#268bd2">&lt;/version&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;/dependency&gt;</span> |
| </span></span></code></pre></div></description></item><item><title>Overview: IDL 方式使用 Triple</title><link>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/triple/idl/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/triple/idl/</guid><description> |
| <p>这篇教程会通过从零构建一个简单的工程来演示如何基于 IDL 方式使用 Dubbo Triple</p> |
| <h2 id="前置条件">前置条件</h2> |
| <ul> |
| <li><a href="https://jdk.java.net/">JDK</a> 版本 &gt;= 8</li> |
| <li>已安装 <a href="https://maven.apache.org/">Maven</a></li> |
| <li>已安装并启动 <a href="https://zookeeper.apache.org/">Zookeeper</a></li> |
| </ul> |
| <h2 id="创建工程">创建工程</h2> |
| <h3 id="1-创建一个空的-maven-工程">1. 创建一个空的 maven 工程</h3> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>$ mvn archetype:generate \ |
| </span></span><span style="display:flex;"><span> -DgroupId=org.apache.dubbo \ |
| </span></span><span style="display:flex;"><span> -DartifactId=tri-stub-demo \ |
| </span></span><span style="display:flex;"><span> -DarchetypeArtifactId=maven-archetype-quickstart \ |
| </span></span><span style="display:flex;"><span> -DarchetypeVersion=1.4 \ |
| </span></span><span style="display:flex;"><span> -DarchetypeGroupId=org.apache.maven.archetypes \ |
| </span></span><span style="display:flex;"><span> -Dversion=1.0-SNAPSHOT |
| </span></span></code></pre></div><h3 id="2-切换到工程目录">2. 切换到工程目录</h3> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span> $ cd tri-stub-demo |
| </span></span></code></pre></div><h3 id="3-添加-dubbo-依赖和插件">3. 添加 Dubbo 依赖和插件</h3> |
| <p>在 <code>pom.xml</code> 中设置 JDK 版本</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-xml" data-lang="xml"><span style="display:flex;"><span> <span style="color:#268bd2">&lt;properties&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;project.build.sourceEncoding&gt;</span>UTF-8<span style="color:#268bd2">&lt;/project.build.sourceEncoding&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;maven.compiler.source&gt;</span>1.8<span style="color:#268bd2">&lt;/maven.compiler.source&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;maven.compiler.target&gt;</span>1.8<span style="color:#268bd2">&lt;/maven.compiler.target&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;dubbo.version&gt;</span>3.1.7<span style="color:#268bd2">&lt;/dubbo.version&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;/properties&gt;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;dependencies&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;dependency&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;groupId&gt;</span>junit<span style="color:#268bd2">&lt;/groupId&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;artifactId&gt;</span>junit<span style="color:#268bd2">&lt;/artifactId&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;version&gt;</span>4.13<span style="color:#268bd2">&lt;/version&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;scope&gt;</span>test<span style="color:#268bd2">&lt;/scope&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;/dependency&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;dependency&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;groupId&gt;</span>org.apache.dubbo<span style="color:#268bd2">&lt;/groupId&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;artifactId&gt;</span>dubbo<span style="color:#268bd2">&lt;/artifactId&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;version&gt;</span>${dubbo.version}<span style="color:#268bd2">&lt;/version&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;/dependency&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;dependency&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;groupId&gt;</span>org.apache.dubbo<span style="color:#268bd2">&lt;/groupId&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;artifactId&gt;</span>dubbo-dependencies-zookeeper-curator5<span style="color:#268bd2">&lt;/artifactId&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;type&gt;</span>pom<span style="color:#268bd2">&lt;/type&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;version&gt;</span>${dubbo.version}<span style="color:#268bd2">&lt;/version&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;/dependency&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;dependency&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;groupId&gt;</span>com.google.protobuf<span style="color:#268bd2">&lt;/groupId&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;artifactId&gt;</span>protobuf-java<span style="color:#268bd2">&lt;/artifactId&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;version&gt;</span>3.19.4<span style="color:#268bd2">&lt;/version&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;/dependency&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;/dependencies&gt;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;build&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;extensions&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;extension&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;groupId&gt;</span>kr.motd.maven<span style="color:#268bd2">&lt;/groupId&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;artifactId&gt;</span>os-maven-plugin<span style="color:#268bd2">&lt;/artifactId&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;version&gt;</span>1.6.1<span style="color:#268bd2">&lt;/version&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;/extension&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;/extensions&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;plugins&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;plugin&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;groupId&gt;</span>org.xolstice.maven.plugins<span style="color:#268bd2">&lt;/groupId&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;artifactId&gt;</span>protobuf-maven-plugin<span style="color:#268bd2">&lt;/artifactId&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;version&gt;</span>0.6.1<span style="color:#268bd2">&lt;/version&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;configuration&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;protocArtifact&gt;</span>com.google.protobuf:protoc:3.19.4:exe:${os.detected.classifier}<span style="color:#268bd2">&lt;/protocArtifact&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;protocPlugins&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;protocPlugin&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;id&gt;</span>dubbo<span style="color:#268bd2">&lt;/id&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;groupId&gt;</span>org.apache.dubbo<span style="color:#268bd2">&lt;/groupId&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;artifactId&gt;</span>dubbo-compiler<span style="color:#268bd2">&lt;/artifactId&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;version&gt;</span>${dubbo.version}<span style="color:#268bd2">&lt;/version&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;mainClass&gt;</span>org.apache.dubbo.gen.tri.Dubbo3TripleGenerator<span style="color:#268bd2">&lt;/mainClass&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;/protocPlugin&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;/protocPlugins&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;/configuration&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;executions&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;execution&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;goals&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;goal&gt;</span>compile<span style="color:#268bd2">&lt;/goal&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;/goals&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;/execution&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;/executions&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;/plugin&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;/plugins&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;/build&gt;</span> |
| </span></span></code></pre></div><h3 id="4-添加接口定义文件">4. 添加接口定义文件</h3> |
| <p><code>src/main/proto/hello.proto</code>,Dubbo 使用 <a href="https://developers.google.com/protocol-buffers">Protobuf</a> 作为 IDL</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-protobuf" data-lang="protobuf"><span style="display:flex;"><span> syntax <span style="color:#719e07">=</span> <span style="color:#2aa198">&#34;proto3&#34;</span>; |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">option</span> java_multiple_files <span style="color:#719e07">=</span> <span style="color:#cb4b16">true</span>; |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">option</span> java_package <span style="color:#719e07">=</span> <span style="color:#2aa198">&#34;org.apache.dubbo.hello&#34;</span>; |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">option</span> java_outer_classname <span style="color:#719e07">=</span> <span style="color:#2aa198">&#34;HelloWorldProto&#34;</span>; |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">option</span> objc_class_prefix <span style="color:#719e07">=</span> <span style="color:#2aa198">&#34;HLW&#34;</span>; |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">package</span> helloworld; |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">message</span> <span style="color:#268bd2">HelloRequest</span> { |
| </span></span><span style="display:flex;"><span> <span style="color:#dc322f">string</span> name <span style="color:#719e07">=</span> <span style="color:#2aa198">1</span>; |
| </span></span><span style="display:flex;"><span> } |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">message</span> <span style="color:#268bd2">HelloReply</span> { |
| </span></span><span style="display:flex;"><span> <span style="color:#dc322f">string</span> <span style="color:#268bd2">message</span> <span style="color:#719e07">=</span> <span style="color:#2aa198">1</span>; |
| </span></span><span style="display:flex;"><span> } |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">service</span> Greeter{ |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">rpc</span> greet(HelloRequest) <span style="color:#719e07">returns</span> (HelloReply); |
| </span></span><span style="display:flex;"><span> } |
| </span></span></code></pre></div><h3 id="5-编译-idl">5. 编译 IDL</h3> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span> $ mvn clean install |
| </span></span></code></pre></div><p>编译成功后,可以看到<code>target/generated-sources/protobuf/java</code> 目录下生成了代码文件</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span> $ ls org/apache/dubbo/hello/ |
| </span></span><span style="display:flex;"><span> DubboGreeterTriple.java HelloReply.java HelloRequest.java HelloWorldProto.java |
| </span></span><span style="display:flex;"><span> Greeter.java HelloReplyOrBuilder.java HelloRequestOrBuilder.java |
| </span></span></code></pre></div><h3 id="6-添加服务端接口实现">6. 添加服务端接口实现</h3> |
| <p><code>src/main/java/org/apache/dubbo/GreeterImpl.java</code></p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span> <span style="color:#719e07">package</span> org.apache.dubbo; |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">import</span> org.apache.dubbo.hello.DubboGreeterTriple; |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">import</span> org.apache.dubbo.hello.HelloReply; |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">import</span> org.apache.dubbo.hello.HelloRequest; |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#268bd2">class</span> <span style="color:#268bd2">GreeterImpl</span> <span style="color:#268bd2">extends</span> DubboGreeterTriple.GreeterImplBase { |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">@Override</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> HelloReply <span style="color:#268bd2">greet</span>(HelloRequest request) { |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">return</span> HelloReply.newBuilder() |
| </span></span><span style="display:flex;"><span> .setMessage(<span style="color:#2aa198">&#34;Hello,&#34;</span> <span style="color:#719e07">+</span> request.getName() <span style="color:#719e07">+</span> <span style="color:#2aa198">&#34;!&#34;</span>) |
| </span></span><span style="display:flex;"><span> .build(); |
| </span></span><span style="display:flex;"><span> } |
| </span></span><span style="display:flex;"><span> } |
| </span></span></code></pre></div><h3 id="7-添加服务端启动类">7. 添加服务端启动类</h3> |
| <p><code>src/main/java/org/apache/dubbo/MyDubboServer.java</code></p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span> <span style="color:#719e07">package</span> org.apache.dubbo; |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">import</span> org.apache.dubbo.common.constants.CommonConstants; |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">import</span> org.apache.dubbo.config.ApplicationConfig; |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">import</span> org.apache.dubbo.config.ProtocolConfig; |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">import</span> org.apache.dubbo.config.RegistryConfig; |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">import</span> org.apache.dubbo.config.ServiceConfig; |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">import</span> org.apache.dubbo.config.bootstrap.DubboBootstrap; |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">import</span> org.apache.dubbo.hello.Greeter; |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">import</span> java.io.IOException; |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#268bd2">class</span> <span style="color:#268bd2">MyDubboServer</span> { |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#268bd2">static</span> <span style="color:#dc322f">void</span> <span style="color:#268bd2">main</span>(String<span style="color:#719e07">[]</span> args) <span style="color:#268bd2">throws</span> IOException { |
| </span></span><span style="display:flex;"><span> ServiceConfig<span style="color:#719e07">&lt;</span>Greeter<span style="color:#719e07">&gt;</span> service <span style="color:#719e07">=</span> <span style="color:#719e07">new</span> ServiceConfig<span style="color:#719e07">&lt;&gt;</span>(); |
| </span></span><span style="display:flex;"><span> service.setInterface(Greeter.class); |
| </span></span><span style="display:flex;"><span> service.setRef(<span style="color:#719e07">new</span> GreeterImpl()); |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> DubboBootstrap bootstrap <span style="color:#719e07">=</span> DubboBootstrap.getInstance(); |
| </span></span><span style="display:flex;"><span> bootstrap.application(<span style="color:#719e07">new</span> ApplicationConfig(<span style="color:#2aa198">&#34;tri-stub-server&#34;</span>)) |
| </span></span><span style="display:flex;"><span> .registry(<span style="color:#719e07">new</span> RegistryConfig(<span style="color:#2aa198">&#34;zookeeper://127.0.0.1:2181&#34;</span>)) |
| </span></span><span style="display:flex;"><span> .protocol(<span style="color:#719e07">new</span> ProtocolConfig(CommonConstants.TRIPLE, 50051)) |
| </span></span><span style="display:flex;"><span> .service(service) |
| </span></span><span style="display:flex;"><span> .start(); |
| </span></span><span style="display:flex;"><span> System.out.println(<span style="color:#2aa198">&#34;Dubbo triple stub server started&#34;</span>); |
| </span></span><span style="display:flex;"><span> System.in.read(); |
| </span></span><span style="display:flex;"><span> } |
| </span></span><span style="display:flex;"><span> } |
| </span></span></code></pre></div><h3 id="8-添加客户端启动类">8. 添加客户端启动类</h3> |
| <p><code>src/main/java/org/apache/dubbo/MyDubboClient.java</code></p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span> <span style="color:#719e07">package</span> org.apache.dubbo; |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">import</span> org.apache.dubbo.common.constants.CommonConstants; |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">import</span> org.apache.dubbo.config.ApplicationConfig; |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">import</span> org.apache.dubbo.config.ReferenceConfig; |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">import</span> org.apache.dubbo.config.RegistryConfig; |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">import</span> org.apache.dubbo.config.bootstrap.DubboBootstrap; |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">import</span> org.apache.dubbo.hello.Greeter; |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">import</span> org.apache.dubbo.hello.HelloReply; |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">import</span> org.apache.dubbo.hello.HelloRequest; |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#268bd2">class</span> <span style="color:#268bd2">MyDubboClient</span> { |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#268bd2">static</span> <span style="color:#dc322f">void</span> <span style="color:#268bd2">main</span>(String<span style="color:#719e07">[]</span> args) { |
| </span></span><span style="display:flex;"><span> DubboBootstrap bootstrap <span style="color:#719e07">=</span> DubboBootstrap.getInstance(); |
| </span></span><span style="display:flex;"><span> ReferenceConfig<span style="color:#719e07">&lt;</span>Greeter<span style="color:#719e07">&gt;</span> ref <span style="color:#719e07">=</span> <span style="color:#719e07">new</span> ReferenceConfig<span style="color:#719e07">&lt;&gt;</span>(); |
| </span></span><span style="display:flex;"><span> ref.setInterface(Greeter.class); |
| </span></span><span style="display:flex;"><span> ref.setProtocol(CommonConstants.TRIPLE); |
| </span></span><span style="display:flex;"><span> ref.setProxy(CommonConstants.NATIVE_STUB); |
| </span></span><span style="display:flex;"><span> ref.setTimeout(3000); |
| </span></span><span style="display:flex;"><span> bootstrap.application(<span style="color:#719e07">new</span> ApplicationConfig(<span style="color:#2aa198">&#34;tri-stub-client&#34;</span>)) |
| </span></span><span style="display:flex;"><span> .registry(<span style="color:#719e07">new</span> RegistryConfig(<span style="color:#2aa198">&#34;zookeeper://127.0.0.1:2181&#34;</span>)) |
| </span></span><span style="display:flex;"><span> .reference(ref) |
| </span></span><span style="display:flex;"><span> .start(); |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> Greeter greeter <span style="color:#719e07">=</span> ref.get(); |
| </span></span><span style="display:flex;"><span> HelloRequest request <span style="color:#719e07">=</span> HelloRequest.newBuilder().setName(<span style="color:#2aa198">&#34;Demo&#34;</span>).build(); |
| </span></span><span style="display:flex;"><span> HelloReply reply <span style="color:#719e07">=</span> greeter.greet(request); |
| </span></span><span style="display:flex;"><span> System.out.println(<span style="color:#2aa198">&#34;Received reply:&#34;</span> <span style="color:#719e07">+</span> reply); |
| </span></span><span style="display:flex;"><span> } |
| </span></span><span style="display:flex;"><span> } |
| </span></span></code></pre></div><h3 id="9-编译代码">9. 编译代码</h3> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>$ mvn clean install |
| </span></span></code></pre></div><h3 id="10-启动服务端">10. 启动服务端</h3> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>$ mvn org.codehaus.mojo:exec-maven-plugin:3.0.0:java -Dexec.mainClass=&#34;org.apache.dubbo.MyDubboServer&#34; |
| </span></span><span style="display:flex;"><span>Dubbo triple stub server started |
| </span></span></code></pre></div><h3 id="11-打开新的终端启动客户端">11. 打开新的终端,启动客户端</h3> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>$ mvn org.codehaus.mojo:exec-maven-plugin:3.0.0:java -Dexec.mainClass=&#34;org.apache.dubbo.MyDubboClient&#34; |
| </span></span><span style="display:flex;"><span>Received reply:message: &#34;Hello,Demo!&#34; |
| </span></span></code></pre></div></description></item><item><title>Overview: POJO 方式使用 Triple</title><link>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/triple/pojo/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/triple/pojo/</guid><description> |
| <p>这篇教程会通过从零构建一个简单的工程来演示如何基于 POJO 方式使用 Dubbo Triple, 在应用不改变已有接口定义的同时升级到 Triple 协议。</p> |
| <h3 id="实现原理">实现原理</h3> |
| <p>通过上面介绍的升级过程,我们可以很简单的通过修改协议类型来完成升级。框架是怎么帮我们做到这些的呢?</p> |
| <p>通过对 <code>Triple</code> 协议的介绍,我们知道Dubbo3的 <code>Triple</code> 的数据类型是 <code>protobuf</code> 对象,那为什么非 <code>protobuf</code> 的 java 对象也可以被正常传输呢。</p> |
| <p>这里 Dubbo3 使用了一个巧妙的设计,首先判断参数类型是否为 <code>protobuf</code> 对象,如果不是。用一个 <code>protobuf</code> 对象将 <code>request</code> 和 <code>response</code> 进行 wrapper,这样就屏蔽了其他各种序列化带来的复杂度。在 <code>wrapper</code> 对象内部声明序列化类型,来支持序列化的扩展。</p> |
| <p>wrapper 的<code>protobuf</code>的 IDL如下:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-proto" data-lang="proto"><span style="display:flex;"><span>syntax <span style="color:#719e07">=</span> <span style="color:#2aa198">&#34;proto3&#34;</span>; |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">package</span> org<span style="color:#719e07">.</span>apache.dubbo.triple; |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">message</span> <span style="color:#268bd2">TripleRequestWrapper</span> { |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// hessian4 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#586e75">// json |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#dc322f">string</span> serializeType <span style="color:#719e07">=</span> <span style="color:#2aa198">1</span>; |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">repeated</span> <span style="color:#dc322f">bytes</span> args <span style="color:#719e07">=</span> <span style="color:#2aa198">2</span>; |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">repeated</span> <span style="color:#dc322f">string</span> argTypes <span style="color:#719e07">=</span> <span style="color:#2aa198">3</span>; |
| </span></span><span style="display:flex;"><span>} |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">message</span> <span style="color:#268bd2">TripleResponseWrapper</span> { |
| </span></span><span style="display:flex;"><span> <span style="color:#dc322f">string</span> serializeType <span style="color:#719e07">=</span> <span style="color:#2aa198">1</span>; |
| </span></span><span style="display:flex;"><span> <span style="color:#dc322f">bytes</span> data <span style="color:#719e07">=</span> <span style="color:#2aa198">2</span>; |
| </span></span><span style="display:flex;"><span> <span style="color:#dc322f">string</span> type <span style="color:#719e07">=</span> <span style="color:#2aa198">3</span>; |
| </span></span><span style="display:flex;"><span>} |
| </span></span></code></pre></div><p>对于请求,使用<code>TripleRequestWrapper</code>进行包装,对于响应使用<code>TripleResponseWrapper</code>进行包装。</p> |
| <blockquote> |
| <p>对于请求参数,可以看到 args 被<code>repeated</code>修饰,这是因为需要支持 java 方法的多个参数。当然,序列化只能是一种。序列化的实现沿用 Dubbo2 实现的 spi</p> |
| </blockquote> |
| <h3 id="前置条件">前置条件</h3> |
| <ul> |
| <li><a href="https://jdk.java.net/">JDK</a> 版本 &gt;= 8</li> |
| <li>已安装 <a href="https://maven.apache.org/">Maven</a></li> |
| <li>已安装并启动 <a href="https://zookeeper.apache.org/">Zookeeper</a></li> |
| </ul> |
| <h3 id="创建工程">创建工程</h3> |
| <ol> |
| <li>首先创建一个空的 maven 工程</li> |
| </ol> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>$ mvn archetype:generate \ |
| </span></span><span style="display:flex;"><span> -DgroupId=org.apache.dubbo \ |
| </span></span><span style="display:flex;"><span> -DartifactId=tri-pojo-demo \ |
| </span></span><span style="display:flex;"><span> -DarchetypeArtifactId=maven-archetype-quickstart \ |
| </span></span><span style="display:flex;"><span> -DarchetypeVersion=1.4 \ |
| </span></span><span style="display:flex;"><span> -DarchetypeGroupId=org.apache.maven.archetypes \ |
| </span></span><span style="display:flex;"><span> -Dversion=1.0-SNAPSHOT |
| </span></span></code></pre></div><ol start="2"> |
| <li>切换到工程目录</li> |
| </ol> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>$ cd tri-pojo-demo |
| </span></span></code></pre></div><ol start="3"> |
| <li>在 <code>pom.xml</code> 中设置 JDK 版本,添加 Dubbo 依赖和插件</li> |
| </ol> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-xml" data-lang="xml"><span style="display:flex;"><span> <span style="color:#268bd2">&lt;properties&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;project.build.sourceEncoding&gt;</span>UTF-8<span style="color:#268bd2">&lt;/project.build.sourceEncoding&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;maven.compiler.source&gt;</span>1.8<span style="color:#268bd2">&lt;/maven.compiler.source&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;maven.compiler.target&gt;</span>1.8<span style="color:#268bd2">&lt;/maven.compiler.target&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;/properties&gt;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;dependencies&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;dependency&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;groupId&gt;</span>junit<span style="color:#268bd2">&lt;/groupId&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;artifactId&gt;</span>junit<span style="color:#268bd2">&lt;/artifactId&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;version&gt;</span>4.13<span style="color:#268bd2">&lt;/version&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;scope&gt;</span>test<span style="color:#268bd2">&lt;/scope&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;/dependency&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;dependency&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;groupId&gt;</span>org.apache.dubbo<span style="color:#268bd2">&lt;/groupId&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;artifactId&gt;</span>dubbo<span style="color:#268bd2">&lt;/artifactId&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;version&gt;</span>3.0.8<span style="color:#268bd2">&lt;/version&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;/dependency&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;dependency&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;groupId&gt;</span>org.apache.dubbo<span style="color:#268bd2">&lt;/groupId&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;artifactId&gt;</span>dubbo-dependencies-zookeeper-curator5<span style="color:#268bd2">&lt;/artifactId&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;type&gt;</span>pom<span style="color:#268bd2">&lt;/type&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;version&gt;</span>3.0.8<span style="color:#268bd2">&lt;/version&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;/dependency&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;dependency&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;groupId&gt;</span>com.google.protobuf<span style="color:#268bd2">&lt;/groupId&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;artifactId&gt;</span>protobuf-java<span style="color:#268bd2">&lt;/artifactId&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;version&gt;</span>3.19.4<span style="color:#268bd2">&lt;/version&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;/dependency&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;/dependencies&gt;</span> |
| </span></span></code></pre></div><ol start="4"> |
| <li>添加接口定义<code>src/main/java/org/apache/dubbo/Greeter.java</code></li> |
| </ol> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span> <span style="color:#719e07">package</span> org.apache.dubbo; |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#268bd2">interface</span> <span style="color:#268bd2">Greeter</span> { |
| </span></span><span style="display:flex;"><span> String <span style="color:#268bd2">sayHello</span>(String name); |
| </span></span><span style="display:flex;"><span> } |
| </span></span></code></pre></div><ol start="5"> |
| <li>添加服务端接口实现<code>src/main/java/org/apache/dubbo/GreeterImpl.java</code></li> |
| </ol> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span> <span style="color:#719e07">package</span> org.apache.dubbo; |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#268bd2">class</span> <span style="color:#268bd2">GreeterImpl</span> <span style="color:#268bd2">implements</span> Greeter { |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">@Override</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> String <span style="color:#268bd2">sayHello</span>(String name) { |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">return</span> <span style="color:#2aa198">&#34;Hello,&#34;</span> <span style="color:#719e07">+</span> name <span style="color:#719e07">+</span> <span style="color:#2aa198">&#34;!&#34;</span>; |
| </span></span><span style="display:flex;"><span> } |
| </span></span><span style="display:flex;"><span> } |
| </span></span></code></pre></div><ol start="6"> |
| <li>添加服务端启动类 <code>src/main/java/org/apache/dubbo/MyDubboServer.java</code></li> |
| </ol> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span> <span style="color:#719e07">package</span> org.apache.dubbo; |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">import</span> org.apache.dubbo.common.constants.CommonConstants; |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">import</span> org.apache.dubbo.config.ApplicationConfig; |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">import</span> org.apache.dubbo.config.ProtocolConfig; |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">import</span> org.apache.dubbo.config.RegistryConfig; |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">import</span> org.apache.dubbo.config.ServiceConfig; |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">import</span> org.apache.dubbo.config.bootstrap.DubboBootstrap; |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">import</span> java.io.IOException; |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#268bd2">class</span> <span style="color:#268bd2">MyDubboServer</span> { |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#268bd2">static</span> <span style="color:#dc322f">void</span> <span style="color:#268bd2">main</span>(String<span style="color:#719e07">[]</span> args) <span style="color:#268bd2">throws</span> IOException { |
| </span></span><span style="display:flex;"><span> ServiceConfig<span style="color:#719e07">&lt;</span>Greeter<span style="color:#719e07">&gt;</span> service <span style="color:#719e07">=</span> <span style="color:#719e07">new</span> ServiceConfig<span style="color:#719e07">&lt;&gt;</span>(); |
| </span></span><span style="display:flex;"><span> service.setInterface(Greeter.class); |
| </span></span><span style="display:flex;"><span> service.setRef(<span style="color:#719e07">new</span> GreeterImpl()); |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> DubboBootstrap bootstrap <span style="color:#719e07">=</span> DubboBootstrap.getInstance(); |
| </span></span><span style="display:flex;"><span> bootstrap.application(<span style="color:#719e07">new</span> ApplicationConfig(<span style="color:#2aa198">&#34;tri-pojo-server&#34;</span>)) |
| </span></span><span style="display:flex;"><span> .registry(<span style="color:#719e07">new</span> RegistryConfig(<span style="color:#2aa198">&#34;zookeeper://127.0.0.1:2181&#34;</span>)) |
| </span></span><span style="display:flex;"><span> .protocol(<span style="color:#719e07">new</span> ProtocolConfig(CommonConstants.TRIPLE, 50051)) |
| </span></span><span style="display:flex;"><span> .service(service) |
| </span></span><span style="display:flex;"><span> .start(); |
| </span></span><span style="display:flex;"><span> System.out.println(<span style="color:#2aa198">&#34;Dubbo triple pojo server started&#34;</span>); |
| </span></span><span style="display:flex;"><span> System.in.read(); |
| </span></span><span style="display:flex;"><span> } |
| </span></span><span style="display:flex;"><span> } |
| </span></span></code></pre></div><ol start="7"> |
| <li>添加客户端启动类<code>src/main/java/org/apache/dubbo/MyDubboClient.java</code></li> |
| </ol> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span> <span style="color:#719e07">package</span> org.apache.dubbo; |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">import</span> org.apache.dubbo.common.constants.CommonConstants; |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">import</span> org.apache.dubbo.config.ApplicationConfig; |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">import</span> org.apache.dubbo.config.ReferenceConfig; |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">import</span> org.apache.dubbo.config.RegistryConfig; |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">import</span> org.apache.dubbo.config.bootstrap.DubboBootstrap; |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#268bd2">class</span> <span style="color:#268bd2">MyDubboClient</span> { |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#268bd2">static</span> <span style="color:#dc322f">void</span> <span style="color:#268bd2">main</span>(String<span style="color:#719e07">[]</span> args) { |
| </span></span><span style="display:flex;"><span> DubboBootstrap bootstrap <span style="color:#719e07">=</span> DubboBootstrap.getInstance(); |
| </span></span><span style="display:flex;"><span> ReferenceConfig<span style="color:#719e07">&lt;</span>Greeter<span style="color:#719e07">&gt;</span> ref <span style="color:#719e07">=</span> <span style="color:#719e07">new</span> ReferenceConfig<span style="color:#719e07">&lt;&gt;</span>(); |
| </span></span><span style="display:flex;"><span> ref.setInterface(Greeter.class); |
| </span></span><span style="display:flex;"><span> ref.setProtocol(CommonConstants.TRIPLE); |
| </span></span><span style="display:flex;"><span> ref.setTimeout(3000); |
| </span></span><span style="display:flex;"><span> bootstrap.application(<span style="color:#719e07">new</span> ApplicationConfig(<span style="color:#2aa198">&#34;tri-pojo-client&#34;</span>)) |
| </span></span><span style="display:flex;"><span> .registry(<span style="color:#719e07">new</span> RegistryConfig(<span style="color:#2aa198">&#34;zookeeper://127.0.0.1:2181&#34;</span>)) |
| </span></span><span style="display:flex;"><span> .reference(ref) |
| </span></span><span style="display:flex;"><span> .start(); |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> Greeter greeter <span style="color:#719e07">=</span> ref.get(); |
| </span></span><span style="display:flex;"><span> String reply <span style="color:#719e07">=</span> greeter.sayHello(<span style="color:#2aa198">&#34;pojo&#34;</span>); |
| </span></span><span style="display:flex;"><span> System.out.println(<span style="color:#2aa198">&#34;Received reply:&#34;</span> <span style="color:#719e07">+</span> reply); |
| </span></span><span style="display:flex;"><span> } |
| </span></span><span style="display:flex;"><span> } |
| </span></span></code></pre></div><ol start="8"> |
| <li>编译代码</li> |
| </ol> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>$ mvn clean install |
| </span></span></code></pre></div><ol start="9"> |
| <li>启动服务端</li> |
| </ol> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>$ mvn org.codehaus.mojo:exec-maven-plugin:3.0.0:java -Dexec.mainClass=&#34;org.apache.dubbo.MyDubboServer&#34; |
| </span></span></code></pre></div> |
| <div class="alert alert-info" role="alert"> |
| <h4 class="alert-heading">输出结果</h4> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>Dubbo triple pojo server started |
| </span></span></code></pre></div> |
| </div> |
| <ol start="10"> |
| <li>打开新的终端,启动客户端</li> |
| </ol> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>$ mvn org.codehaus.mojo:exec-maven-plugin:3.0.0:java -Dexec.mainClass=&#34;org.apache.dubbo.MyDubboClient&#34; |
| </span></span></code></pre></div> |
| <div class="alert alert-info" role="alert"> |
| <h4 class="alert-heading">输出结果</h4> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>Received reply:message: <span style="color:#2aa198">&#34;Hello,Demo!&#34;</span> |
| </span></span></code></pre></div> |
| </div></description></item><item><title>Overview: 协议使用方式</title><link>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/triple/guide/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/triple/guide/</guid><description> |
| <p>Triple 协议是 Dubbo3 的主力协议,完整兼容 gRPC over HTTP/2,并在协议层面扩展了负载均衡和流量控制相关机制。本文档旨在指导用户正确的使用 Triple 协议。</p> |
| <p>在开始前,需要决定服务使用的序列化方式,如果为新服务,推荐使用 protobuf 作为默认序列化,在性能和跨语言上的效果都会更好。如果是原有服务想进行协议升级,Triple 协议也已经支持其他序列化方式,如 Hessian / JSON 等</p> |
| <h3 id="protobuf-方式">Protobuf 方式</h3> |
| <ol> |
| <li>编写 IDL 文件</li> |
| </ol> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-protobuf" data-lang="protobuf"><span style="display:flex;"><span> syntax <span style="color:#719e07">=</span> <span style="color:#2aa198">&#34;proto3&#34;</span>; |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">option</span> java_multiple_files <span style="color:#719e07">=</span> <span style="color:#cb4b16">true</span>; |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">option</span> java_package <span style="color:#719e07">=</span> <span style="color:#2aa198">&#34;org.apache.dubbo.hello&#34;</span>; |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">option</span> java_outer_classname <span style="color:#719e07">=</span> <span style="color:#2aa198">&#34;HelloWorldProto&#34;</span>; |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">option</span> objc_class_prefix <span style="color:#719e07">=</span> <span style="color:#2aa198">&#34;HLW&#34;</span>; |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">package</span> helloworld; |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// The request message containing the user&#39;s name. |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#268bd2">message</span> <span style="color:#268bd2">HelloRequest</span> { |
| </span></span><span style="display:flex;"><span> <span style="color:#dc322f">string</span> name <span style="color:#719e07">=</span> <span style="color:#2aa198">1</span>; |
| </span></span><span style="display:flex;"><span> } |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// The response message containing the greetings |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#268bd2">message</span> <span style="color:#268bd2">HelloReply</span> { |
| </span></span><span style="display:flex;"><span> <span style="color:#dc322f">string</span> <span style="color:#268bd2">message</span> <span style="color:#719e07">=</span> <span style="color:#2aa198">1</span>; |
| </span></span><span style="display:flex;"><span> } |
| </span></span></code></pre></div><ol start="2"> |
| <li>添加编译 protobuf 的 extension 和 plugin (以 maven 为例)</li> |
| </ol> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-xml" data-lang="xml"><span style="display:flex;"><span> <span style="color:#268bd2">&lt;extensions&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;extension&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;groupId&gt;</span>kr.motd.maven<span style="color:#268bd2">&lt;/groupId&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;artifactId&gt;</span>os-maven-plugin<span style="color:#268bd2">&lt;/artifactId&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;version&gt;</span>1.6.1<span style="color:#268bd2">&lt;/version&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;/extension&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;/extensions&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;plugins&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;plugin&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;groupId&gt;</span>org.xolstice.maven.plugins<span style="color:#268bd2">&lt;/groupId&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;artifactId&gt;</span>protobuf-maven-plugin<span style="color:#268bd2">&lt;/artifactId&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;version&gt;</span>0.6.1<span style="color:#268bd2">&lt;/version&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;configuration&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;protocArtifact&gt;</span>com.google.protobuf:protoc:3.7.1:exe:${os.detected.classifier}<span style="color:#268bd2">&lt;/protocArtifact&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;pluginId&gt;</span>triple-java<span style="color:#268bd2">&lt;/pluginId&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;outputDirectory&gt;</span>build/generated/source/proto/main/java<span style="color:#268bd2">&lt;/outputDirectory&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;/configuration&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;executions&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;execution&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;goals&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;goal&gt;</span>compile<span style="color:#268bd2">&lt;/goal&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;goal&gt;</span>test-compile<span style="color:#268bd2">&lt;/goal&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;/goals&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;/execution&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;/executions&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;/plugin&gt;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">&lt;/plugins&gt;</span> |
| </span></span></code></pre></div><ol start="3"> |
| <li>构建/ 编译生成 protobuf Message 类</li> |
| </ol> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>mvn clean install |
| </span></span></code></pre></div><h3 id="unary-方式">Unary 方式</h3> |
| <ol start="4"> |
| <li>编写 Java 接口</li> |
| </ol> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span> <span style="color:#719e07">import</span> org.apache.dubbo.hello.HelloReply; |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">import</span> org.apache.dubbo.hello.HelloRequest; |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#268bd2">interface</span> <span style="color:#268bd2">IGreeter</span> { |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">/** |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * &lt;pre&gt; |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * Sends a greeting |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * &lt;/pre&gt; |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> */</span> |
| </span></span><span style="display:flex;"><span> HelloReply <span style="color:#268bd2">sayHello</span>(HelloRequest request); |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> } |
| </span></span></code></pre></div><ol start="5"> |
| <li>创建 Provider</li> |
| </ol> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#268bd2">static</span> <span style="color:#dc322f">void</span> <span style="color:#268bd2">main</span>(String<span style="color:#719e07">[]</span> args) <span style="color:#268bd2">throws</span> InterruptedException { |
| </span></span><span style="display:flex;"><span> ServiceConfig<span style="color:#719e07">&lt;</span>IGreeter<span style="color:#719e07">&gt;</span> service <span style="color:#719e07">=</span> <span style="color:#719e07">new</span> ServiceConfig<span style="color:#719e07">&lt;&gt;</span>(); |
| </span></span><span style="display:flex;"><span> service.setInterface(IGreeter.class); |
| </span></span><span style="display:flex;"><span> service.setRef(<span style="color:#719e07">new</span> IGreeter1Impl()); |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// 这里需要显示声明使用的协议为triple </span> |
| </span></span><span style="display:flex;"><span> service.setProtocol(<span style="color:#719e07">new</span> ProtocolConfig(CommonConstants.TRIPLE, 50051)); |
| </span></span><span style="display:flex;"><span> service.setApplication(<span style="color:#719e07">new</span> ApplicationConfig(<span style="color:#2aa198">&#34;demo-provider&#34;</span>)); |
| </span></span><span style="display:flex;"><span> service.setRegistry(<span style="color:#719e07">new</span> RegistryConfig(<span style="color:#2aa198">&#34;zookeeper://127.0.0.1:2181&#34;</span>)); |
| </span></span><span style="display:flex;"><span> service.export(); |
| </span></span><span style="display:flex;"><span> System.out.println(<span style="color:#2aa198">&#34;dubbo service started&#34;</span>); |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">new</span> CountDownLatch(1).await(); |
| </span></span><span style="display:flex;"><span> } |
| </span></span></code></pre></div><ol start="6"> |
| <li>创建 Consumer</li> |
| </ol> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#268bd2">static</span> <span style="color:#dc322f">void</span> <span style="color:#268bd2">main</span>(String<span style="color:#719e07">[]</span> args) <span style="color:#268bd2">throws</span> IOException { |
| </span></span><span style="display:flex;"><span> ReferenceConfig<span style="color:#719e07">&lt;</span>IGreeter<span style="color:#719e07">&gt;</span> ref <span style="color:#719e07">=</span> <span style="color:#719e07">new</span> ReferenceConfig<span style="color:#719e07">&lt;&gt;</span>(); |
| </span></span><span style="display:flex;"><span> ref.setInterface(IGreeter.class); |
| </span></span><span style="display:flex;"><span> ref.setCheck(<span style="color:#cb4b16">false</span>); |
| </span></span><span style="display:flex;"><span> ref.setProtocol(CommonConstants.TRIPLE); |
| </span></span><span style="display:flex;"><span> ref.setLazy(<span style="color:#cb4b16">true</span>); |
| </span></span><span style="display:flex;"><span> ref.setTimeout(100000); |
| </span></span><span style="display:flex;"><span> ref.setApplication(<span style="color:#719e07">new</span> ApplicationConfig(<span style="color:#2aa198">&#34;demo-consumer&#34;</span>)); |
| </span></span><span style="display:flex;"><span> ref.setRegistry(<span style="color:#719e07">new</span> RegistryConfig(<span style="color:#2aa198">&#34;zookeeper://127.0.0.1:2181&#34;</span>)); |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">final</span> IGreeter iGreeter <span style="color:#719e07">=</span> ref.get(); |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> System.out.println(<span style="color:#2aa198">&#34;dubbo ref started&#34;</span>); |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">try</span> { |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">final</span> HelloReply reply <span style="color:#719e07">=</span> iGreeter.sayHello(HelloRequest.newBuilder() |
| </span></span><span style="display:flex;"><span> .setName(<span style="color:#2aa198">&#34;name&#34;</span>) |
| </span></span><span style="display:flex;"><span> .build()); |
| </span></span><span style="display:flex;"><span> TimeUnit.SECONDS.sleep(1); |
| </span></span><span style="display:flex;"><span> System.out.println(<span style="color:#2aa198">&#34;Reply:&#34;</span> <span style="color:#719e07">+</span> reply); |
| </span></span><span style="display:flex;"><span> } <span style="color:#719e07">catch</span> (Throwable t) { |
| </span></span><span style="display:flex;"><span> t.printStackTrace(); |
| </span></span><span style="display:flex;"><span> } |
| </span></span><span style="display:flex;"><span> System.in.read(); |
| </span></span><span style="display:flex;"><span> } |
| </span></span></code></pre></div><ol start="7"> |
| <li>运行 Provider 和 Consumer ,可以看到请求正常返回</li> |
| </ol> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#719e07">&gt;</span> Reply:message: <span style="color:#2aa198">&#34;name&#34;</span> |
| </span></span></code></pre></div><h3 id="stream-方式">stream 方式</h3> |
| <ol start="8"> |
| <li>编写 Java 接口</li> |
| </ol> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span> <span style="color:#719e07">import</span> org.apache.dubbo.hello.HelloReply; |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">import</span> org.apache.dubbo.hello.HelloRequest; |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#268bd2">interface</span> <span style="color:#268bd2">IGreeter</span> { |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">/** |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * &lt;pre&gt; |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * Sends greeting by stream |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * &lt;/pre&gt; |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> */</span> |
| </span></span><span style="display:flex;"><span> StreamObserver<span style="color:#719e07">&lt;</span>HelloRequest<span style="color:#719e07">&gt;</span> <span style="color:#268bd2">sayHello</span>(StreamObserver<span style="color:#719e07">&lt;</span>HelloReply<span style="color:#719e07">&gt;</span> replyObserver); |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> } |
| </span></span></code></pre></div><ol start="9"> |
| <li>编写实现类</li> |
| </ol> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#268bd2">class</span> <span style="color:#268bd2">IStreamGreeterImpl</span> <span style="color:#268bd2">implements</span> IStreamGreeter { |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">@Override</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> StreamObserver<span style="color:#719e07">&lt;</span>HelloRequest<span style="color:#719e07">&gt;</span> <span style="color:#268bd2">sayHello</span>(StreamObserver<span style="color:#719e07">&lt;</span>HelloReply<span style="color:#719e07">&gt;</span> replyObserver) { |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">return</span> <span style="color:#719e07">new</span> StreamObserver<span style="color:#719e07">&lt;</span>HelloRequest<span style="color:#719e07">&gt;</span>() { |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">private</span> List<span style="color:#719e07">&lt;</span>HelloReply<span style="color:#719e07">&gt;</span> replyList <span style="color:#719e07">=</span> <span style="color:#719e07">new</span> ArrayList<span style="color:#719e07">&lt;&gt;</span>(); |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">@Override</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#dc322f">void</span> <span style="color:#268bd2">onNext</span>(HelloRequest helloRequest) { |
| </span></span><span style="display:flex;"><span> System.out.println(<span style="color:#2aa198">&#34;onNext receive request name:&#34;</span> <span style="color:#719e07">+</span> helloRequest.getName()); |
| </span></span><span style="display:flex;"><span> replyList.add(HelloReply.newBuilder() |
| </span></span><span style="display:flex;"><span> .setMessage(<span style="color:#2aa198">&#34;receive name:&#34;</span> <span style="color:#719e07">+</span> helloRequest.getName()) |
| </span></span><span style="display:flex;"><span> .build()); |
| </span></span><span style="display:flex;"><span> } |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">@Override</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#dc322f">void</span> <span style="color:#268bd2">onError</span>(Throwable cause) { |
| </span></span><span style="display:flex;"><span> System.out.println(<span style="color:#2aa198">&#34;onError&#34;</span>); |
| </span></span><span style="display:flex;"><span> replyObserver.onError(cause); |
| </span></span><span style="display:flex;"><span> } |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">@Override</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#dc322f">void</span> <span style="color:#268bd2">onCompleted</span>() { |
| </span></span><span style="display:flex;"><span> System.out.println(<span style="color:#2aa198">&#34;onComplete receive request size:&#34;</span> <span style="color:#719e07">+</span> replyList.size()); |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">for</span> (HelloReply reply : replyList) { |
| </span></span><span style="display:flex;"><span> replyObserver.onNext(reply); |
| </span></span><span style="display:flex;"><span> } |
| </span></span><span style="display:flex;"><span> replyObserver.onCompleted(); |
| </span></span><span style="display:flex;"><span> } |
| </span></span><span style="display:flex;"><span> }; |
| </span></span><span style="display:flex;"><span> } |
| </span></span><span style="display:flex;"><span> } |
| </span></span></code></pre></div><ol start="10"> |
| <li>创建 Provider</li> |
| </ol> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#268bd2">class</span> <span style="color:#268bd2">StreamProvider</span> { |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#268bd2">static</span> <span style="color:#dc322f">void</span> <span style="color:#268bd2">main</span>(String<span style="color:#719e07">[]</span> args) <span style="color:#268bd2">throws</span> InterruptedException { |
| </span></span><span style="display:flex;"><span> ServiceConfig<span style="color:#719e07">&lt;</span>IStreamGreeter<span style="color:#719e07">&gt;</span> service <span style="color:#719e07">=</span> <span style="color:#719e07">new</span> ServiceConfig<span style="color:#719e07">&lt;&gt;</span>(); |
| </span></span><span style="display:flex;"><span> service.setInterface(IStreamGreeter.class); |
| </span></span><span style="display:flex;"><span> service.setRef(<span style="color:#719e07">new</span> IStreamGreeterImpl()); |
| </span></span><span style="display:flex;"><span> service.setProtocol(<span style="color:#719e07">new</span> ProtocolConfig(CommonConstants.TRIPLE, 50051)); |
| </span></span><span style="display:flex;"><span> service.setApplication(<span style="color:#719e07">new</span> ApplicationConfig(<span style="color:#2aa198">&#34;stream-provider&#34;</span>)); |
| </span></span><span style="display:flex;"><span> service.setRegistry(<span style="color:#719e07">new</span> RegistryConfig(<span style="color:#2aa198">&#34;zookeeper://127.0.0.1:2181&#34;</span>)); |
| </span></span><span style="display:flex;"><span> service.export(); |
| </span></span><span style="display:flex;"><span> System.out.println(<span style="color:#2aa198">&#34;dubbo service started&#34;</span>); |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">new</span> CountDownLatch(1).await(); |
| </span></span><span style="display:flex;"><span> } |
| </span></span><span style="display:flex;"><span> } |
| </span></span></code></pre></div><ol start="11"> |
| <li>创建 Consumer</li> |
| </ol> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#268bd2">class</span> <span style="color:#268bd2">StreamConsumer</span> { |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#268bd2">static</span> <span style="color:#dc322f">void</span> <span style="color:#268bd2">main</span>(String<span style="color:#719e07">[]</span> args) <span style="color:#268bd2">throws</span> InterruptedException, IOException { |
| </span></span><span style="display:flex;"><span> ReferenceConfig<span style="color:#719e07">&lt;</span>IStreamGreeter<span style="color:#719e07">&gt;</span> ref <span style="color:#719e07">=</span> <span style="color:#719e07">new</span> ReferenceConfig<span style="color:#719e07">&lt;&gt;</span>(); |
| </span></span><span style="display:flex;"><span> ref.setInterface(IStreamGreeter.class); |
| </span></span><span style="display:flex;"><span> ref.setCheck(<span style="color:#cb4b16">false</span>); |
| </span></span><span style="display:flex;"><span> ref.setProtocol(CommonConstants.TRIPLE); |
| </span></span><span style="display:flex;"><span> ref.setLazy(<span style="color:#cb4b16">true</span>); |
| </span></span><span style="display:flex;"><span> ref.setTimeout(100000); |
| </span></span><span style="display:flex;"><span> ref.setApplication(<span style="color:#719e07">new</span> ApplicationConfig(<span style="color:#2aa198">&#34;stream-consumer&#34;</span>)); |
| </span></span><span style="display:flex;"><span> ref.setRegistry(<span style="color:#719e07">new</span> RegistryConfig(<span style="color:#2aa198">&#34;zookeeper://mse-6e9fda00-p.zk.mse.aliyuncs.com:2181&#34;</span>)); |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">final</span> IStreamGreeter iStreamGreeter <span style="color:#719e07">=</span> ref.get(); |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> System.out.println(<span style="color:#2aa198">&#34;dubbo ref started&#34;</span>); |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">try</span> { |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> StreamObserver<span style="color:#719e07">&lt;</span>HelloRequest<span style="color:#719e07">&gt;</span> streamObserver <span style="color:#719e07">=</span> iStreamGreeter.sayHello(<span style="color:#719e07">new</span> StreamObserver<span style="color:#719e07">&lt;</span>HelloReply<span style="color:#719e07">&gt;</span>() { |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">@Override</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#dc322f">void</span> <span style="color:#268bd2">onNext</span>(HelloReply reply) { |
| </span></span><span style="display:flex;"><span> System.out.println(<span style="color:#2aa198">&#34;onNext&#34;</span>); |
| </span></span><span style="display:flex;"><span> System.out.println(reply.getMessage()); |
| </span></span><span style="display:flex;"><span> } |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">@Override</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#dc322f">void</span> <span style="color:#268bd2">onError</span>(Throwable throwable) { |
| </span></span><span style="display:flex;"><span> System.out.println(<span style="color:#2aa198">&#34;onError:&#34;</span> <span style="color:#719e07">+</span> throwable.getMessage()); |
| </span></span><span style="display:flex;"><span> } |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">@Override</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#dc322f">void</span> <span style="color:#268bd2">onCompleted</span>() { |
| </span></span><span style="display:flex;"><span> System.out.println(<span style="color:#2aa198">&#34;onCompleted&#34;</span>); |
| </span></span><span style="display:flex;"><span> } |
| </span></span><span style="display:flex;"><span> }); |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> streamObserver.onNext(HelloRequest.newBuilder() |
| </span></span><span style="display:flex;"><span> .setName(<span style="color:#2aa198">&#34;tony&#34;</span>) |
| </span></span><span style="display:flex;"><span> .build()); |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> streamObserver.onNext(HelloRequest.newBuilder() |
| </span></span><span style="display:flex;"><span> .setName(<span style="color:#2aa198">&#34;nick&#34;</span>) |
| </span></span><span style="display:flex;"><span> .build()); |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> streamObserver.onCompleted(); |
| </span></span><span style="display:flex;"><span> } <span style="color:#719e07">catch</span> (Throwable t) { |
| </span></span><span style="display:flex;"><span> t.printStackTrace(); |
| </span></span><span style="display:flex;"><span> } |
| </span></span><span style="display:flex;"><span> System.in.read(); |
| </span></span><span style="display:flex;"><span> } |
| </span></span><span style="display:flex;"><span> } |
| </span></span></code></pre></div><ol start="12"> |
| <li>运行 Provider 和 Consumer ,可以看到请求正常返回了</li> |
| </ol> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#719e07">&gt;</span> onNext\ |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">&gt;</span> receive name:tony\ |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">&gt;</span> onNext\ |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">&gt;</span> receive name:nick\ |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">&gt;</span> onCompleted |
| </span></span></code></pre></div><h3 id="其他序列化方式">其他序列化方式</h3> |
| <p>省略上文中的 1-3 步,指定 Provider 和 Consumer 使用的协议即可完成协议升级。</p> |
| <blockquote> |
| <p>本文的示例可以在 <a href="https://github.com/apache/dubbo-samples/tree/master/3-extensions/protocol/dubbo-samples-triple">triple-samples</a> 找到</p> |
| </blockquote></description></item><item><title>Overview: Dubbo2 协议迁移</title><link>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/triple/migration/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/triple/migration/</guid><description> |
| <h2 id="迁移流程说明">迁移流程说明</h2> |
| <p>Dubbo2 的用户使用 dubbo 协议 + 自定义序列化,如 hessian2 完成远程调用。</p> |
| <p>而 Grpc 的默认仅支持 Protobuf 序列化,对于 Java 语言中的多参数以及方法重载也无法支持。</p> |
| <p>Dubbo3 的之初就有一条目标是完美兼容 Dubbo2,所以为了 Dubbo2 能够平滑升级, Dubbo 框架侧做了很多工作来保证升级的无感,目前默认的序列化和 Dubbo2 保持一致为 <code>hessian2</code>。</p> |
| <p>所以,如果决定要升级到 Dubbo3 的 <code>Triple</code> 协议,只需要修改配置中的协议名称为 <code>tri</code> (注意: 不是 triple )即可。</p> |
| <p>接下来我们以一个使用 Dubbo2 协议的<a href="https://github.com/apache/dubbo-samples/tree/master/3-extensions/protocol/dubbo-samples-triple/src/main/java/org/apache/dubbo/sample/tri/migration">工程</a>来举例,如何一步一步安全的升级。</p> |
| <ol> |
| <li>仅使用 <code>dubbo</code> 协议启动 <code>provider</code> 和 <code>consumer</code>,并完成调用。</li> |
| <li>仅使用 <code>tri</code> 协议启动 <code>provider</code> 和 <code>consumer</code>,并完成调用。</li> |
| <li>使用 <code>dubbo</code> 协议和 <code>tri</code> 协议 启动 <code>provider</code>,以 <code>dubbo</code> 协议启动 <code>consumer</code>,并完成调用。</li> |
| </ol> |
| <h3 id="定义服务">定义服务</h3> |
| <ol> |
| <li>定义接口</li> |
| </ol> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#268bd2">public</span> <span style="color:#268bd2">interface</span> <span style="color:#268bd2">IWrapperGreeter</span> { |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">//... </span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">/** |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * 这是一个普通接口,没有使用 pb 序列化 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> */</span> |
| </span></span><span style="display:flex;"><span> String <span style="color:#268bd2">sayHello</span>(String request); |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span>} |
| </span></span></code></pre></div><ol start="2"> |
| <li>实现类示例</li> |
| </ol> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#268bd2">public</span> <span style="color:#268bd2">class</span> <span style="color:#268bd2">IGreeter2Impl</span> <span style="color:#268bd2">implements</span> IWrapperGreeter { |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">@Override</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> String <span style="color:#268bd2">sayHello</span>(String request) { |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">return</span> <span style="color:#2aa198">&#34;hello,&#34;</span> <span style="color:#719e07">+</span> request; |
| </span></span><span style="display:flex;"><span> } |
| </span></span><span style="display:flex;"><span>} |
| </span></span></code></pre></div><h3 id="仅使用-dubbo-协议">仅使用 dubbo 协议</h3> |
| <p>为保证兼容性,我们先将部分 provider 升级到 <code>dubbo3</code> 版本并使用 <code>dubbo</code> 协议。</p> |
| <p>使用 <code>dubbo</code> 协议启动一个 <a href="https://github.com/apache/dubbo-samples/tree/master/3-extensions/protocol/dubbo-samples-triple/src/main/java/org/apache/dubbo/sample/tri/migration/ApiMigrationDubboProvider.java"><code>Provider</code></a> 和 <a href="https://github.com/apache/dubbo-samples/tree/master/3-extensions/protocol/dubbo-samples-triple/src/main/java/org/apache/dubbo/sample/tri/migration/ApiMigrationDubboConsumer.java"><code>Consumer</code></a> 完成调用。</p> |
| <div class="alert alert-info" role="alert"> |
| <h4 class="alert-heading">输出结果</h4> |
| <img src="https://dubbo.apache.org/imgs/v3/migration/tri/dubbo3-tri-migration-dubbo-dubbo-result.png" alt="result"> |
| </div> |
| <h3 id="仅使用-triple-协议">仅使用 triple 协议</h3> |
| <p>当所有的 consumer 都升级至支持 <code>Triple</code> 协议的版本后,provider 可切换至仅使用 <code>Triple</code> 协议启动</p> |
| <p>结构如图所示: |
| <img src="https://dubbo.apache.org/imgs/v3/migration/tri/migrate-only-tri-strust.png" alt="strust"></p> |
| <p><a href="https://github.com/apache/dubbo-samples/tree/master/3-extensions/protocol/dubbo-samples-triple/src/main/java/org/apache/dubbo/sample/tri/migration/ApiMigrationTriProvider.java">Provider</a> |
| 和 <a href="https://github.com/apache/dubbo-samples/tree/master/3-extensions/protocol/dubbo-samples-triple/src/main/java/org/apache/dubbo/sample/tri/migration/ApiMigrationTriConsumer.java">Consumer</a> 完成调用。</p> |
| <div class="alert alert-info" role="alert"> |
| <h4 class="alert-heading">输出结果</h4> |
| <img src="https://dubbo.apache.org/imgs/v3/migration/tri/dubbo3-tri-migration-tri-tri-result.png" alt="result"> |
| </div> |
| <h3 id="同时使用-dubbo-和-triple-协议">同时使用 dubbo 和 triple 协议</h3> |
| <p>对于线上服务的升级,不可能一蹴而就同时完成 provider 和 consumer 升级, 需要按步操作,</p> |
| <p><strong>第一步:保证业务稳定。</strong></p> |
| <p><strong>第二步:provider 提供双协议的方式同时支持 dubbo + tri 两种协议的客户端。</strong></p> |
| <p>结构如图所示: |
| <img src="https://dubbo.apache.org/imgs/v3/migration/tri/migrate-dubbo-tri-strust.png" alt="strust"></p> |
| <blockquote> |
| <p>按照推荐升级步骤,provider 已经支持了 tri 协议,所以 dubbo3 的 consumer 可以直接使用 tri 协议</p> |
| </blockquote> |
| <p>使用 <code>dubbo</code> 协议和 <code>triple</code> 协议启动<a href="https://github.com/apache/dubbo-samples/tree/master/3-extensions/protocol/dubbo-samples-triple/src/main/java/org/apache/dubbo/sample/tri/migration/ApiMigrationBothProvider.java"><code>Provider</code></a>和<a href="https://github.com/apache/dubbo-samples/tree/master/3-extensions/protocol/dubbo-samples-triple/src/main/java/org/apache/dubbo/sample/tri/migration/ApiMigrationBothConsumer.java"><code>Consumer</code></a> 完成调用。</p> |
| <div class="alert alert-info" role="alert"> |
| <h4 class="alert-heading">输出结果</h4> |
| <img src="https://dubbo.apache.org/imgs/v3/migration/tri/dubbo3-tri-migration-both-dubbo-tri-result.png" alt="result"> |
| </div></description></item><item><title>Overview: Streaming 通信</title><link>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/triple/streaming/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/triple/streaming/</guid><description> |
| <h2 id="流实现原理">流实现原理</h2> |
| <p><code>Triple</code>协议的流模式</p> |
| <ul> |
| <li> |
| <p>从协议层来说,<code>Triple</code> 是建立在 <code>HTTP2</code> 基础上的,所以直接拥有所有 <code>HTTP2</code> 的能力,故拥有了分 <code>stream</code> 和全双工的能力。</p> |
| </li> |
| <li> |
| <p>框架层来说,<code>StreamObserver</code> 作为流的接口提供给用户,用于入参和出参提供流式处理。框架在收发 stream data 时进行相应的接口调用, 从而保证流的生命周期完整。</p> |
| </li> |
| </ul> |
| <h2 id="流使用方式">流使用方式</h2> |
| <h3 id="stream-流">Stream 流</h3> |
| <p>Stream 是 Dubbo3 新提供的一种调用类型,在以下场景时建议使用流的方式:</p> |
| <ul> |
| <li>接口需要发送大量数据,这些数据无法被放在一个 RPC 的请求或响应中,需要分批发送,但应用层如果按照传统的多次 RPC 方式无法解决顺序和性能的问题,如果需要保证有序,则只能串行发送</li> |
| <li>流式场景,数据需要按照发送顺序处理, 数据本身是没有确定边界的</li> |
| <li>推送类场景,多个消息在同一个调用的上下文中被发送和处理</li> |
| </ul> |
| <p>Stream 分为以下三种:</p> |
| <ul> |
| <li>SERVER_STREAM(服务端流) |
| <img src="https://dubbo.apache.org/imgs/v3/migration/tri/migrate-server-stream.png" alt="SERVER_STREAM"></li> |
| <li>CLIENT_STREAM(客户端流) |
| <img src="https://dubbo.apache.org/imgs/v3/migration/tri/migrate-client-stream.png" alt="CLIENT_STREAM"></li> |
| <li>BIDIRECTIONAL_STREAM(双向流) |
| <img src="https://dubbo.apache.org/imgs/v3/migration/tri/migrate-bi-stream.png" alt="BIDIRECTIONAL_STREAM"></li> |
| </ul> |
| <p>由于 <code>java</code> 语言的限制,BIDIRECTIONAL_STREAM 和 CLIENT_STREAM 的实现是一样的。</p> |
| <p>在 Dubbo3 中,流式接口以 <code>SteamObserver</code> 声明和使用,用户可以通过使用和实现这个接口来发送和处理流的数据、异常和结束。</p> |
| <p>对于 Dubbo2 用户来说,可能会对StreamObserver感到陌生,这是Dubbo3定义的一种流类型,Dubbo2 中并不存在 Stream 的类型,所以对于迁移场景没有任何影响。</p> |
| <div class="alert alert-primary" role="alert"> |
| <h4 class="alert-heading">流的语义保证</h4> |
| <ul> |
| <li>提供消息边界,可以方便地对消息单独处理</li> |
| <li>严格有序,发送端的顺序和接收端顺序一致</li> |
| <li>全双工,发送不需要等待</li> |
| <li>支持取消和超时</li> |
| </ul> |
| </div> |
| <h3 id="protobuf-序列化的流">Protobuf 序列化的流</h3> |
| <p>对于 <code>Protobuf</code> 序列化方式,推荐编写 <code>IDL</code> 使用 <code>compiler</code> 插件进行编译生成。生成的代码大致如下:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#268bd2">public</span> <span style="color:#268bd2">interface</span> <span style="color:#268bd2">PbGreeter</span> { |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">static</span> <span style="color:#268bd2">final</span> String JAVA_SERVICE_NAME <span style="color:#719e07">=</span> <span style="color:#2aa198">&#34;org.apache.dubbo.sample.tri.PbGreeter&#34;</span>; |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">static</span> <span style="color:#268bd2">final</span> String SERVICE_NAME <span style="color:#719e07">=</span> <span style="color:#2aa198">&#34;org.apache.dubbo.sample.tri.PbGreeter&#34;</span>; |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">static</span> <span style="color:#268bd2">final</span> <span style="color:#dc322f">boolean</span> inited <span style="color:#719e07">=</span> PbGreeterDubbo.init(); |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">//...</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#dc322f">void</span> <span style="color:#268bd2">greetServerStream</span>(org.apache.dubbo.sample.tri.GreeterRequest request, org.apache.dubbo.common.stream.StreamObserver<span style="color:#719e07">&lt;</span>org.apache.dubbo.sample.tri.GreeterReply<span style="color:#719e07">&gt;</span> responseObserver); |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> org.apache.dubbo.common.stream.StreamObserver<span style="color:#719e07">&lt;</span>org.apache.dubbo.sample.tri.GreeterRequest<span style="color:#719e07">&gt;</span> <span style="color:#268bd2">greetStream</span>(org.apache.dubbo.common.stream.StreamObserver<span style="color:#719e07">&lt;</span>org.apache.dubbo.sample.tri.GreeterReply<span style="color:#719e07">&gt;</span> responseObserver); |
| </span></span><span style="display:flex;"><span>} |
| </span></span></code></pre></div><h2 id="非-protobuf-序列化的流">非 Protobuf 序列化的流</h2> |
| <h3 id="api">api</h3> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#268bd2">public</span> <span style="color:#268bd2">interface</span> <span style="color:#268bd2">IWrapperGreeter</span> { |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> StreamObserver<span style="color:#719e07">&lt;</span>String<span style="color:#719e07">&gt;</span> <span style="color:#268bd2">sayHelloStream</span>(StreamObserver<span style="color:#719e07">&lt;</span>String<span style="color:#719e07">&gt;</span> response); |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#dc322f">void</span> <span style="color:#268bd2">sayHelloServerStream</span>(String request, StreamObserver<span style="color:#719e07">&lt;</span>String<span style="color:#719e07">&gt;</span> response); |
| </span></span><span style="display:flex;"><span>} |
| </span></span></code></pre></div><blockquote> |
| <p>Stream 方法的方法入参和返回值是严格约定的,为防止写错而导致问题,Dubbo3 框架侧做了对参数的检查, 如果出错则会抛出异常。 |
| 对于 <code>双向流(BIDIRECTIONAL_STREAM)</code>, 需要注意参数中的 <code>StreamObserver</code> 是响应流,返回参数中的 <code>StreamObserver</code> 为请求流。</p> |
| </blockquote> |
| <h3 id="实现类">实现类</h3> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#268bd2">public</span> <span style="color:#268bd2">class</span> <span style="color:#268bd2">WrapGreeterImpl</span> <span style="color:#268bd2">implements</span> WrapGreeter { |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">//...</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">@Override</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> StreamObserver<span style="color:#719e07">&lt;</span>String<span style="color:#719e07">&gt;</span> <span style="color:#268bd2">sayHelloStream</span>(StreamObserver<span style="color:#719e07">&lt;</span>String<span style="color:#719e07">&gt;</span> response) { |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">return</span> <span style="color:#719e07">new</span> StreamObserver<span style="color:#719e07">&lt;</span>String<span style="color:#719e07">&gt;</span>() { |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">@Override</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#dc322f">void</span> <span style="color:#268bd2">onNext</span>(String data) { |
| </span></span><span style="display:flex;"><span> System.out.println(data); |
| </span></span><span style="display:flex;"><span> response.onNext(<span style="color:#2aa198">&#34;hello,&#34;</span><span style="color:#719e07">+</span>data); |
| </span></span><span style="display:flex;"><span> } |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">@Override</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#dc322f">void</span> <span style="color:#268bd2">onError</span>(Throwable throwable) { |
| </span></span><span style="display:flex;"><span> throwable.printStackTrace(); |
| </span></span><span style="display:flex;"><span> } |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">@Override</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#dc322f">void</span> <span style="color:#268bd2">onCompleted</span>() { |
| </span></span><span style="display:flex;"><span> System.out.println(<span style="color:#2aa198">&#34;onCompleted&#34;</span>); |
| </span></span><span style="display:flex;"><span> response.onCompleted(); |
| </span></span><span style="display:flex;"><span> } |
| </span></span><span style="display:flex;"><span> }; |
| </span></span><span style="display:flex;"><span> } |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">@Override</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#dc322f">void</span> <span style="color:#268bd2">sayHelloServerStream</span>(String request, StreamObserver<span style="color:#719e07">&lt;</span>String<span style="color:#719e07">&gt;</span> response) { |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">for</span> (<span style="color:#dc322f">int</span> i <span style="color:#719e07">=</span> 0; i <span style="color:#719e07">&lt;</span> 10; i<span style="color:#719e07">++</span>) { |
| </span></span><span style="display:flex;"><span> response.onNext(<span style="color:#2aa198">&#34;hello,&#34;</span> <span style="color:#719e07">+</span> request); |
| </span></span><span style="display:flex;"><span> } |
| </span></span><span style="display:flex;"><span> response.onCompleted(); |
| </span></span><span style="display:flex;"><span> } |
| </span></span><span style="display:flex;"><span>} |
| </span></span></code></pre></div><h3 id="调用方式">调用方式</h3> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span>delegate.sayHelloServerStream(<span style="color:#2aa198">&#34;server stream&#34;</span>, <span style="color:#719e07">new</span> StreamObserver<span style="color:#719e07">&lt;</span>String<span style="color:#719e07">&gt;</span>() { |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">@Override</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#dc322f">void</span> <span style="color:#268bd2">onNext</span>(String data) { |
| </span></span><span style="display:flex;"><span> System.out.println(data); |
| </span></span><span style="display:flex;"><span> } |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">@Override</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#dc322f">void</span> <span style="color:#268bd2">onError</span>(Throwable throwable) { |
| </span></span><span style="display:flex;"><span> throwable.printStackTrace(); |
| </span></span><span style="display:flex;"><span> } |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">@Override</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#dc322f">void</span> <span style="color:#268bd2">onCompleted</span>() { |
| </span></span><span style="display:flex;"><span> System.out.println(<span style="color:#2aa198">&#34;onCompleted&#34;</span>); |
| </span></span><span style="display:flex;"><span> } |
| </span></span><span style="display:flex;"><span>}); |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span>StreamObserver<span style="color:#719e07">&lt;</span>String<span style="color:#719e07">&gt;</span> request <span style="color:#719e07">=</span> delegate.sayHelloStream(<span style="color:#719e07">new</span> StreamObserver<span style="color:#719e07">&lt;</span>String<span style="color:#719e07">&gt;</span>() { |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">@Override</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#dc322f">void</span> <span style="color:#268bd2">onNext</span>(String data) { |
| </span></span><span style="display:flex;"><span> System.out.println(data); |
| </span></span><span style="display:flex;"><span> } |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">@Override</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#dc322f">void</span> <span style="color:#268bd2">onError</span>(Throwable throwable) { |
| </span></span><span style="display:flex;"><span> throwable.printStackTrace(); |
| </span></span><span style="display:flex;"><span> } |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">@Override</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#dc322f">void</span> <span style="color:#268bd2">onCompleted</span>() { |
| </span></span><span style="display:flex;"><span> System.out.println(<span style="color:#2aa198">&#34;onCompleted&#34;</span>); |
| </span></span><span style="display:flex;"><span> } |
| </span></span><span style="display:flex;"><span>}); |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">for</span> (<span style="color:#dc322f">int</span> i <span style="color:#719e07">=</span> 0; i <span style="color:#719e07">&lt;</span> n; i<span style="color:#719e07">++</span>) { |
| </span></span><span style="display:flex;"><span> request.onNext(<span style="color:#2aa198">&#34;stream request&#34;</span> <span style="color:#719e07">+</span> i); |
| </span></span><span style="display:flex;"><span>} |
| </span></span><span style="display:flex;"><span>request.onCompleted(); |
| </span></span></code></pre></div></description></item></channel></rss> |