IDEA搭建gRPC服务

一、什么是gRPC
gRPC是一个高性能、通用的开源 RPC 框架,其由 Google 主要面向移动应用开发并基于HTTP/2协议标准而设计,基于ProtoBuf(Protocol Buffers) 序列化协议开发,且支持众多开发语言。gRPC 提供了一种简单的方法来精确地定义服务和为 iOS、Android 和后台支持服务自动生成可靠性很强的客户端功能库。客户端充分利用高级流和链接功能,从而有助于节省带宽、降低的 TCP 链接次数、节省 CPU 使用、和电池寿命。
gRPC使用 ProtoBuf 来定义服务,ProtoBuf 是由 Google 开发的一种数据序列化协议(类似于 XML、JSON、hessian)。ProtoBuf 能够将数据进行序列化,并广泛应用在数据存储、通信协议等方面。不过,当前 gRPC 仅支持 Protobuf ,且不支持在浏览器中使用。由于 gRPC 的设计能够支持支持多种数据格式。
二、首先搭建maven项目
IDEA搭建gRPC服务
1.然后在src/main目录下的proto目录
IDEA搭建gRPC服务
2.设置把proto设置成java的sources,选择file->project structure->modules
IDEA搭建gRPC服务
3.创建hello_service.proto的文件
IDEA搭建gRPC服务
4.hello_service.proto与hello.proto
4.1、hello.proto

syntax = "proto3";

package com.xxx.tutorial.demo.grpc;

option java_multiple_files = true;
option java_package = "com.xxx.tutorial.model";
option java_outer_classname = "Hello";

message HelloRequest{  
    string name  = 1;  
    int32 id    = 2;  
}  
message HelloResponse{  
    string message = 1;  
}  

4.2、hello_service.proto

syntax = "proto3";

package com.xxx.tutorial.demo.grpc;


option java_multiple_files = true;
option java_package = "com.xxx.tutorial.service";
option java_outer_classname = "GreetingService";

import "hello.proto";

service HelloService{  
    rpc sayHello(HelloRequest) returns (HelloResponse);  
}  

5.需要导入一个IDEA插件Protobuf
IDEA搭建gRPC服务
6.使用maven进行编译
IDEA搭建gRPC服务
7.选择install等待一会进行生成GRPC代码
IDEA搭建gRPC服务
三、应用springboot搭建GRPC项目
8.比如说创建简单的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;
}

9.将gradle转换成maven
注意此代码是gradle转写maven的gradle文件,并非项目文件。进行gradle打包需要将此代码注释

apply plugin: 'maven'

task writeNewPom << {
    pom {
        project {
            inceptionYear '2018'
            licenses {
                license {
                    name 'The Apache Software License, Version 2.0'
                    url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
                    distribution 'repo'
                }
            }
        }
    }.writeTo("pom.xml")
}

IDEA搭建gRPC服务
再运行右侧 gradle writeNewPom 即可在当前项目中生成pom.xml文件。
10.创建springboot的依赖
IDEA搭建gRPC服务
build.gradle

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'
    }
}

进行编译
IDEA搭建gRPC服务
11.创建客户端项目
IDEA搭建gRPC服务
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'

//apply plugin: 'maven'

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')
}


//
//task writeNewPom << {
//	pom {
//		project {
//			inceptionYear '2018'
//			licenses {
//				license {
//					name 'The Apache Software License, Version 2.0'
//					url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
//					distribution 'repo'
//				}
//			}
//		}
//	}.writeTo("pom.xml")
//} as String

GRPCClientApplication

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class GRpcClientApplication {

	public static void main(String[] args) {
		SpringApplication.run(GRpcClientApplication.class, args);
	}
}

GrpcClientController

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);
    }
}

GrpcClientService


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

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

12.服务端项目

IDEA搭建gRPC服务
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")
	}
}

GRpcApplication

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class GRpcApplication {

	public static void main(String[] args) {
		SpringApplication.run(GRpcApplication.class, args);
	}
}

GrpcServerService

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();
    }
}

application.properties

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

13.大功告成。
14.待续…