真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

怎么使用Dubbo開發(fā)gRPC服務(wù)

這篇文章主要講解了“怎么使用Dubbo開發(fā)gRPC服務(wù)”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“怎么使用Dubbo開發(fā)gRPC服務(wù)”吧!

創(chuàng)新互聯(lián)是一家專業(yè)提供臨潁企業(yè)網(wǎng)站建設(shè),專注與成都網(wǎng)站建設(shè)、網(wǎng)站建設(shè)成都h5網(wǎng)站建設(shè)、小程序制作等業(yè)務(wù)。10年已為臨潁眾多企業(yè)、政府機(jī)構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專業(yè)網(wǎng)站建設(shè)公司優(yōu)惠進(jìn)行中。

基本介紹

Dubbo 協(xié)議

從協(xié)議層面展開,以下是當(dāng)前 2.7 版本支持的 Dubbo 協(xié)議

眾所周知,Dubbo 協(xié)議是直接定義在 TCP 傳輸層協(xié)議之上,由于 TCP 高可靠全雙工的特點(diǎn),為 Dubbo 協(xié)議的定義提供了最大的靈活性,但同時(shí)也正是因?yàn)檫@樣的靈活性,RPC 協(xié)議普遍都是定制化的私有協(xié)議,Dubbo 同樣也面臨這個(gè)問題。在這里我們著重講一下 Dubbo 在協(xié)議通用性方面值得改進(jìn)的地方,關(guān)于協(xié)議詳細(xì)解析請(qǐng)參見官網(wǎng)博客

  • Dubbo 協(xié)議體 Body 中有一個(gè)可擴(kuò)展的 attachments 部分,這給 RPC 方法之外額外傳遞附加屬性提供了可能,是一個(gè)很好的設(shè)計(jì)。但是類似的 Header 部分,卻缺少類似的可擴(kuò)展 attachments,這點(diǎn)可參考 HTTP 定義的 Ascii Header 設(shè)計(jì),將 Body Attachments 和 Header Attachments 做職責(zé)劃分。

  • Body 協(xié)議體中的一些 RPC 請(qǐng)求定位符如 Service Name、Method Name、Version 等,可以提到 Header 中,和具體的序列化協(xié)議解耦,以更好的被網(wǎng)絡(luò)基礎(chǔ)設(shè)施識(shí)別或用于流量管控。

  • 擴(kuò)展性不夠好,欠缺協(xié)議升級(jí)方面的設(shè)計(jì),如 Header 頭中沒有預(yù)留的狀態(tài)標(biāo)識(shí)位,或者像 HTTP 有專為協(xié)議升級(jí)或協(xié)商設(shè)計(jì)的特殊 packet。

  • 在 Java 版本的代碼實(shí)現(xiàn)上,不夠精簡(jiǎn)和通用。如在鏈路傳輸中,存在一些語言綁定的內(nèi)容;消息體中存在冗余內(nèi)容,如 Service Name 在 Body 和 Attachments 中都存在。

HTTP/1

相比于直接構(gòu)建與 TPC 傳輸層的私有 RPC 協(xié)議,構(gòu)建于 HTTP 之上的遠(yuǎn)程調(diào)用解決方案會(huì)有更好的通用性,如WebServices 或 REST 架構(gòu),使用 HTTP + JSON 可以說是一個(gè)事實(shí)標(biāo)準(zhǔn)的解決方案。

之所有選擇構(gòu)建在 HTTP 之上,我認(rèn)為有兩個(gè)最大的優(yōu)勢(shì):

  1. HTTP 的語義和可擴(kuò)展性能很好的滿足 RPC 調(diào)用需求。

  2. 通用性,HTTP 協(xié)議幾乎被網(wǎng)絡(luò)上的所有設(shè)備所支持,具有很好的協(xié)議穿透性。

具體來說,HTTP/1 的優(yōu)勢(shì)和限制是:

  • 典型的 Request – Response 模型,一個(gè)鏈路上一次只能有一個(gè)等待的 Request 請(qǐng)求

  • HTTP/1 支持 Keep-Alive 鏈接,避免了鏈接重復(fù)創(chuàng)建開銷

  • Human Readable Headers,使用更通用、更易于人類閱讀的頭部傳輸格式

  • 無直接 Server Push 支持,需要使用 Polling Long-Polling 等變通模式

