java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > gRPC整合SpringCloud

一文详解gRPC快速整合SpringCloud

作者:东小西

这篇文章主要为大家介绍gRPC快速整合SpringCloud的实现示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

gRPC

gRPC是由 google开发的一个高性能、通用的开源RPC框架,主要面向移动应用开发且基于HTTP/2协议标准而设计,同时支持大多数流行的编程语言。它是一种与语言、平台无关、可扩展的序列化结构数据。它的定位类似于JSON、XML,但是比他们更小、更快、更简单。

优势

gRPC基于HTTP/2协议传输,而HTTP/2相比HTTP1.x,还是有需要优势的:

HTTP/2支持通过一个连接发送多个并发的请求。

服务端推送是一种在客户端请求之前发送数据的机制。在HTTP/2中,服务器可以对客户端的一个请求发送多个响应。而不像HTTP/1.X一样,只能通过客户端发起request,服务端才产生对应的response。

HTTP/2对消息头进行了压缩传输,能够节省消息头占用的网络流量。

工作方式

从上图可以看出,简单了解一下grpc的工作模式。用gRPC来进行远程调用服务,客户端(client) 仅仅需要gRPC Stub ,通过Proto Request向gRPC Server发起服务调用,然后 gRPC Server通过Proto Response(s)将调用结果返回给调用的client。

使用场景

Protobuf语法

基本规范

message SongServerRequest {
    required string song_name = 1;   
} 
enum Foo {       
  FIRST_VALUE = 1;       
  SECOND_VALUE = 2;   
} 

限定修饰符

数据类型

.protoC++JavaPythonGoRubyC#
doubledoubledoublefloatfloat64Floatdouble
floatfloatfloatfloatfloat32Floatfloat
int32int32intintint32Fixnum or Bignumint
int64int64longing/long[3]int64Bignumlong
uint32uint32int[1]int/long[3]uint32Fixnum or Bignumuint
uint64uint64long[1]int/long[3]uint64Bignumulong
sint32int32intintjint32Fixnum or Bignumint
sint64int64longint/long[3]int64Bignumlong
fixed32uint32int[1]intuint32Fixnum or Bignumuint
fixed64uint64long[1]int/long[3]uint64Bignumulong
sfixed32int32intintint32Fixnum or Bignumint
sfixed64int64longint/long[3]int64Bignumlong
boolboolbooleanbooleanboolTrueClass/FalseClassbool
stringstringStringstr/unicode[4]stringString(UTF-8)string
bytesstringByteStringstr[]byteString(ASCII-8BIT)ByteString

gRPC整合SpringCloud & Nacos

其实,第一次了解gRPC,也是在Nacos2.0升级的时候,Nacos2.0版本相比1.X新增了gRPC的通信方式。

端口与主端口的偏移量描述
98481000客户端gRPC请求服务端端口,用于客户端向服务端发起连接和请求
98491001服务端gRPC请求服务端端口,用于服务间同步等

核心依赖

    <properties>
        <java.version>8</java.version>
        <nacos.version>2.2.5.RELEASE</nacos.version>
        <mapstruct.version>1.3.1.Final</mapstruct.version>
        <grpc.starter.version>2.10.1.RELEASE</grpc.starter.version>
        <grpc.client.version>2.10.1.RELEASE</grpc.client.version>
        <lombok.version>1.18.12</lombok.version>
        <fastjson.version>1.2.76</fastjson.version>
        <freemarker.verson>2.3.28</freemarker.verson>
        <nacos.client>2.0.0</nacos.client>
    </properties>
    <dependency>
       <groupId>net.devh</groupId>
       <artifactId>grpc-client-spring-boot-starter</artifactId>
       <version>${grpc.client.version}</version>
    </dependency>
    <dependency>
        <groupId>net.devh</groupId>
        <artifactId>grpc-server-spring-boot-starter</artifactId>
        <version>${grpc.starter.version}</version>
    </dependency>

项目结构

API

