Springboot 集成 GRPC

springboot 集成 GRPC(https://so.csdn.net/so/search?q=GRPC&spm=1001.2101.3001.7020),需要做如下准备

  1. server 端

  2. client 端

  3. proto 文件

  4. 相应的 pom

步骤 1.

创建 java maven 工程,使用 maven 对 Jar 包进行管理,工程目录如下:

9f48239a2ae7403b7923159ffc9653dc.png

步骤 2.

在 pom.xml 中添加相应的依赖,注意依赖的版本,不同的版本生成的代码可能不致,因为是示例 demo,所以我把两个相应的包都放在了最外层的 pom 中,真正的项目中,两都是要分开在不同项目中,做到最小依赖; 引入的 POM 并不是只有这一种方法,也可以单独引入 sprintboot pom,再把 grpc 相关的引入,这些方式都可以,只是这个包里集成了这些,使用起来比较方便,线上项目可根据情况而定。

<dependencies>
        <dependency>
            <groupId>net.devh</groupId>
            <artifactId>grpc-client-spring-boot-starter</artifactId>
            <version>2.10.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>net.devh</groupId>
            <artifactId>grpc-server-spring-boot-starter</artifactId>
            <version>2.10.1.RELEASE</version>
        </dependency>
 
    </dependencies>

步骤 3.

编写 proto 文件,我这里是在 api 中编写,跟 java 直接使用 grpc 一样,也需要注意文件存放的位置。

syntax = "proto3";
 
option java_multiple_files = true;
option java_package = "com.cc.grpc.userInfo";
 
service UserInfoService {
  rpc queryUserInfo(UserInfoReq) returns (UserInfoResponse) {}
  rpc queryUserInfo2(UserInfoReq) returns (UserInfoResponse) {}
  rpc queryUserInfo3(UserStr) returns (UserStr) {}
}
 
message UserStr{
  string str = 1;
}
 
 
message UserInfoReq {
  string name = 1;
  int64 id = 2;
}
message UserInfoResponse {
  int32 code = 1;
  string msg = 2;
  bool success = 3;
  message Data {
    UserInfo userInfo = 1;
  }
  Data data = 4;
}
message UserInfo {
  int64 id = 1;
  string name = 2;
  string sex = 3;
  string addr = 4;
}
c12bd2ceddabe22eee11f447c25b0096.png

## 步骤 4.

在 api 的 pom.xml 中添加编译依赖,这里需要注意版本(protoc:3.12.0),其它的根据这个进行适配,这里没什么变化,java 直接使用 grpc 一致

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

## 步骤 5.

生成 GRPC 代码,使用 ideal,直接在 maven 操作区,点击 compile,如果出现错误,可能需要安装 protobuf 插件,点击 compile 之后,会在相应的目录生成代码,目录的设置是根据## 步骤 4,以及 proto 的设置决定。

ea604e086c012e3bdfea22bdf2c22fef.png 3f590478350e8f65534d9e5bad7caabd.png

步骤 6.

编写 server 端代码 ,需要引入 api 的 pom

e6e2b4fff325710d2d42e25686084dc8.png

步骤 6.1

编写 application.yml ,这里使用 bootstrap.yml 可能不生效,需要注意;

grpc.server.port 指的是 grpc 通信端口

spring.application.name 指的是 server 的项目名称,client 访问时需要指定服务名称

server.port 指的是项目启动的端口,如果不写,默认是 8080,我的 client 与 server 放在同一台机器,会发生冲突

grpc:
  server:
    port: 8888
spring:
  application:
    name: grpc-server
server:
  port: 8890

步骤 6.2.

编写启动类,标准启动类

fd89c0c9d65e3247d664c12a4aecba7c.png

## 步骤 6.3

编写接收处理方法,UserInfoServiceGrpcImpl,用于处理接收 client 端 GRPC 的请求;该类直接继承 UserInfoServiceGrpc.UserInfoServiceImplBase,实现其方法即可。由于是 springboot 项目,类是交由 spring 进行管理,所以需要加上特定注解 @GrpcService

package com.cc.grpc.server.service;
 
import com.cc.grpc.userInfo.*;
import net.devh.boot.grpc.server.service.GrpcService;
 
 
@GrpcService
public class UserInfoServiceGrpcImpl extends UserInfoServiceGrpc.UserInfoServiceImplBase {
    @Override
    public void queryUserInfo(UserInfoReq request, io.grpc.stub.StreamObserver<UserInfoResponse> responseObserver) {
        UserInfoResponse.Builder userInfoResp = UserInfoResponse.newBuilder();
        userInfoResp.setCode(0).setMsg("success").setSuccess(true);
        UserInfo.Builder userInfo = UserInfo.newBuilder();
        userInfo.setId(request.getId());
        userInfo.setName(request.getName());
 
        userInfoResp.setData(UserInfoResponse.Data.newBuilder().setUserInfo(userInfo));
        responseObserver.onNext(userInfoResp.build());
        responseObserver.onCompleted();
    }
 
    @Override
    public void queryUserInfo2(UserInfoReq request, io.grpc.stub.StreamObserver<UserInfoResponse> responseObserver) {
        super.queryUserInfo2(request, responseObserver);
    }
 
    @Override
    public void queryUserInfo3(UserStr request, io.grpc.stub.StreamObserver<UserStr> responseObserver) {
        System.out.println("queryUserInfo3 =======> " + request.getStr());
        responseObserver.onNext(UserStr.newBuilder().setStr("msg : success").build());
        responseObserver.onCompleted();
    }
}

步骤 7

编写 client 端代码,需要引入 api 的 pom

0b77a2ae907a7996ac97d7abba2f71d8.png

## 步骤 7.1

编写 application.yml

grpc.client.grpc-server 需要配置需要建的 server 的信息

address 为必需,由于我这里是 demo,所以写了静态 IP

grpc:
  client:
    grpc-server:
      address: static://localhost:8888
      enableKeepAlive: true
      keepAliveWithoutCalls: true
      negotiationType: plaintext
spring:
  application:
    name: grpc-client
server:
  port: 8891

## 步骤 7.2

编写启动类,也是标准代码

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

步骤 7.3

编写 Controller,这个 controller 就是 rest 请求的 controller,用 url 调用,就是这个

@GrpcClient 中的 value 值,就是 server 端的名称(spring.application.name )

import com.cc.grpc.userInfo.UserInfoServiceGrpc;
import com.cc.grpc.userInfo.UserStr;
import net.devh.boot.grpc.client.inject.GrpcClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
 
import java.util.concurrent.ExecutionException;
 
 
 
@RestController
@RequestMapping("/userInfo")
public class UserInfoController {
 
    @GrpcClient("grpc-server")
    UserInfoServiceGrpc.UserInfoServiceFutureStub userInfoServiceStub;
 
 
    @RequestMapping(value="/query/{id}")
    public String queryUser(@PathVariable Integer id, String str)  {
        String userResp = null;
        try {
 
            userResp = userInfoServiceStub.queryUserInfo3(UserStr.newBuilder().setStr(str).build()).get().getStr();
            return userResp;
        } catch (InterruptedException e) {
 
        } catch (ExecutionException e) {
 
        }
        return userResp;
    }
 
}

测试

返回的值就是 server 中写的数据

f38368cf65b9e6b06ae9ecf1815d1e8c.png f1bc7ad9182491074e3a1cb638e16a16.png 73998a69dcc35bac5d1994dca62cc570.png

作者:llyilo

来源链接:

https://blog.csdn.net/llyilo/article/details/122554816

074e1e595ac9c376956d68f2b25ef889.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值