HTTP/2

HTTP/2 保留了 HTTP/1 的所有語義,在保持兼容的同時(shí),在通信模型和傳輸效率上做了很大的改進(jìn)。

  • 支持單條鏈路上的 Multiplexing,相比于 Request - Response 獨(dú)占鏈路,基于 Frame 實(shí)現(xiàn)更高效利用鏈路

  • Request - Stream 語義,原生支持 Server Push 和 Stream 數(shù)據(jù)傳輸

  • Flow Control,單條 Stream 粒度的和整個(gè)鏈路粒度的流量控制

  • 頭部壓縮 HPACK

  • Binary Frame

  • 原生 TLS 支持

gRPC

上面提到了在 HTTP 及 TCP 協(xié)議之上構(gòu)建 RPC 協(xié)議各自的優(yōu)缺點(diǎn),相比于 Dubbo 構(gòu)建于 TPC 傳輸層之上,Google 選擇將 gRPC 直接定義在 HTTP/2 協(xié)議之上,關(guān)于 gRPC 的 基本介紹和 設(shè)計(jì)愿景請(qǐng)參考以上兩篇文章,我這里僅摘取 設(shè)計(jì)愿景 中幾個(gè)能反映 gRPC 設(shè)計(jì)目的特性來做簡(jiǎn)單說明。

  • Coverage & Simplicity,協(xié)議設(shè)計(jì)和框架實(shí)現(xiàn)要足夠通用和簡(jiǎn)單,能運(yùn)行在任何設(shè)備之上,甚至一些資源首先的如 IoT、Mobile 等設(shè)備。

  • Interoperability & Reach,要構(gòu)建在更通用的協(xié)議之上,協(xié)議本身要能被網(wǎng)絡(luò)上幾乎所有的基礎(chǔ)設(shè)施所支持。

  • General Purpose & Performant,要在場(chǎng)景和性能間做好平衡,首先協(xié)議本身要是適用于各種場(chǎng)景的,同時(shí)也要盡量有高的性能。

  • Payload Agnostic,協(xié)議上傳輸?shù)呢?fù)載要保持語言和平臺(tái)中立。

  • Streaming,要支持 Request - Response、Request - Stream、Bi-Steam 等通信模型。

  • Flow Control,協(xié)議自身具備流量感知和限制的能力。

  • Metadata Exchange,在 RPC 服務(wù)定義之外,提供額外附加數(shù)據(jù)傳輸?shù)哪芰Α?/p>

總的來說,在這樣的設(shè)計(jì)理念指導(dǎo)下,gRPC 最終被設(shè)計(jì)為一個(gè)跨語言、跨平臺(tái)的、通用的、高性能的、基于 HTTP/2 的 RPC 協(xié)議和框架。

Protobuf

Protocol buffers (Protobuf) 是 Google 推出的一個(gè)跨平臺(tái)、語言中立的結(jié)構(gòu)化數(shù)據(jù)描述和序列化的產(chǎn)品,它定義了一套結(jié)構(gòu)化數(shù)據(jù)定義的協(xié)議,同時(shí)也提供了相應(yīng)的 Compiler 工具,用來將語言中立的描述轉(zhuǎn)化為相應(yīng)語言的具體描述。

它的一些特性包括:

  • 跨語言 跨平臺(tái),語言中立的數(shù)據(jù)描述格式,默認(rèn)提供了生成多種語言的 Compiler 工具。

  • 安全性,由于反序列化的范圍和輸出內(nèi)容格式都是 Compiler 在編譯時(shí)預(yù)生成的,因此繞過了類似 Java Deserialization Vulnarability 的問題。

  • 二進(jìn)制 高性能

  • 強(qiáng)類型

  • 字段變更向后兼容

message Person {
      required string name = 1;
      required int32 id = 2;
      optional string email = 3;
      enum PhoneType {
        MOBILE = 0;
        HOME = 1;
        WORK = 2;
      }
      message PhoneNumber {
        required string number = 1;
        optional PhoneType type = 2 [default = HOME];
      }
      repeated PhoneNumber phone = 4;
    }

