第二节 gRPC-Java 快速开始

目录

第一步:创建工程

1、引入依赖

2、引入插件

3、工程结构

第二步:编写helloword.proto

第三步:使用插件生成代码

第四步:将文件拷贝到相应的包中

第五步:使用生成的代码,编写客户端和服务端

1、 服务端代码

2、 客户端代码

3、运行


本小节主要介绍Java中的gRPC快速开始示例。要求jdk版本1.7+.

你可以在github上下载官方提供的案例。
# git地址
git clone -b v1.40.0 https://github.com/grpc/grpc-java

# 本示例位置grpc-java/examples 模块
# helloword包以及proto文件夹中hellowrod.proto

我的gitee代码地址:

# 我的示例
https://gitee.com/work_ldj/gRPC-examples.git
# Hello-gRPC模块(本文使用的示例)
# 该模块基本上参考的官网示例,只不过加了些注释

第一步:创建工程

1、引入依赖

(版本详见源码)

<properties>
        <!--gRPC版本-->
        <gRPC.version>1.40.0</gRPC.version>
        <protobuf.version>3.17.2</protobuf.version>
</properties> 

<dependencies>
        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-netty-shaded</artifactId>
        </dependency>

        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-protobuf</artifactId>
        </dependency>

        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-stub</artifactId>
        </dependency>

        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-testing</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>com.google.protobuf</groupId>
            <artifactId>protobuf-java-util</artifactId>
        </dependency>

        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-core</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.apache.tomcat</groupId>
            <artifactId>annotations-api</artifactId>
            <scope>provided</scope>
        </dependency>

        <!--日志组件-->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
        </dependency>
        <!--测试组件-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </dependency>

    </dependencies>