<dependencies>
        <dependency>
            <groupId>net.devh</groupId>
            <artifactId>grpc-server-spring-boot-starter</artifactId>
        </dependency>
    </dependencies>
    <build>
        <extensions>
            <extension>
                <groupId>kr.motd.maven</groupId>
                <artifactId>os-maven-plugin</artifactId>
                <version>1.6.2</version>
            </extension>
        </extensions>
        <plugins>
            <plugin>
                <groupId>org.xolstice.maven.plugins</groupId>
                <artifactId>protobuf-maven-plugin</artifactId>
                <version>0.6.1</version>
                <configuration>
                    <protocArtifact>com.google.protobuf:protoc:3.12.0:exe:${os.detected.classifier}</protocArtifact>
                    <pluginId>grpc-java</pluginId>
                    <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.34.1:exe:${os.detected.classifier}</pluginArtifact>
                    <!--设置grpc生成代码到指定路径-->
                    <outputDirectory>${project.basedir}/src/main/java</outputDirectory>
                    <!--生成代码前是否清空目录-->
                    <clearOutputDirectory>false</clearOutputDirectory>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                            <goal>compile-custom</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <!-- 设置多个源文件夹 -->
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>build-helper-maven-plugin</artifactId>
                <version>3.0.0</version>
                <executions>
                    <!-- 添加主源码目录 -->
                    <execution>
                        <id>add-source</id>
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>add-source</goal>
                        </goals>
                        <configuration>
                            <sources>
                                <source>${project.basedir}/src/main/gen</source>
                                <source>${project.basedir}/src/main/java</source>
                            </sources>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
syntax = "proto3";
option java_multiple_files = true;
option java_package = "com.yx.grpc.user";
service UserService {
  rpc queryUser(UserRequest) returns (UserReply) {}
}
message UserRequest {
  int64 id = 2;
}
message UserReply {
  int32 code = 1;
  string msg = 2;
  bool success = 3;
  message Data {
    UserPb userPb = 1;
  }
  Data data = 4;
}
message UserPb {
  int64 id = 1;
  string name = 2;
  string sex = 3;
}

服务端

@GrpcService
public class UserServiceImpl  extends UserServiceGrpc.UserServiceImplBase{
    @Override
    public void queryUser(UserRequest request, StreamObserver&lt;UserReply&gt; responseObserver) {
        UserReply.Builder userReply =  UserReply.newBuilder();
        TblUser tblUser = new TblUser(11L, "syx", "nan");
        userReply.setCode(200).setMsg("SUCCESS").setSuccess(true);
        userReply.setData(UserReply.Data.newBuilder()
                .setUserPb(UserPb.newBuilder()
                        .setId(tblUser.getId())
                .setName(tblUser.getName())
                .setSex(tblUser.getSex())));
        responseObserver.onNext(userReply.build());
        responseObserver.onCompleted();
        super.queryUser(request, responseObserver);
    }
}

客户端

grpc:
  client:
    GLOBAL:
      negotiation-type: plaintext
      enable-keep-alive: true
      keep-alive-without-calls: true
@Configuration
public class MessageConverter {
    @Bean
    public HttpMessageConverters protobufHttpMessageConverter() {
        ProtobufHttpMessageConverter protobufHttpMessageConverter = new ProtobufHttpMessageConverter();
        protobufHttpMessageConverter.setSupportedMediaTypes(Lists.newArrayList(MediaType.APPLICATION_JSON, MediaType.parseMediaType(MediaType.TEXT_PLAIN_VALUE + ";charset=ISO-8859-1")));
        return new HttpMessageConverters(protobufHttpMessageConverter);
    }
}
@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {
    @GrpcClient("yx-grpc-service")
    UserServiceGrpc.UserServiceFutureStub futureStub;
    @RequestMapping(value="/queryUser/{id}")
    public UserReply queryUser(@PathVariable Integer id)  {
        UserReply userReply = null;
        try {
            userReply = futureStub.queryUser(UserRequest.newBuilder().setId(id).build()).get();
            return userReply;
        } catch (Exception e) {
        }
        return userReply;
    }
}

测试

启动服务端和客户端,访问 http://localhost:8002/user/queryUser/1 。

Gitee 地址:gitee.com/renxiaoshi/…

以上就是一文详解gRPC快速整合SpringCloud的详细内容,更多关于gRPC整合SpringCloud的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文