除了結(jié)構(gòu)化數(shù)據(jù)描述之外,Protobuf 還支持定義 RPC 服務(wù),它允許我們定義一個(gè) .proto 的服務(wù)描述文件,進(jìn)而利用 Protobuf Compiler 工具生成特定語言和 RPC 框架的接口和 stub。后續(xù)將要具體講到的 gRPC + Protobuf、Dubbo-gRPC + Protobuf 以及 Dubbo + Protobuf 都是通過定制 Compiler 類實(shí)現(xiàn)的。

service SearchService {
    rpc Search (SearchRequest) returns (SearchResponse);
}

Dubbo 所做的支持

跨語言的服務(wù)開發(fā)涉及到多個(gè)方面,從服務(wù)定義、RPC 協(xié)議到序列化協(xié)議都要做到語言中立,同時(shí)還針對(duì)每種語言有對(duì)應(yīng)的 SDK 實(shí)現(xiàn)。雖然得益于社區(qū)的貢獻(xiàn),現(xiàn)在 Dubbo 在多語言 SDK 實(shí)現(xiàn)上逐步有了起色,已經(jīng)提供了包括 Java, Go, PHP, C#, Python, NodeJs, C 等版本的客戶端或全量實(shí)現(xiàn)版本,但在以上提到的跨語言友好型方面,以上三點(diǎn)還是有很多可改進(jìn)之處。

  • 協(xié)議,上面我們已經(jīng)分析過 Dubbo 協(xié)議既有的缺點(diǎn),如果能在 HTTP/2 之上構(gòu)建應(yīng)用層協(xié)議,則無疑能避免這些弊端,同時(shí)最大可能的提高協(xié)議的穿透性,避免網(wǎng)關(guān)等協(xié)議轉(zhuǎn)換組件的存在,更有利于鏈路上的流量管控??紤]到 gRPC 是構(gòu)建在 HTTP/2 之上,并且已經(jīng)是云原生領(lǐng)域推薦的通信協(xié)議,Dubbo 在第一階段選擇了直接支持 gRPC 協(xié)議作為當(dāng)前的 HTTP/2 解決方案。我們也知道 gRPC 框架自身的弊端在于易用性不足以及服務(wù)治理能力欠缺(這也是目前絕大多數(shù)廠商不會(huì)直接裸用 gRPC 框架的原因),通過將其集成進(jìn) Dubbo 框架,用戶可以方便的使用 Dubbo 編程模型 + Dubbo 服務(wù)治理 + gRPC 協(xié)議通信的組合。

  • 服務(wù)定義,當(dāng)前 Dubbo 的服務(wù)定義和具體的編程語言綁定,沒有提供一種語言中立的服務(wù)描述格式,比如 Java 就是定義 Interface 接口,到了其他語言又得重新以另外的格式定義一遍。因此 Dubbo 通過支持 Protobuf 實(shí)現(xiàn)了語言中立的服務(wù)定義。

  • 序列化,Dubbo 當(dāng)前支持的序列化包括 Json、Hessian2、Kryo、FST、Java 等,而這其中支持跨語言的只有 Json、Hessian2,通用的 Json 有固有的性能問題,而 Hessian2 無論在效率還是多語言 SDK 方面都有所欠缺。為此,Dubbo 通過支持 Protobuf 序列化來提供更高效、易用的跨語言序列化方案。

示例

示例 1,使用 Dubbo 開發(fā) gRPC 服務(wù)

gRPC 是 Google 開源的構(gòu)建在 HTTP/2 之上的一個(gè) PRC 通信協(xié)議。Dubbo 依賴其靈活的協(xié)議擴(kuò)展機(jī)制,增加了對(duì) gRPC (HTTP/2) 協(xié)議的支持。

目前的支持限定在 Dubbo Java 語言版本,后續(xù) Go 語言或其他語言版本將會(huì)以類似方式提供支持。下面,通過一個(gè)簡(jiǎn)單的 示例來演示如何在 Dubbo 中使用 gRPC 協(xié)議通信。

1. 定義服務(wù) IDL

