2 Star 3 Fork 1

石头哥哥 / grpc

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README

关于 grpc , proto3 的实践分享

前言

互联网+ , 微服务化---服务模块化,它们之间的数据交互协作方式TCP/IP自定义协议 ,Restful风格,RPC(远程调用)等

RPC (远程过程调用,远程方法调用)----允许一台电脑上的程序调用另一台电脑的程序,它有标准化的沟通机制, 为了能够实现跨平台,大都采用接口描述性语言(Interface Description Language,IDL),无需关注底层实现,专注业务需求开发

facebook 开发的 apache thrift

它采用接口描述语言定义并创建服务,支持可扩展的跨语言服务开发,所包含的代码生成引擎可以在多种语言中, 如 C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, Smalltalk等创建高效的、无缝的服务, 其传输数据采用二进制格式 thrift应用实践demo

google开发的GRPC

gRPC是一个高性能、通用的开源RPC框架,其由Google主要面向移动应用开发并基于HTTP/2协议标准而设计, 基于ProtoBuf(Protocol Buffers)序列化协议开发,且支持众多开发语言。

GRPC 构建

支持多种语言

gRPC支持多种语言,并能够基于语言自动生成客户端和服务端功能库。目前, 在GitHub上已提供了C版本grpc、Java版本grpc-java 和 Go版本grpc-go, 其它语言的版本正在积极开发中,其中 grpc支持C、C++、Node.js、Python、Ruby、Objective-C、PHP和C#等语言, grpc-java已经支持Android开发。

基于HTTP/2标准设计

由于gRPC基于HTTP/2标准设计,所以相对于其他RPC框架,gRPC带来了更多强大功能,如双向流、头部压缩、多复用请求等。 这些功能给移动设备带来重大益处,如节省带宽、降低TCP链接次数、节省CPU使用和延长电池寿命等。 同时,gRPC还能够提高了云端服务和Web应用的性能。gRPC既能够在客户端应用,也能够在服务器端应用, 从而以透明的方式实现客户端和服务器端的通信和简化通信系统的构建。

gRPC已经应用在Google的云服务和对外提供的API中,其主要应用场景如下:

  1. 低延迟、高扩展性、分布式的系统
  2. 同云服务器进行通信的移动应用客户端
  3. 设计语言独立、高效、精确的新协议
  4. 便于各方面扩展的分层设计,如认证、负载均衡、日志记录、监控等

gRPC是什么

使用gRPC,一个客户端应用程序可以直接调用另一台机器上的服务端应用程序的方法,就好像调用本地方法一样。这使得更容易创建分布式应用程序和服务。 正如很多RPC系统,gRPC是基于定义服务,指定可以远程调用方法的参数和返回类型的概念。在服务器侧,服务端实现该接口并且返回gRPC的客户端来处理客户端调用请求。 在客户端侧,客户端打桩,提供跟服务端一样的方法。

grpc_what

proto3 编译安装

  1. 编译基础需求
  • autoconf
  • automake
  • libtool
  • curl (used to download gmock)
  1. 构建
#注意配置依赖 gmock --- (被墙)
./autogen.sh


./configure --prefix=/usr
make && make check && make install
  1. 编写IDL文件
syntax = "proto3";

option java_multiple_files = true;

package pb;

// The greeter service definition.
service Greeter {
    // Sends a greeting
    rpc  SayHello (HelloRequest) returns (HelloResponse){}
}

service Test {
    // Sends a greeting
    rpc  SayHello (HelloRequest) returns (HelloResponse){}
}


// The request message containing the user's name.
message HelloRequest {
    string name = 1;
}

// The response message containing the greetings
message HelloResponse {
    string message = 1;
}
  1. 依赖maven,构建GRPC的编译器

编译器

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">


    <modelVersion>4.0.0</modelVersion>


    <properties>
        <protobuf.version>3.0.0-beta-2</protobuf.version>
        <grpc.version>0.9.0</grpc.version>
    </properties>

    //grpc需求依赖的模块
    <dependencies>
        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-core</artifactId>
            <version>${grpc.version}</version>
        </dependency>

        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-stub</artifactId>
            <version>${grpc.version}</version>
        </dependency>

        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-protobuf</artifactId>
            <version>${grpc.version}</version>
        </dependency>

        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-netty</artifactId>
            <version>${grpc.version}</version>
        </dependency>



        <dependency>
            <groupId>com.google.protobuf</groupId>
            <artifactId>protobuf-java</artifactId>
            <version>${protobuf.version}</version>
        </dependency>

        <dependency>
            <groupId>com.google.protobuf.nano</groupId>
            <artifactId>protobuf-javanano</artifactId>
            <version>3.0.0-alpha-5</version>
        </dependency>

    </dependencies>


    <!--protoc plugin 仓库 -->
    <pluginRepositories>
        <pluginRepository>
            <releases>
                <updatePolicy>never</updatePolicy>
            </releases>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
            <id>central</id>
            <name>Central Repository</name>
            <url>https://repo.maven.apache.org/maven2</url>
        </pluginRepository>
        <pluginRepository>
            <id>protoc-plugin</id>
            <url>https://dl.bintray.com/sergei-ivanov/maven/</url>
        </pluginRepository>
    </pluginRepositories>


    <build>
        <extensions>
            <extension>
                <groupId>kr.motd.maven</groupId>
                <artifactId>os-maven-plugin</artifactId>
                <version>1.4.0.Final</version>
            </extension>
        </extensions>
        <plugins>
            <!--grpc plugin-->
            <plugin>
                <groupId>com.google.protobuf.tools</groupId>
                <artifactId>maven-protoc-plugin</artifactId>
                <version>0.4.4</version>
                <configuration>
                    <!--
                      The version of protoc must match protobuf-java. If you don't depend on
                      protobuf-java directly, you will be transitively depending on the
                      protobuf-java version that grpc depends on.
                    -->
                    <pluginId>grpc-java</pluginId>
                    <protocArtifact>com.google.protobuf:protoc:3.0.0-beta-2:exe:${os.detected.classifier}
                    </protocArtifact>
                    <pluginArtifact>io.grpc:protoc-gen-grpc-java:0.9.0:exe:${os.detected.classifier}</pluginArtifact>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                            <goal>compile-custom</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

