java|springboot-grpc

grpc简介:
官网地址:https://grpc.io/
gRPC 是一个高性能、开源、通用的RPC框架,由Google推出,基于HTTP2协议标准设计开发,默认采用Protocol Buffers数据序列化协议,支持多种开发语言。gRPC提供了一种简单的方法来精确的定义服务,并且为客户端和服务端自动生成可靠的功能库。
在gRPC客户端可以直接调用不同服务器上的远程程序,使用姿势看起来就像调用本地程序一样,很容易去构建分布式应用和服务。和很多RPC系统一样,服务端负责实现定义好的接口并处理客户端的请求,客户端根据接口描述直接调用需要的服务。客户端和服务端可以分别使用gRPC支持的不同语言实现。
java|springboot-grpc
文章图片

特性:
  • 强大的IDL
    gRPC使用ProtoBuf来定义服务,ProtoBuf是由Google开发的一种数据序列化协议(类似于XML、JSON、hessian)。ProtoBuf能够将数据进行序列化,并广泛应用在数据存储、通信协议等方面。
  • 多语言支持
    gRPC支持多种语言,并能够基于语言自动生成客户端和服务端功能库。目前已提供了C版本grpc、Java版本grpc-java 和 Go版本grpc-go,其它语言的版本正在积极开发中,其中,grpc支持C、C++、Node.js、Python、Ruby、Objective-C、PHP和C#等语言,grpc-java已经支持Android开发。
  • HTTP2
    gRPC基于HTTP2标准设计,所以相对于其他RPC框架,gRPC带来了更多强大功能,如双向流、头部压缩、多复用请求等。这些功能给移动设备带来重大益处,如节省带宽、降低TCP链接次数、节省CPU使用和延长电池寿命等。同时,gRPC还能够提高了云端服务和Web应用的性能。gRPC既能够在客户端应用,也能够在服务器端应用,从而以透明的方式实现客户端和服务器端的通信和简化通信系统的构建。
DEMO-java
主要依赖:
io.github.lognet grpc-spring-boot-starter 3.0.0

配置proto:
kr.motd.maven os-maven-plugin 1.4.1.Final org.apache.maven.plugins maven-surefire-plugin 2.22.2 true org.springframework.boot spring-boot-maven-plugin org.xolstice.maven.plugins protobuf-maven-plugin 0.5.0 com.google.protobuf:protoc:3.5.1-1:exe:${os.detected.classifier}grpc-javaio.grpc:protoc-gen-grpc-java:1.16.1:exe:${os.detected.classifier} compile compile-custom

编写proto接口文件
syntax = "proto3"; option java_multiple_files = true; package cc.superl.grpc.demo.hello; message Person { string first_name = 1; string last_name = 2; }message Greeting { string message = 1; }service HelloWorldService { rpc sayHello (Person) returns (Greeting); }

【可自行安装protobuf工具进行生成的语言代码】
具体查看 https://developers.google.com/protocol-buffers/docs/proto3#generating

进行编译:
java|springboot-grpc
文章图片

产出结果就是接口:
java|springboot-grpc
文章图片

开始编写简单的demo
  • Server端
import cc.superl.grpc.demo.hello.Greeting; import cc.superl.grpc.demo.hello.HelloWorldServiceGrpc.HelloWorldServiceImplBase; import cc.superl.grpc.demo.hello.Person; import io.grpc.stub.StreamObserver; import org.lognet.springboot.grpc.GRpcService; @GRpcService public class HelloServerImpl extends HelloWorldServiceImplBase {@Override public void sayHello(Person request, StreamObserver responseObserver) {String message = "Hello " + request.getFirstName() + " " + request.getLastName() + "!"; Greeting greeting = Greeting.newBuilder().setMessage(message).build(); responseObserver.onNext(greeting); responseObserver.onCompleted(); } }

  • 客户端dmeo
import cc.superl.grpc.demo.hello.Greeting; import cc.superl.grpc.demo.hello.HelloWorldServiceGrpc; import cc.superl.grpc.demo.hello.Person; import io.grpc.ManagedChannel; import io.grpc.ManagedChannelBuilder; import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; @Component public class HelloClient {private HelloWorldServiceGrpc.HelloWorldServiceBlockingStub stub; @PostConstruct private void init() { ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost",6565).usePlaintext().build(); stub = HelloWorldServiceGrpc.newBlockingStub(channel); } public String sayHello(String firstName,String lastName) { Person person = Person.newBuilder().setFirstName(firstName) .setLastName(lastName).build(); Greeting greeting = stub.sayHello(person); return greeting.getMessage(); } }

grpc-port 默认为6565,可进行设置在application配置文件中其他端口
  • 测试类
import cc.superl.grpc.demo.client.HelloClient; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import static org.assertj.core.api.Assertions.assertThat; @RunWith(SpringRunner.class) @SpringBootTest public class DemoApplicationTests {@Autowired private HelloClient client; @Test public void testSayHello() { assertThat(client.sayHello("a","b")).isEqualTo("Hello a b!"); } }

简单demo就到此了
福利:
对grpc的反向代理,nginx在1.13.10版本做了支持,https://www.nginx.com/blog/nginx-1-13-10-grpc/
安装编译nginx时需
./configure --with-http_ssl_module --with-http_v2_module

nginx.conf配置内容为:
http { log_formatmain'$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent"'; server { listen 80 http2; access_log logs/access.log main; location / { # Replace localhost:50051 with the address and port of your gRPC server # The 'grpc://' prefix is optional; unencrypted gRPC is the default grpc_pass grpc://localhost:50051; } } }

对于TLS支持为
http { log_formatmain'$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent"'; server { listen 1443 ssl http2; ssl_certificatessl/cert.pem; ssl_certificate_key ssl/key.pem; access_log logs/access.log main; location / { # Use grpcs for TLS-encrypted gRPC traffic grpc_pass grpcs://localhost:50051; } } }s

参看资料:
https://www.nginx.com/blog/nginx-1-13-10-grpc/
https://www.bookstack.cn/read/go-grpc/chapter1-intro.md
https://grpc.io/docs/quickstart/java/
https://yidongnan.github.io/grpc-spring-boot-starter/en/server/getting-started.html
【java|springboot-grpc】

    推荐阅读