首先,通過標(biāo)準(zhǔn)的 Protobuf 協(xié)議定義服務(wù)如下:

syntax = "proto3";
    
    option java_multiple_files = true;
    option java_package = "io.grpc.examples.helloworld";
    option java_outer_classname = "HelloWorldProto";
    option objc_class_prefix = "HLW";
    
    package helloworld;
    
    // The greeting service definition.
    service Greeter {
      // Sends a greeting
      rpc SayHello (HelloRequest) returns (HelloReply) {}
    }
    
    // The request message containing the user's name.
    message HelloRequest {
      string name = 1;
    }
    
    // The response message containing the greetings
    message HelloReply {
      string message = 1;
    }

在此,我們定義了一個(gè)只有一個(gè)方法 sayHello 的 Greeter 服務(wù),同時(shí)定義了方法的入?yún)⒑统鰠ⅲ?/p>

2. Protobuf Compiler 生成 Stub

  1. 定義 Maven Protobuf Compiler 插件工具。這里我們擴(kuò)展了 Protobuf 的 Compiler 工具,以用來生成 Dubbo 特有的 RPC stub,此當(dāng)前以 Maven 插件的形式發(fā)布。


  org.xolstice.maven.plugins
  protobuf-maven-plugin
  0.5.1
  
    com.google.protobuf:protoc:3.7.1:exe:${os.detected.classifier}    
    
    dubbo-grpc-java
    org.apache.dubbo:protoc-gen-dubbo-java:1.19.0-SNAPSHOT:exe:${os.detected.classifier}
    build/generated/source/proto/main/java
    false
    grpc
  
  
    
      
        compile
        compile-custom
      
    
  

其中,

pluginArtifact 指定了 Dubbo 定制版本的 Java Protobuf Compiler 插件,通過這個(gè)插件來在編譯過程中生成 Dubbo 定制版本的 gRPC stub。

org.apache.dubbo:protoc-gen-dubbo-java:1.19.0-SNAPSHOT:exe:${os.detected.classifier}

由于 protoc-gen-dubbo-java 支持 gRPC 和 Dubbo 兩種協(xié)議,可生成的 stub 類型,默認(rèn)值是 gRPC,關(guān)于 dubbo 協(xié)議的使用可參見 使用 Protobuf 開發(fā) Dubbo 服務(wù)。

grpc

2. 生成 Java Bean 和 Dubbo-gRPC stub

# 運(yùn)行以下 maven 命令
$ mvn clean compile

生成的 Stub 和消息類 如下:

重點(diǎn)關(guān)注 GreeterGrpc ,包含了所有 gRPC 標(biāo)準(zhǔn)的 stub 類/方法,同時(shí)增加了 Dubbo 特定的接口,之后 Provider 端的服務(wù)暴露和 Consumer 端的服務(wù)調(diào)用都將依賴這個(gè)接口。

/**
* Code generated for Dubbo
*/
public interface IGreeter {
  default public io.grpc.examples.helloworld.HelloReply     sayHello(io.grpc.examples.helloworld.HelloRequest request) {
    throw new UnsupportedOperationException("No need to override this method, extend XxxImplBase and override all methods it allows.");
  }
  default public com.google.common.util.concurrent.ListenableFuture sayHelloAsync(
    io.grpc.examples.helloworld.HelloRequest request) {
    throw new UnsupportedOperationException("No need to override this method, extend XxxImplBase and override all methods it allows.");
  }
  public void sayHello(io.grpc.examples.helloworld.HelloRequest request,
                       io.grpc.stub.StreamObserver responseObserver);
}

3. 業(yè)務(wù)邏輯開發(fā)

繼承 GreeterGrpc.GreeterImplBase (來自第 2 步),編寫業(yè)務(wù)邏輯,這點(diǎn)和原生 gRPC 是一致的。

