SpringBoot 集成gRpc Demo

1.gRpc简介

    gRpc是google开源的一个高性能、跨语言的rpc框架,基于HTTP2协议,基于protobuf 3.x;对于开发者,使用gRpc需要做的事情:

1>使用protobuf定义接口,即.proto文件

2>compile生成特定语言的代码,比如JAVA,Python等,解决跨语言的问题。

3>服务端实现上述生成的接口,然后启动,等待客户端进行连接;

4>启动一个或者多个客户端,与service建立连接并发送请求;request和response都被封装成Http2的stream Frame,通过channel进行交互;

2.SpringBoot对于gRpc的封装

    SpringBoot提供了grpc-spring-boot-starter对gRpc进行集成;具体的代码地址https://github.com/xiaoguangtouqiang/grpc-demo.git

项目目录结构如图


grpc-lib存放定义的proto文件,作为公共的依赖,给grpc-client和grpc-server调用;

1>创建grpc-lib文件夹,新建目录src/main/proto,再下面新建helloworld.proto文件,代码如下

syntax = "proto3";

option java_multiple_files = true;
//定义输出的目录,生成的目录就是“net/devh/examples/grpc/lib”下面
option java_package = "net.devh.examples.grpc.lib";
//定义输出的文件名称,生成在lib下的就是HelloWorldProto.class
option java_outer_classname = "HelloWorldProto";

// The greeting service definition.
//定义的接口的类,这里会生成一个SimpleGrpc.class,服务端需要来实现的
service Simple {
    //定义接口方法
    rpc SayHello (HelloRequest) returns (HelloReply) {
    }
}

//请求参数
message HelloRequest {
    string name = 1;
}

//返回结果
message HelloReply {
    string message = 1;
}

然后创建build.gradle,需要添加protobuf将上面的文件编译成java代码,具体内容如下

apply plugin: 'java'
apply plugin: 'com.google.protobuf'
apply plugin: 'idea'

repositories {
    maven { url "https://plugins.gradle.org/m2/" }
}

dependencies {
    compile "io.grpc:grpc-netty:1.10.0"
    compile "io.grpc:grpc-protobuf:1.10.0"
    compile "io.grpc:grpc-stub:1.10.0"
}


protobuf {
    protoc {
        // The artifact spec for the Protobuf Compiler
        artifact = 'com.google.protobuf:protoc:3.0.0'
    }
    plugins {
        // Optional: an artifact spec for a protoc plugin, with "grpc" as
        // the identifier, which can be referred to in the "plugins"
        // container of the "generateProtoTasks" closure.
        grpc {
            artifact = 'io.grpc:protoc-gen-grpc-java:1.0.0-pre2'
        }
    }
    generateProtoTasks {
        ofSourceSet('main')*.plugins {
            // Apply the "grpc" plugin whose spec is defined above, without
            // options.  Note the braces cannot be omitted, otherwise the
            // plugin will not be added. This is because of the implicit way
            // NamedDomainObjectContainer binds the methods.
            grpc { }
        }
    }
}

buildscript {
    repositories {
        maven { url "https://plugins.gradle.org/m2/" }
    }
    dependencies {
        classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.4'
    }
}

然后执行gradle compileJava生成对应的java代码,生成的结果如图所示


2>服务端实现

    通过start.spring.io生成springBoot的服务端,build.gradle文件添加依赖项,代码如下

buildscript {
	ext {
		springBootVersion = '2.0.2.RELEASE'
	}
	repositories {
		mavenCentral()
	}
	dependencies {
		classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
	}
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'

group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8

repositories {
	mavenCentral()
}


dependencies {
	compile('org.springframework.boot:spring-boot-starter-web')
	compile 'net.devh:grpc-server-spring-boot-starter:1.4.0.RELEASE'
	//注意,需要依赖grpc-lib项目
	compile project(':grpc-lib')
	testCompile('org.springframework.boot:spring-boot-starter-test')
}
buildscript {
	dependencies {
		classpath("org.springframework.boot:spring-boot-gradle-plugin:0.8.4")
	}
}

然后创建GrpcServerService实现上面的接口,代码如图所示

package com.example.gRpc;

import io.grpc.stub.StreamObserver;
import net.devh.examples.grpc.lib.HelloReply;
import net.devh.examples.grpc.lib.HelloRequest;
import net.devh.examples.grpc.lib.SimpleGrpc;
import net.devh.springboot.autoconfigure.grpc.server.GrpcService;

@GrpcService(SimpleGrpc.class)
public class GrpcServerService extends SimpleGrpc.SimpleImplBase{
    @Override
    public void sayHello(HelloRequest req, StreamObserver<HelloReply> responseObserver) {
        HelloReply reply = HelloReply.newBuilder().setMessage("Hello =============> " + req.getName()).build();
        responseObserver.onNext(reply);
        responseObserver.onCompleted();
    }
}

另外,需要配置rpc服务端的名称,端口等信息,application.properties配置如图

#服务端名称
spring.application.name=local-grpc-server
#服务端运行端口
server.port=8888
#grpc通信端口
grpc.server.port=9898

3>客户端

与服务端类似,build.gradle文件添加依赖

buildscript {
	ext {
		springBootVersion = '2.0.2.RELEASE'
	}
	repositories {
		mavenCentral()
	}
	dependencies {
		classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
	}
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'

group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8

repositories {
	mavenCentral()
}

dependencies {
	compile project(':grpc-lib')
	compile("net.devh:grpc-client-spring-boot-starter:1.4.0.RELEASE")
	compile('org.springframework.boot:spring-boot-starter-web')
}

然后创建GrpcClientService,调用服务端提供的接口,代码如下

package com.example.gRpcclient;

import io.grpc.Channel;
import net.devh.examples.grpc.lib.HelloReply;
import net.devh.examples.grpc.lib.HelloRequest;
import net.devh.examples.grpc.lib.SimpleGrpc;
import net.devh.springboot.autoconfigure.grpc.client.GrpcClient;
import org.springframework.stereotype.Service;

@Service
public class GrpcClientService {
    @GrpcClient("local-grpc-server")
    private Channel serverChannel;

    public String sendMessage(String name) {
        SimpleGrpc.SimpleBlockingStub stub = SimpleGrpc.newBlockingStub(serverChannel);
        HelloReply response = stub.sayHello(HelloRequest.newBuilder().setName(name).build());
        return response.getMessage();
    }
}

application.properties中配置grpc服务端的信息

server.port=8080
spring.application.name=local-grpc-client
grpc.client.local-grpc-server.host=127.0.0.1
grpc.client.local-grpc-server.port=9898
grpc.client.local-grpc-server.enableKeepAlive=true
grpc.client.local-grpc-server.keepAliveWithoutCalls=true

最后写个简单的请求来测试下

package com.example.gRpcclient;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class GrpcClientController {
    @Autowired
    private GrpcClientService grpcClientService;

    @RequestMapping("/")
    public String printMessage(@RequestParam(defaultValue = "Michael") String name) {
        return grpcClientService.sendMessage(name);
    }
}

运行结果如图所示



参考内容:

https://github.com/yidongnan/grpc-spring-boot-starter/blob/master/README-zh.md

https://blog.csdn.net/qq_28423433/article/details/79108976

https://blog.csdn.net/lyjshen/article/details/52238234

protobuf-gradle-plugin


猜你喜欢

转载自blog.csdn.net/xiaoguangtouqiang/article/details/80492324