gRPC SkyLB.md

gRPC SkyLB

gRPC 作為一款高性能、通用的 RPC 框架,相比傳統(tǒng)的RPC框架有著自己天然的優(yōu)勢(shì):

  1. protobuf二進(jìn)制消息,性能好/效率高(空間和時(shí)間效率都很不錯(cuò));
  2. proto文件生成目標(biāo)代碼,簡(jiǎn)單易用;
  3. 序列化反序列化直接對(duì)應(yīng)程序中的數(shù)據(jù)類,不需要解析后在進(jìn)行映射(XML,JSON都是這種方式);
  4. 支持向前兼容(新加字段采用默認(rèn)值)和向后兼容(忽略新加字段),簡(jiǎn)化升級(jí);
  5. 支持多種語言(可以把proto文件看做IDL文件);
  6. Netty等一些框架集成;

服務(wù)注冊(cè)/發(fā)現(xiàn) 是RPC框架的核心組件,但是gRPC 作為企業(yè)級(jí)框架,他的開源組件官方并未直接提供服務(wù)注冊(cè)與發(fā)現(xiàn)的功能實(shí)現(xiàn)。而是在設(shè)計(jì)文檔(load-balancing.md)中提供了實(shí)現(xiàn)的思路,并在不同語言的gRPC代碼API中提供了命名解析和負(fù)載均衡接口供擴(kuò)展。

關(guān)于gRPC 服務(wù)發(fā)現(xiàn)&負(fù)載均衡的介紹,可以參見我之前寫的一篇文章 gRPC服務(wù)發(fā)現(xiàn)&負(fù)載均衡

Overview

gRPC SkyLB 采用獨(dú)立LB進(jìn)程(External Load Balancing Service)負(fù)載均衡方式,支持輪詢、一致性哈希兩種負(fù)載均衡策略,并支持服務(wù)端權(quán)重。采用etcd作為注冊(cè)中心。

項(xiàng)目地址:

https://github.com/binchencoder/grpc-skylb

Architecture of SkyLB

architecture.png

服務(wù)提供者起來后向注冊(cè)中心(SkyLB) 注冊(cè)自己的信息,ip、端口、權(quán)重等,并保持心跳??蛻舳吮O(jiān)聽注冊(cè)中心,獲取服務(wù)器列表,一旦服務(wù)器發(fā)生變化,客戶端馬上更新本地的服務(wù)器列表??蛻舳嗣總€(gè)請(qǐng)求都通過負(fù)載均衡策略選擇一個(gè)合適的服務(wù)器去訪問。

Usage

  1. Dependency

    Install skylb-client local repository

    chenbindeMacBook-Pro:grpc-skylb chenbin$ mvn clean install
    
    <dependency>
     <groupId>com.binchencoder.skylb</groupId>
     <artifactId>skylb-client</artifactId>
     <version>1.0-SNAPSHOT</version>
    </dependency>
    
  2. Implements gRPC API

    public class DemoGrpcImpl extends DemoGrpc.DemoImplBase {
      private final Logger LOGGER = LoggerFactory.getLogger(DemoGrpcImpl.class);
    
      private Random rand = new Random(System.currentTimeMillis());
      private int port;
      public DemoGrpcImpl(int port_) {
        this.port = port_;
      }
    
      @Override
      public void greeting(GreetingProtos.GreetingRequest request,
          StreamObserver<GreetingProtos.GreetingResponse> responseObserver) {
        LOGGER.info("Got req: {}", request);
    
        // 隨機(jī)耗時(shí)350~550毫秒.
        int elapse = 350 + rand.nextInt(200);
        try {
          TimeUnit.MILLISECONDS.sleep(elapse);
        } catch (InterruptedException ie) {
          LOGGER.warn("sleep interrupted");
        }
    
        GreetingResponse reply = GreetingResponse.newBuilder().setGreeting(
            "Hello " + request.getName() + ", from :" + port + ", elapse " + elapse + "ms").build();
        responseObserver.onNext(reply);
        responseObserver.onCompleted();
      }
    
      @Override
      public void greetingForEver(GreetingProtos.GreetingRequest request,
          StreamObserver<GreetingProtos.GreetingResponse> responseObserver) {
        super.greetingForEver(request, responseObserver);
      }
    }
    
  3. Register gRPC Server to SkyLB Server

    Server server = ServerTemplate.create(
             {port} 9090, 
             {bindableService} new DemoGrpcImpl(), 
             {serviceName} "shared-test-client-service")
      .build()
      .start();
    
    SkyLBServiceReporter reporter = ServerTemplate.reportLoad(
             {skylbUri} "skylb://127.0.0.1:1900/",
             {serviceName} ServiceNameUtil.toString(ServiceId.CUSTOM_EASE_GATEWAY_TEST),
             {portName} "grpc",
             {port} 9090);
    
  4. Call gRPC Server

    Create gRPC Stub

    ManagedChannel channel = ClientTemplate.createChannel(
             {skylbAddr} "skylb://127.0.0.1:1900/",
             {calleeServiceName} ServiceNameUtil.toString(ServiceId.CUSTOM_EASE_GATEWAY_TEST),
             {calleePortName} "grpc", 
             {calleeNamespace} null,                                   
             {callerServiceName} ServiceNameUtil.toString(ServiceId.SERVICE_NONE)).getOriginChannel();
    
    DemoGrpc.DemoBlockingStub blockingStub = DemoGrpc.newBlockingStub(channel);
    
    GreetingRequest request = GreetingRequest.newBuilder()
      .setName("GC " + Calendar.getInstance().get(Calendar.SECOND))
      .build();
    GreetingResponse response = blockingStub
      .withDeadlineAfter(2000, TimeUnit.MILLISECONDS)
      .greeting(request);
    