package org.apache.dubbo.samples.basic.impl;
import io.grpc.examples.helloworld.GreeterGrpc;
import io.grpc.examples.helloworld.HelloReply;
import io.grpc.examples.helloworld.HelloRequest;
import io.grpc.stub.StreamObserver;
public class GrpcGreeterImpl extends GreeterGrpc.GreeterImplBase {
  @Override
  public void sayHello(HelloRequest request, StreamObserver responseObserver)         {
    System.out.println("Received request from client.");
    System.out.println("Executing thread is " + Thread.currentThread().getName());
    HelloReply reply = HelloReply.newBuilder()
      .setMessage("Hello " +     request.getName()).build();
    responseObserver.onNext(reply);
    responseObserver.onCompleted();
  }
}
  1. Provider 端暴露 Dubbo 服務(wù)

以 Spring XML 為例







public static void main(String[] args) throws Exception {
  ClassPathXmlApplicationContext context =
    new ClassPathXmlApplicationContext("spring/dubbo-demo-provider.xml");
  context.start();
  System.out.println("dubbo service started");
  new CountDownLatch(1).await();
}
  1. 引用 Dubbo 服務(wù)




public static void main(String[] args) throws IOException {
  ClassPathXmlApplicationContext context =
    new ClassPathXmlApplicationContext("spring/dubbo-demo-consumer.xml");
  context.start();
  GreeterGrpc.IGreeter greeter = (GreeterGrpc.IGreeter) context.getBean("greeter");
  HelloReply reply = greeter.sayHello(HelloRequest.newBuilder().setName("world!").build());
  System.out.println("Result: " + reply.getMessage());
  System.in.read();
}

示例1附:高級(jí)用法

一、異步調(diào)用

再來看一遍 protoc-gen-dubbo-java 生成的接口:

/**
* Code generated for Dubbo
*/
public interface IGreeter {
  default public HelloReply sayHello(HelloRequest request) {
    // ......
  }
  default public ListenableFuture sayHelloAsync(HelloRequest request) {
    // ......
  }
  public void sayHello(HelloRequest request, StreamObserver responseObserver);
}

這里為 sayHello 方法生成了三種類型的重載方法,分別用于同步調(diào)用、異步調(diào)用和流式調(diào)用,如果消費(fèi)端要進(jìn)行異步調(diào)用,直接調(diào)用 sayHelloAsync() 即可:

public static void main(String[] args) throws IOException {
  // ...
  GreeterGrpc.IGreeter greeter = (GreeterGrpc.IGreeter) context.getBean("greeter");
  ListenableFuture future =   
    greeter.sayHAsyncello(HelloRequest.newBuilder().setName("world!").build());
  // ...
}

二、高級(jí)配置

由于當(dāng)前實(shí)現(xiàn)方式是直接集成了 gRPC-java SDK,因此很多配置還沒有和 Dubbo 側(cè)對(duì)齊,或者還沒有以 Dubbo 的配置形式開放,因此,為了提供最大的靈活性,我們直接把 gRPC-java 的配置接口暴露了出來。

絕大多數(shù)場(chǎng)景下,你可能并不會(huì)用到以下擴(kuò)展,因?yàn)樗鼈兏嗟氖菍?duì) gRPC 協(xié)議的攔截或者 HTTP/2 層面的配置。同時(shí)使用這些擴(kuò)展點(diǎn)可能需要對(duì) HTTP/2 或 gRPC 有基本的了解。

擴(kuò)展點(diǎn)

目前支持的擴(kuò)展點(diǎn)如下:

  • org.apache.dubbo.rpc.protocol.grpc.interceptors.ClientInterceptor

  • org.apache.dubbo.rpc.protocol.grpc.interceptors.GrpcConfigurator

  • org.apache.dubbo.rpc.protocol.grpc.interceptors.ServerInterceptor

  • org.apache.dubbo.rpc.protocol.grpc.interceptors.ServerTransportFilter

GrpcConfigurator 是最通用的擴(kuò)展點(diǎn),我們以此為例來說明一下,其基本定義如下:

public interface GrpcConfigurator {
  // 用來定制 gRPC NettyServerBuilder
  default NettyServerBuilder configureServerBuilder(NettyServerBuilder builder, URL url) {
    return builder;
  }
  // 用來定制 gRPC NettyChannelBuilder
  default NettyChannelBuilder configureChannelBuilder(NettyChannelBuilder builder, URL url) {
    return builder;
  }
  // 用來定制 gRPC CallOptions, 定義某個(gè)服務(wù)在每次請(qǐng)求間傳遞數(shù)據(jù)
  default CallOptions configureCallOptions(CallOptions options, URL url) {
    return options;
  }
}

