Spring Cloud集成grpc

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring Cloud集成grpc相关的知识,希望对你有一定的参考价值。

参考技术A spring cloud集成grpc(Eureka版本)
这个demo的本质是先搭建一套简单的微服务,然后在注册的服务中引入grpc。
说明:使用的Spring Cloud版本不新,是Eureka支持的版本。

目录结果如下图:

在 resources 目录下创建application.yml文件,配置内容如下:

创建SpringBoot的启动类,并使用 @EnableEurekaServer :

运行该类的main方法,在启动成功后,用浏览器防伪 localhost:8761 。

在 resources 目录下创建application.yml文件,用于配置服务注册,配置内容如下:

在 src/main/java/ ,创建grpc服务,并使用 @GrpcService 注册:

在 src/main/java/ 下创建SpringBoot启动的Application,并使用Eureka相关的注解:

运行该类的main方法,然后刷新localhost:8761的网页,检查是否有服务出现。

在 resources 目录下创建application.yml文件,配置服务注册,内容如下:

创建调用grpc的客户端,使用 @GrpcClient 声明服务的地址:

创建控制器,方便测试:

创建SpringBoot的启动类,并注册为服务:

启动该类的main方法,然后刷新浏览器检查 localhost:8761 上是否有新增服务。

gRPC在Spring Cloud中的应用

1、前言

在微服务开发中,服务间的调用一般有两种方式:Feign、RestTemplate,但在实际使用过程中,尤其是Feign,存在各种限制及局限性,如:HTTP请求方式、返回类型等限制,有时会让你觉得那那都别扭。在微服务项目中,服务间的调用,是非常普遍频繁的,其性能也不是很理想。


 为了解决上述问题,进行反复对比,最终服务间的调用方式采取了gRPC方式,其显著特点就是性能之高(通信采用Netty),通过proto文件定义的接口也是非常清晰而又灵活。本文主要就gRPC在Spring Cloud项目中的使用进行说明实战。


 关于gRPC相关基础知识可以参考上一篇文章。


2、gRPC在Spring Cloud中的使用

    看过上一篇文章gRPC的使用的话,你就清楚如果直接使用gRPC,显得有些吃力,因此借助一些开源的框架变得尤为必要。gRPC在Spring Cloud中使用开源项目grpc-spring-boot-starter,便于在Spring Cloud项目中开发应用。

(grpc-spring-boot-starter虽然存在一些问题,但集成Sping Cloud项目已经相当高了,还是不错之选。如果你有时间,精力,还是又必要在源码基础上进行开发。)


下面以实际demo来说明grpc-spring-boot-starter的应用。


2.1 特点

  • 使用@ GrpcService自动创建并运行一个 gRPC 服务,内嵌在 spring-boot 应用中

  • 使用@ GrpcClient自动创建和管理你的客户端

  • 支持Spring Cloud(向Consul或Eureka注册服务并获取gRPC服务器信息)

  • 支持Spring Sleuth 进行链路跟踪

  • 支持对于server、client 分别设置全局拦截器或单个的拦截器

  • 支持Spring-Security

  • 支持metric (micrometer / actuator)


(看了上面这些特点,就知道为啥选择这个开源项目了)


2.2 使用DEMO

2.2.1 定义gRPC接口

     基于protobuf来声明数据模型和RPC接口服务。

     创建一个公共字模块项目spring-boot-grpc-common,用于定义存放gRPC接口(proto),便于gRPC服务端和客户端使用。以helloworld.proto(srcmainprotohelloworld.proto)为例:

syntax = "proto3";



option java_multiple_files = true;

option java_package = "com.xcbeyond.springboot.grpc.lib";

option java_outer_classname = "HelloWorldProto";



// The greeting service definition.

service Simple {

    // Sends a greeting

    rpc SayHello (HelloRequest) returns (HelloReply) {

    }

}



// The request message containing the user's name.

message HelloRequest {

    string name = 1;

}



// The response message containing the greetings

message HelloReply {

    string message = 1;

}


     根据proto的命令可以转换成对应的语言的代码,生成java代码,也可以借助maven插件,在编译时自动生成。这里通过mavent插件,可以在pom.xml中增加如下依赖:

<build>

        <extensions>

            <extension>

                <groupId>kr.motd.maven</groupId>

                <artifactId>os-maven-plugin</artifactId>

                <version>${os.plugin.version}</version>

            </extension>

        </extensions>

        <plugins>

            <plugin>

                <groupId>org.xolstice.maven.plugins</groupId>

                <artifactId>protobuf-maven-plugin</artifactId>

                <version>${protobuf.plugin.version}</version>

                <configuration>

                    <protocArtifact>com.google.protobuf:protoc:${protoc.version}:exe:${os.detected.classifier}</protocArtifact>

                    <pluginId>grpc-java</pluginId>

                    <pluginArtifact>io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier}</pluginArtifact>

                </configuration>

                <executions>

                    <execution>

                        <goals>

                            <goal>compile</goal>

                            <goal>compile-custom</goal>

                        </goals>

                    </execution>

                </executions>

            </plugin>

        </plugins>