Run Demo

  1. Build SkyLB Server

    chenbindeMacBook-Pro:grpc-skylb chenbin$ cd skylb-server
    chenbindeMacBook-Pro:skylb-server chenbin$ mvn clean package
    

    最終skylb.jar 打包到 skylb-server/target 目錄下

  2. Start SkyLB Server

    Start ETCD3

    yum install etcd -y
    
    systemctl enable etcd && systemctl start etcd
    

    NOTE

    部署ETCD遇到問題可參考 https://www.cnblogs.com/shawhe/p/10640820.html

    chenbindeMacBook-Pro:skylb-server chenbin$ cd target/skylblib
    
    chenbindeMacBook-Pro:skylblib chenbin$ java -jar skylb.jar -h
     Usage: java -jar skylb.jar [options] [command] [command options]
      Options:
        --auto-disconn-timeout, -auto-disconn-timeout
          The timeout to automatically disconnect the resolve RPC. e.g. 10s(10 
          Seconds), 10m(10 Minutes)
          Default: PT5M
      Commands:
        etcd      Help for etcd options
          Usage: etcd [options]
            Options:
              --etcd-endpoints, -etcd-endpoints
                The comma separated ETCD endpoints. e.g., 
                http://etcd1:2379,http://etcd2:2379 
                Default: [http://127.0.0.1:2379]
              --etcd-key-ttl, -etcd-key-ttl
                The etcd key time-to-live. e.g. 10s(10 Seconds), 10m(10 Minutes)
                Default: PT10S
    
    chenbindeMacBook-Pro:skylblib chenbin$ java -jar skylb.jar -etcd-endpoints=http://127.0.0.1:2379
    
  3. Start gRPC Server

    https://github.com/binchencoder/grpc-skylb/blob/master/examples/demo/src/main/java/com/binchencoder/skylb/demo/grpc/server/GreetingServer.java

    Run com/binchencoder/skylb/demo/grpc/server/GreetingServer#main

  4. Start gRPC Client

    https://github.com/binchencoder/grpc-skylb/blob/master/examples/demo/src/main/java/com/binchencoder/skylb/demo/grpc/client/GreetingClient.java

    Run com/binchencoder/skylb/demo/grpc/client/GreetingClient#main

More Examples

grpc-skylb/examples/echo

該示例采用SpringBoot腳手架,在spring-boot-grpc-common.jar中封裝好了注冊(cè)服務(wù)的邏輯,啟動(dòng)方式比較簡(jiǎn)單

@GrpcService(applyGlobalInterceptors = true) // Default use Global Interceptor
public class EchoGrpcService extends EchoServiceGrpc.EchoServiceImplBase {
}
  1. 使用@GrpcService 注解方式標(biāo)示gRPC Service

  2. 在 spring-boot-grpc-common.jar 中默認(rèn)配置兩個(gè)Global Interceptor(ExceptionInterceptor, AuthenticationInterceptor)

  3. 使用者可通過注解不使用Global Interceptor,實(shí)現(xiàn)自己的Interceptor

    @GrpcService(applyGlobalInterceptors = false, interceptors = ExceptionInterceptor.class)
    

Features

  • @GrpcService Annotation
  • 支持配置全局?jǐn)r截器
  • 將來計(jì)劃支持skylb-client Golang版本

References

本人現(xiàn)在正在找工作,有合適的伯樂可隨時(shí)騷擾

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1)簡(jiǎn)介 gRPC負(fù)載平衡的主要實(shí)現(xiàn)機(jī)制是外部負(fù)載平衡,即通過外部負(fù)載平衡器來向客戶端提供更新后的服務(wù)器列表。 g...
    Jay_Guo閱讀 13,644評(píng)論 6 22
  • 1 服務(wù)化 服務(wù)化(SOA: Service-oriented architecture): 小而美的獨(dú)立功能 平...
    tracy_668閱讀 8,216評(píng)論 0 4
  • 目標(biāo)任務(wù): 1、Kubernetes集群部署架構(gòu)規(guī)劃 2、部署Etcd集群 3、在Node節(jié)點(diǎn)安裝Docker 4...
    落幕_f94c閱讀 1,271評(píng)論 2 0
  • K8s安裝 主機(jī)部署組件說明(根據(jù)文檔架構(gòu)): master-1主機(jī)對(duì)應(yīng)的是ETCE_NAME="etcd01" ...
    我的喵叫初六閱讀 951評(píng)論 0 0
  • 漸變的面目拼圖要我怎么拼? 我是疲乏了還是投降了? 不是不允許自己墜落, 我沒有滴水不進(jìn)的保護(hù)膜。 就是害怕變得面...
    悶熱當(dāng)乘涼閱讀 4,480評(píng)論 0 13

友情鏈接更多精彩內(nèi)容