Java 实现Grpc服务通信

本文介绍了如何使用gRPC和Protocol Buffers进行服务通信。首先,通过.proto文件定义服务和消息类型,然后使用Maven插件生成Java代码。接着展示了服务端和客户端的实现,包括业务逻辑和配置。最后,给出了测试的简单结果,演示了如何在实际项目中应用gRPC。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

GRPC实现服务通信

grpc相关特性:

gRPC 是一种现代开源高性能远程过程调用 (RPC) 框架,可以在任何环境中运行。它可以通过对负载平衡、跟踪、健康检查和身份验证的可插拔支持,有效地连接数据中心内和数据中心之间的服务。它还适用于分布式计算的最后一英里,将设备、移动应用程序和浏览器连接到后端服务。特性如下:
1.简单的服务定义
使用 Protocol Buffers 定义您的服务,这是一种强大的二进制序列化工具集和语言。
2.快速启动并扩展
使用一行代码安装运行时和开发环境,并使用框架扩展到每秒数百万次 RPC。
3.跨语言和平台工作
以各种语言和平台为您的服务自动生成惯用的客户端和服务器存根。
4.双向流和集成身份验证
双向流和完全集成的可插拔身份验证与基于 HTTP/2 的传输。
grpc与protobuf是相辅相成的,想要使用grpc,必须先学会使用protobuf,grpc跨语言和平台工作的能力是protobuf赋予的。但是利用传统的protobuf的生成器,反而不能生成grpc的代码,java语言有专门的grpc的代码生成的maven插件。如果你想了解protobuf,可以参考:https://www.jianshu.com/p/a24c88c0526a

1、定义proto文件

在main文件夹下新建proto文件夹,在proto文件夹下新建.proto文件
在这里插入图片描述

syntax = "proto3";

package com.redic.Test;//编译后包的位置

option java_multiple_files = true; //拆分成多个文件

//请求对象
message inpushRequest{
  string name = 1;
  string msg = 2;
  int32 i = 3;
}

//返回对象
message ReturnResponse{
  Result result = 1;
  string msg = 2;
}

enum Result {
  SUCCESS = 0;
  FAIL = 1;
}

//接口
service TestService{
  //方法
  rpc getInpushService(inpushRequest) returns (ReturnResponse);
}

2、整合Grpc所需要的Maven插件

        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-netty</artifactId>
            <version>1.17.1</version>
            <exclusions>
                <exclusion>
                    <artifactId>netty-common</artifactId>
                    <groupId>io.netty</groupId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-protobuf</artifactId>
            <version>1.17.1</version>
        </dependency>
        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-stub</artifactId>
            <version>1.17.1</version>
        </dependency>
        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-common</artifactId>
            <version>4.1.14.Final</version>
        </dependency>

 <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.5.0</version>
                <configuration>
                    <protocArtifact>com.google.protobuf:protoc:3.3.0:exe:${os.detected.classifier}</protocArtifact>
                    <pluginId>grpc-java</pluginId>
                    <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.17.1:exe:${os.detected.classifier}</pluginArtifact>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                            <goal>compile-custom</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

注:记住在你的各个服务一定要公共模块

<dependency>
            <groupId>com.redic</groupId>
            <artifactId>cloud-api-common</artifactId>
            <version>${project.version}</version>
        </dependency>

3、通过插件生成接口代码

在这里插入图片描述
编译好后,就会自动在target中出现生成好的代码文件,在.proto定义的 package com.redic.Test 文件夹下面
在这里插入图片描述

4、服务端业务实现代码

4.1 yml文件配置服务端

grpc:
  server:
    port: 50001

4.1 业务代码

@GrpcService
@Slf4j
public class TestService extends TestServiceGrpc.TestServiceImplBase {

    /**
     * server实现代码
     * @param request
     * @param responseObserver
     */
    @Override
    public void getInpushService(inpushRequest request, StreamObserver<ReturnResponse> responseObserver) {
        ReturnResponse response = null;
        try {
            log.info("name:"+request.getName());
            log.info("msg:"+request.getMsg());
            response = ReturnResponse.newBuilder()
                    .setMsg("测试成功了!")
                    .setResult(Result.SUCCESS)
                    .build();
        } catch (Exception e) {
            e.printStackTrace();
            response = ReturnResponse.newBuilder()
                    .setResult(Result.FAIL)
                    .build();
        } finally {
            responseObserver.onNext(response);
            responseObserver.onCompleted();
        }
    }
}

5、客户端业务实现代码

5.1 yml文件配置客户端

grpc:
  client:
    test-grpc-server:
      address: static://localhost:50001
        #      enableKeepAlive: true
        #      keepAliveWithoutCalls: true
        negotiationType: plaintext

5.1 实现客户端

@Slf4j
@Component
public class TestClient {

    @GrpcClient("test-grpc-server")
    private TestServiceGrpc.TestServiceBlockingStub testServiceBlockingStub;


    public void inpush(){
        try {
            inpushRequest request = inpushRequest.newBuilder()
                    .setName("向大阳")
                    .setMsg("测试了一下")
                    .build();
            ReturnResponse response = testServiceBlockingStub.withDeadlineAfter(5, TimeUnit.SECONDS).getInpushService(request);
            if(response.getResult().getNumber() == 1){
                log.info(response.getMsg());
            }else {
                log.info(response.getMsg());
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new CustomException(e.getMessage());
        }
    }
}

6、测试

测试代码就不写了,只展示测试结果:

服务端:
在这里插入图片描述客户端:
在这里插入图片描述到这里,就算是成功了,自己动手试试吧

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值