2、引入插件

 <!--gRPC-examples公用构建组件-->
    <build>
        <extensions>
            <extension>
                <groupId>kr.motd.maven</groupId>
                <artifactId>os-maven-plugin</artifactId>
                <version>1.7.0</version>
            </extension>
        </extensions>

        <plugins>
            <!--
                protobuf 和 grpc 插件
                推荐使用maven插件生成代码
            -->
            <plugin>
                <groupId>org.xolstice.maven.plugins</groupId>
                <artifactId>protobuf-maven-plugin</artifactId>
                <version>0.6.1</version>
                <configuration>
                    <protocArtifact>com.google.protobuf:protoc:${protobuf.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>

            <!--基础组件-->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <version>3.2.0</version>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <inherited>true</inherited>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>utf-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.21.0</version>
                <inherited>true</inherited>
                <configuration>
                    <forkCount>1</forkCount>
                    <reuseForks>false</reuseForks>
                    <skipTests>true</skipTests>
                </configuration>
            </plugin>
        </plugins>

    </build>

3、工程结构

第二步:编写helloword.proto

//申明版本
syntax = "proto3";

option java_multiple_files = true;
//指定生成文件放在哪个包下
option java_package = "top.joylee.example.grpc.hello";

//声明 rpc 服务接口
//关键字: service 声明需要生成的服务接口"类"
service Greeter {
    // 关键字: rpc 声明服务方法,包括方法名、请求消息(请求体)、相应消息(响应体)
    // [注意]: proto使用Pascal命名方式,与驼峰命名的区别就是首字母大写。
    //         不用担心方法调用时的方法名,因为插件会为我们转换过来。
    //         另外推荐使用maven插件的方式生成代码,以免生成与JDK版本冲突的语法
    rpc SayHello(HelloRequest) returns (HelloResponse);
}
//声明请求、响应消息
//关键字: message 声明请求体和响应体
message HelloRequest {
    string name = 1;
}

message HelloResponse {
    string message = 1;
}

【注意】:已经在工程结构中标出,但是还是提一句,此文件要放在src/main/proto文件夹下,proto命名一定不能错。 否则如下图所示:

会因为找不到proto文件而无法生成代码.

第三步:使用插件生成代码

1、重要的事说三遍,.proto文件的位置,要在main/proto文件夹下

2、检查maven插件是否下载成功

3、编译生成代码

3-1 首先执行protobuf:complie,生成消息相关代码

3-2 然后执行protobuf:compile-custome,生成grpc服务相关代码

这两步可以调换执行顺序,但是一定要都执行。

第四步:将文件拷贝到相应的包中

第五步:使用生成的代码,编写客户端和服务端

1、 服务端代码

服务端代码最终要的就是实现.proto文件中service定义的rpc服务。

public class HelloServer {
    private final static Logger log = LoggerFactory.getLogger(HelloServer.class);

    private Server server;

    public static void main(String[] args) throws Exception {
        HelloServer helloServer = new HelloServer();
        helloServer.start();
        helloServer.blockUntilShutdown();
    }

    private void start() throws IOException {
        int port = 50001;
        server = ServerBuilder.forPort(port)
                .addService(new GreeterImpl())
                .build()
                .start();
        log.info("Server started.listening on {}", port);

        // 监听jvm shutdown 事件,并处理
        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
            log.error("**** shutdown g=RPC server since JVM is shutting down");
            try {
                stop();
            } catch (InterruptedException e) {
                log.error("await stop error,interrupted", e);
            }
            log.info("**** server shut down ,good bye ***");
        }));
    }

    private void blockUntilShutdown() throws InterruptedException {
        if (Objects.isNull(server)) {
            return;
        }
        server.awaitTermination();
    }


    private void stop() throws InterruptedException {
        if (Objects.isNull(server)) {
            return;
        }
        server.shutdown().awaitTermination(30, TimeUnit.SECONDS);
    }


    private static class GreeterImpl extends GreeterGrpc.GreeterImplBase {
        @Override
        public void sayHello(HelloRequest request, StreamObserver<HelloResponse> responseObserver) {
            log.info("...receive {} request", request.getName());
            HelloResponse response = HelloResponse.newBuilder().setMessage("Hello \t" + request.getName()).build();
            responseObserver.onNext(response);
            responseObserver.onCompleted();
            log.info("reply {} complete...", request.getName());
        }
    }
}

2、 客户端代码

 客户端,主要展示的就是通过ManagedChannelBuilder创建channel,然后通过channel拿到stub,进行方法调用。

/**
 * Hello gRPC 客户端
 */
public class HelloClient {
    private static final Logger log = LoggerFactory.getLogger(HelloClient.class);
    private final GreeterGrpc.GreeterBlockingStub blockingStub;

    public HelloClient(Channel channel) {
        blockingStub = GreeterGrpc.newBlockingStub(channel);
    }

    public void greet(String name) {
        log.info("*** {} will try to greet ...", name);
        //第一步:设置请求体
        HelloRequest request = HelloRequest
                .newBuilder()
                .setName(name)
                .build();

        //定义response
        HelloResponse response;
        try {
            response = blockingStub.sayHello(request);
        } catch (StatusRuntimeException e) {
            log.error("gRPC failed,{}", e.getMessage(), e);
            return;
        }
        log.info("Great:{}", response.getMessage());
    }

    public static void main(String[] args) throws InterruptedException {
        String user = "Joy";
        String target = "localhost:50001";
        ManagedChannel channel = ManagedChannelBuilder.forTarget(target)
                .usePlaintext()
                .build();
        try {
            for (int i = 1; i <= 5; i++) {
                log.info("...第{}次请求", i);
                HelloClient client = new HelloClient(channel);
                client.greet(user);
                log.info("第{}次请求完成...", i);
                TimeUnit.SECONDS.sleep(2);
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        } finally {
            channel.shutdownNow().awaitTermination(5, TimeUnit.SECONDS);
        }
    }
}

3、运行

启动服务端,然后启动客户端,运行结果如下:

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

joy-lee

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值