生成的对象解析

  /**
    服务端实现接口
  */
  public static interface Greeter {

    public void sayHello(pb.HelloRequest request,
        io.grpc.stub.StreamObserver<pb.HelloResponse> responseObserver);
  }

    /**
     * 客户端实现接口
     */
  public static interface GreeterBlockingClient {

    public pb.HelloResponse sayHello(pb.HelloRequest request);
  }


    /**
     调用方法
    */
    @java.lang.Override
    public void sayHello(pb.HelloRequest request,
        io.grpc.stub.StreamObserver<pb.HelloResponse> responseObserver) {
      asyncUnaryCall(
          getChannel().newCall(METHOD_SAY_HELLO, getCallOptions()), request, responseObserver);
    }
  }

 /*
    绑定服务 ---
 *
 /
  public static io.grpc.ServerServiceDefinition bindService(
      final Greeter serviceImpl) {
    return io.grpc.ServerServiceDefinition.builder(SERVICE_NAME)
      .addMethod(
        METHOD_SAY_HELLO,
        asyncUnaryCall(
          new io.grpc.stub.ServerCalls.UnaryMethod<
              pb.HelloRequest,
              pb.HelloResponse>() {
            @java.lang.Override
            public void invoke(
                pb.HelloRequest request,
                io.grpc.stub.StreamObserver<pb.HelloResponse> responseObserver) {
              serviceImpl.sayHello(request, responseObserver);
            }
          })).build();
  }
}

关键代码片段分解

结构预览

服务器端

1.服务端包含2个模块:网络模块,服务绑定模块

ServerBuilder(基于netty构建的HTTP/2)

服务端网络服务核心模块

网络模块

网络模块代码结构

    /**
     * handle logic  thread pool
     * 用于执行业务逻辑
     */
    private static final ExecutorService executorService =
            Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()
                    , new NamedThreadFactory("logic-handler"));

    /**
     * 启动服务
     *
     * @throws Exception
     */
    public void startGrpc() throws Exception {

        //init builder
        initServerBuilder();

        //bind service
        server = nettyServerBuilder.build().start();

        //register hook
        Runtime.getRuntime().addShutdownHook(new Thread() {
            @Override
            public void run() {
                // Use stderr here since the logger may has been reset by its JVM shutdown hook.
                logger.debug("*** shutting down gRPC server since JVM is shutting down");
                if (server != null) {
                    server.shutdown();// shut down
                }
                executorService.shutdown();
                logger.debug("*** server shut down");
            }
        });

        if (logger.isDebugEnabled()) {
            logger.debug("grpc_server bind service port:" + port);
        }

    }

    /**
     * 挂起服务,提供持久的对外服务
     * @throws InterruptedException
     */
    public void awaitTermination() throws InterruptedException {
        server.awaitTermination();
    }

绑定服务模块

服务绑定抽象类

简单的逻辑实现(对外服务)

服务逻辑处理

客户端

发送的channel ----ManagedChannel,grpc-java 内建根据权重选择对应的channel实现(netty,okhttp,inprocess)

channel选择核心代码

初始化chanel

        if (PlatformDependent.isAndroid()) {// android  平台
            channel = OkHttpChannelBuilder.forAddress(host, port)
                    .usePlaintext(true)
                    .build();
        } else {
            ManagedChannelBuilder managedChannelBuilder = ManagedChannelBuilder.forAddress(host, port);
            if (managedChannelBuilder instanceof NettyChannelBuilder) {
                NettyChannelBuilder nettyChannelBuilder = (NettyChannelBuilder) managedChannelBuilder;

                //default is TLS
//            nettyChannelBuilder.negotiationType(NegotiationType.TLS);
//            try {
//                nettyChannelBuilder.sslContext(GrpcSslContexts.forClient().build());
//            } catch (SSLException e) {
//                e.printStackTrace();
//            }
                channel = nettyChannelBuilder
                        .usePlaintext(true)
                        .build();

            } else if (managedChannelBuilder instanceof InProcessChannelBuilder) {

                InProcessChannelBuilder inProcessChannelBuilder =
                        (InProcessChannelBuilder) managedChannelBuilder;
                channel = inProcessChannelBuilder
                        .usePlaintext(true)
                        .build();
            }

        }

简单使用

  /**
     * 作为单例对象
     */
    HelloWorldClient client = new HelloWorldClient("localhost", 50051);
    //build blocking stub (client)----
    GreeterGrpc.GreeterBlockingClient greeterBlockingClient =
                       GreeterGrpc.newBlockingStub(grpcClient.getChannel());
    //builder send data
    HelloRequest request = HelloRequest.newBuilder().setName(name).build();
    grpcClient.shutdown();

演示

空文件

简介

暂无描述 展开 收起
取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
1
https://gitee.com/502959937/grpc.git
git@gitee.com:502959937/grpc.git
502959937
grpc
grpc
master

搜索帮助