以下是一個(gè)示例擴(kuò)展實(shí)現(xiàn):

public class MyGrpcConfigurator implements GrpcConfigurator {
  private final ExecutorService executor = Executors
    .newFixedThreadPool(200, new NamedThreadFactory("Customized-grpc", true));
  @Override
  public NettyServerBuilder configureServerBuilder(NettyServerBuilder builder, URL url) {
    return builder.executor(executor);
  }
  @Override
  public NettyChannelBuilder configureChannelBuilder(NettyChannelBuilder builder, URL url)
  {
    return builder.flowControlWindow(10);
  }
  @Override
  public CallOptions configureCallOptions(CallOptions options, URL url) {
    return options.withOption(CallOptions.Key.create("key"), "value");
  }
}

配置為 Dubbo SPI,`resources/META-INF/services 增加配置文件

default=org.apache.dubbo.samples.basic.comtomize.MyGrpcConfigurator
  1. 指定 Provider 端線程池 默認(rèn)用的是 Dubbo 的線程池,有 fixed (默認(rèn))、cached、direct 等類型。以下演示了切換為業(yè)務(wù)自定義線程池。

private final ExecutorService executor = Executors
             .newFixedThreadPool(200, new NamedThreadFactory("Customized-grpc", true));
public NettyServerBuilder configureServerBuilder(NettyServerBuilder builder, URL url) 
{
  return builder.executor(executor);
}
  1. 指定 Consumer 端限流值 設(shè)置 Consumer 限流值為 10

@Override
public NettyChannelBuilder configureChannelBuilder(NettyChannelBuilder builder, URL url)
{
  return builder.flowControlWindow(10);
}
  1. 傳遞附加參數(shù) DemoService 服務(wù)調(diào)用傳遞 key

@Override
public CallOptions configureCallOptions(CallOptions options, URL url) {
  if (url.getServiceInterface().equals("xxx.DemoService")) {
    return options.withOption(CallOptions.Key.create("key"), "value");
  } else {
    return options;
  }
}

三、雙向流式通信代碼中還提供了一個(gè)支持 雙向流式通信的示例,同時(shí)提供了攔截流式調(diào)用的 Interceptor 擴(kuò)展示例實(shí)現(xiàn)。

* MyClientStreamInterceptor,工作在 client 端,攔截發(fā)出的請(qǐng)求流和接收的響應(yīng)流
* MyServerStreamInterceptor,工作在 server 端,攔截收到的請(qǐng)求流和發(fā)出的響應(yīng)流

四、TLS 配置

配置方式和 Dubbo 提供的通用的 TLS 支持一致,具體請(qǐng)參見 Dubbo 官方文檔

示例 2, 使用 Protobuf 開發(fā) Dubbo 服務(wù)

下面,我們以一個(gè) 具體的示例來看一下基于 Protobuf 的 Dubbo 服務(wù)開發(fā)流程。

1. 定義服務(wù)

通過標(biāo)準(zhǔn) Protobuf 定義服務(wù)

syntax = "proto3";
    option java_multiple_files = true;
    option java_package = "org.apache.dubbo.demo";
    option java_outer_classname = "DemoServiceProto";
    option objc_class_prefix = "DEMOSRV";
    package demoservice;
    // The demo service definition.
    service DemoService {
      rpc SayHello (HelloRequest) returns (HelloReply) {}
    }
    // The request message containing the user's name.
    message HelloRequest {
      string name = 1;
    }
    // The response message containing the greetings
    message HelloReply {
      string message = 1;
    }

這里定義了一個(gè) DemoService 服務(wù),服務(wù)只包含一個(gè) sayHello 方法,同時(shí)定義了方法的入?yún)⒑统鰠ⅰ?/p>

2. Compiler 編譯服務(wù)

  1. 引入 Protobuf Compiler Maven 插件,同時(shí)指定 protoc-gen-dubbo-java RPC 擴(kuò)展


  org.xolstice.maven.plugins
  protobuf-maven-plugin
  0.5.1
  
    com.google.protobuf:protoc:3.7.1:exe:${os.detected.classifier}    
    
    dubbo-grpc-java
    org.apache.dubbo:protoc-gen-dubbo-java:1.19.0-SNAPSHOT:exe:${os.detected.classifier}
    build/generated/source/proto/main/java
    false
    dubbo
  
  
    
      
        compile
        compile-custom
      
    
  

注意,這里與 Dubbo 對(duì) gRPC 支持部分的區(qū)別在于: dubbo

  1. 生成 RPC stub

# 運(yùn)行以下 maven 命令
$mvn clean compile

生成的 Java 類如下:

DemoServiceDubbo 為 Dubbo 定制的 stub

public final class DemoServiceDubbo {
  private static final AtomicBoolean registered = new AtomicBoolean();
  private static Class init() {
    Class clazz = null;
    try {
      clazz = Class.forName(DemoServiceDubbo.class.getName());
      if (registered.compareAndSet(false, true)) {
        org.apache.dubbo.common.serialize.protobuf.support.ProtobufUtils.marshaller(
          org.apache.dubbo.demo.HelloRequest.getDefaultInstance());
        org.apache.dubbo.common.serialize.protobuf.support.ProtobufUtils.marshaller(
          org.apache.dubbo.demo.HelloReply.getDefaultInstance());
      }
    } catch (ClassNotFoundException e) {
      // ignore 
    }
    return clazz;
  }
  private DemoServiceDubbo() {}
  public static final String SERVICE_NAME = "demoservice.DemoService";
  /**
          * Code generated for Dubbo
          */
  public interface IDemoService {
    static Class clazz = init();
    org.apache.dubbo.demo.HelloReply sayHello(org.apache.dubbo.demo.HelloRequest request);
    java.util.concurrent.CompletableFuture sayHelloAsync(
      org.apache.dubbo.demo.HelloRequest request);
  }
}

最值得注意的是 IDemoService 接口,它會(huì)作為 Dubbo 服務(wù)定義基礎(chǔ)接口。

3. 開發(fā)業(yè)務(wù)邏輯

從這一步開始,所有開發(fā)流程就和直接定義 Java 接口一樣了。實(shí)現(xiàn)接口定義業(yè)務(wù)邏輯。

public class DemoServiceImpl implements DemoServiceDubbo.IDemoService {
  private static final Logger logger = LoggerFactory.getLogger(DemoServiceImpl.class);
  @Override
  public HelloReply sayHello(HelloRequest request) {
    logger.info("Hello " + request.getName() + ", request from consumer: " + RpcContext.getContext().getRemoteAddress());
    return HelloReply.newBuilder()
      .setMessage("Hello " + request.getName() + ", response from provider: "
                  + RpcContext.getContext().getLocalAddress())
      .build();
  }
  @Override
  public CompletableFuture sayHelloAsync(HelloRequest request) {
    return CompletableFuture.completedFuture(sayHello(request));
  }
}

4. 配置 Provider

暴露 Dubbo 服務(wù)





public static void main(String[] args) throws Exception {
  ClassPathXmlApplicationContext context = 
    new ClassPathXmlApplicationContext("spring/dubbo-provider.xml");
  context.start();
  System.in.read();
}

5. 配置 Consumer

引用 Dubbo 服務(wù)



public static void main(String[] args) throws Exception {
  ClassPathXmlApplicationContext context = 
    new ClassPathXmlApplicationContext("spring/dubbo-consumer.xml");
  context.start();
  IDemoService demoService = context.getBean("demoService", IDemoService.class);
  HelloRequest request = HelloRequest.newBuilder().setName("Hello").build();
  HelloReply reply = demoService.sayHello(request);
  System.out.println("result: " + reply.getMessage());
  System.in.read();
}

感謝各位的閱讀,以上就是“怎么使用Dubbo開發(fā)gRPC服務(wù)”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對(duì)怎么使用Dubbo開發(fā)gRPC服務(wù)這一問題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!


當(dāng)前名稱:怎么使用Dubbo開發(fā)gRPC服務(wù)
轉(zhuǎn)載源于:http://weahome.cn/article/psgsej.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部