</build>


    在maven中进行package编译打包,将会在target中看见根据proto自动生成的Java类。(编译过程中可能会报错,此时可以忽略)


2.2.2 gRPC服务端

maven依赖:


<dependency>

  <groupId>net.devh</groupId>

  <artifactId>grpc-server-spring-boot-starter</artifactId>

  <version>2.2.1.RELEASE</version>

</dependency>


    实现 gRPC server 的业务逻辑,使用注解@GrpcService定义gRPC服务端,如下所示:

package com.xcbeyond.springboot.grpc.server.service;



import com.xcbeyond.springboot.grpc.lib.HelloReply;

import com.xcbeyond.springboot.grpc.lib.HelloRequest;

import com.xcbeyond.springboot.grpc.lib.SimpleGrpc;

import io.grpc.stub.StreamObserver;

import net.devh.boot.grpc.server.service.GrpcService;



/**

 * @Auther: xcbeyond

 * @Date: 2019/3/6 18:15

 */


@GrpcService

public class GrpcServerService extends SimpleGrpc.SimpleImplBase {

    @Override

    public void sayHello(HelloRequest request, StreamObserver<HelloReply> responseObserver) {

        System.out.println("GrpcServerService...");

        HelloReply reply = HelloReply.newBuilder().setMessage("Hello ==> " + request.getName()).build();

        responseObserver.onNext(reply);

        responseObserver.onCompleted();

    }

}


application.yml配置:


gRPC 的 host 跟 port ,默认的监听的 host 是 0.0.0.0,默认的 port 是 9090,配置为0将会自动分配未使用的端口。

grpc:

  server:

    port: 0


2.2.3 gRPC客户端

maven依赖:

<dependency>

<groupId>net.devh</groupId>

<artifactId>grpc-client-spring-boot-starter</artifactId>

<version>2.2.1.RELEASE</version>

</dependency>


    使用注解@GrpcClient来调用服务端接口,通过

HelloReply response = simpleBlockingStub.sayHello(HelloRequest.newBuilder().setName(name).build());

直接向服务端发起请求,和调用本地接口一样。

package com.xcbeyond.springboot.grpc.client.service;



import com.xcbeyond.springboot.grpc.lib.HelloReply;

import com.xcbeyond.springboot.grpc.lib.HelloRequest;

import com.xcbeyond.springboot.grpc.lib.SimpleGrpc.SimpleBlockingStub;

import io.grpc.StatusRuntimeException;

import net.devh.boot.grpc.client.inject.GrpcClient;

import org.springframework.stereotype.Service;



/**

 * @Auther: xcbeyond

 * @Date: 2019/3/7 09:10

 */


@Service

public class GrpcClientService {



    @GrpcClient("spring-boot-grpc-server")

    private SimpleBlockingStub simpleBlockingStub;



    public String sendMessage(String name) {

        try {

            HelloReply response = simpleBlockingStub.sayHello(HelloRequest.newBuilder().setName(name).build());

            return response.getMessage();

        } catch (final StatusRuntimeException e) {

            return "FAILED with " + e.getStatus().getCode();

        }

    }

}


application.yml配置:


   spring-boot-grpc-server,即:服务端应用名,结合spring cloud Eureka注册中心,通过服务名将会找到服务端的ip,进行通信,实际上是netty通信。

grpc:

  client:

    spring-boot-grpc-server:

      enableKeepAlive: true

      keepAliveWithoutCalls: true

      negotiationType: plaintext


本demo完整代码请参考https://github.com/xcbeyond/spring-boot-grpc.git。


gRPC在Spring Cloud中的应用
gRPC在Spring Cloud中的应用gRPC在Spring Cloud中的应用 “程序猿技术大咖”,您值得拥有!
gRPC在Spring Cloud中的应用
公众号ID:cxyjsdk
长按左侧二维码关注

以上是关于Spring Cloud集成grpc的主要内容,如果未能解决你的问题,请参考以下文章

Spring Cloud Gateway集成

Spring Cloud Ribbon集成

Spring Cloud Hystrix集成

spring-cloud-sleuth 与 spring-amqp 集成

Spring Cloud微服务分布式云架构 - spring cloud集成项目

Spring cloud 集成Swagger