前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >gRPC基本使用(一)--java与go之间的相互调用

gRPC基本使用(一)--java与go之间的相互调用

作者头像
lpe234
发布2020-07-27 17:27:34
3.7K0
发布2020-07-27 17:27:34
举报
文章被收录于专栏:若是烟花若是烟花

gRPC是一个高性能、开源、通用的RPC框架,面向移动和HTTP/2设计。gRPC 默认使用 protocol buffers,这是 Google 开源的一套成熟的结构数据序列化机制。

Protocol Buffers 是一种轻便高效的结构化数据存储格式,可以用于结构化数据串行化,或者说序列化。它很适合做数据存储或 RPC 数据交换格式。可用于通讯协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式。

简介

本文只是根据gRPC相关资料文档编写的Java Spring Boot 与 Golang 语言相关调用的示例。

详细内容

编写proto文件

使用proto3语法。文件user_provider.proto

需要使用proto文件,来自动生成不同语言的相关接口、类、对象等。

代码语言:javascript
复制
// user service provider

// proto语法版本
syntax = "proto3";

// 可选参数 设置java package
option java_package = "cn.lpe234.grpc.grpcdemo.grpc";

// 定义对外暴露的服务
service UserProvider {

    // 根据用户id获取用户信息的服务(具体服务/函数)
    rpc getByUserId(UserIdRequest) returns (UserVoReplay) {}
}

// 请求
message UserIdRequest {
    uint64 id = 1;          // 用户id 类型为Long
}

// 响应
message UserVoReplay {
    uint64 id = 1;          // 用户id
    string username = 2;    // 用户名称
}

Java Spring Boot 相关

使用Maven作为项目的依赖管理及编译构建工具。当前使用Maven插件,在编译时根据proto文件自动生成服务编写时所需的Class类。

需要将*.proto放置在 xxProject/src/main/proto文件夹下,才能被插件读取到。也就是proto文件夹需要跟javaresources文件夹并列才行(或许可通过修改配置信息修改proto文件存储位置,未做深究~)。

Maven配置

项目精简的pxm.xml配置文件。

代码语言:javascript
复制
<!-- grpc 依赖版本 -->
<properties>
        <grpc.version>1.14.0</grpc.version>
</properties>

<!-- grpc 依赖jar包 -->
<dependencies>
    <dependency>
        <groupId>io.grpc</groupId>
        <artifactId>grpc-netty</artifactId>
        <version>${grpc.version}</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>io.grpc</groupId>
        <artifactId>grpc-protobuf</artifactId>
        <version>${grpc.version}</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>io.grpc</groupId>
        <artifactId>grpc-core</artifactId>
        <version>${grpc.version}</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>io.grpc</groupId>
        <artifactId>grpc-stub</artifactId>
        <version>${grpc.version}</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>net.devh</groupId>
        <artifactId>grpc-server-spring-boot-starter</artifactId>
        <version>2.0.1.RELEASE</version>
    </dependency>
</dependencies>

<!-- grpc build 插件 -->
<build>
    <extensions>
        <extension>
            <groupId>kr.motd.maven</groupId>
            <artifactId>os-maven-plugin</artifactId>
            <version>1.4.1.Final</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.4.0:exe:${os.detected.classifier}</pluginArtifact>
            </configuration>
            <executions>
                <execution>
                    <goals>
                        <goal>compile</goal>
                        <goal>compile-custom</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

理论上,此时执行 mvn -DskipTests=true compile,即可正常生成gRPC相关的Class类。

代码语言:javascript
复制
target
├── generated-sources
│   ├── annotations
│   └── protobuf
│       ├── grpc-java
│       │   └── cn
│       │       └── lpe234
│       │           └── grpc
│       │               └── grpcdemo
│       │                   └── grpc
│       │                       └── UserProviderGrpc.java
│       └── java
│           └── cn
│               └── lpe234
│                   └── grpc
│                       └── grpcdemo
│                           └── grpc
│                               └── UserProviderOuterClass.java
gPPC服务提供编写

使用注解(@net.devh.springboot.autoconfigure.grpc.server.GrpcService)的方式对外提供服务,类似Dubbo服务中的注解方式。

代码语言:javascript
复制
package cn.lpe234.grpc.grpcdemo.grpcprovider;

import cn.lpe234.grpc.grpcdemo.grpc.UserProviderGrpc;
import cn.lpe234.grpc.grpcdemo.grpc.UserProviderOuterClass;
import io.grpc.stub.StreamObserver;
import lombok.extern.slf4j.Slf4j;
import net.devh.springboot.autoconfigure.grpc.server.GrpcService;

/**
 * Grpc服务暴露
 *
 * @author lpe234
 * @datetime 2018/11/24 14:36
 */
@Slf4j
@GrpcService(UserProviderGrpc.class)
public class UserProvider extends UserProviderGrpc.UserProviderImplBase {

    @Override
    public void getByUserId(UserProviderOuterClass.UserIdRequest request, StreamObserver<UserProviderOuterClass.UserVoReplay> responseObserver) {
        // super.getByUserId(request, responseObserver);

        // 获取请求数据
        long userId = request.getId();
        log.debug("grpc request: userId=" + userId);

        // 构造返回数据
        UserProviderOuterClass.UserVoReplay.Builder userVoReplayBuild = UserProviderOuterClass.UserVoReplay.newBuilder();
        userVoReplayBuild.setId(userId);
        userVoReplayBuild.setUsername("hello world");
        UserProviderOuterClass.UserVoReplay userVoReplay = userVoReplayBuild.build();

        // 做出响应
        responseObserver.onNext(userVoReplay);
        responseObserver.onCompleted();
    }
}
gRPC对外服务暴露相关配置

application.xml文件。需配置绑定的地址和监听的端口。

代码语言:javascript
复制
# grpc
grpc:
  server:
    address: 0.0.0.0
    port: 10081
运行

如果一切顺利的话,启动Spring Boot项目。可看到控制台日志输出:

代码语言:javascript
复制
2018-11-24 16:51:16.999  INFO 60266 --- [           main] n.d.s.a.g.server.NettyGrpcServerFactory  : Registered gRPC service: UserProvider, bean: userProvider, class: cn.lpe234.grpc.grpcdemo.grpcprovider.UserProvider
2018-11-24 16:51:17.124  INFO 60266 --- [           main] n.d.s.a.grpc.server.GrpcServerLifecycle  : gRPC Server started, listening on address: 0.0.0.0, port: 10081
2018-11-24 16:51:17.141  INFO 60266 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 10080 (http) with context path ''
2018-11-24 16:51:17.145  INFO 60266 --- [           main] c.l.grpc.grpcdemo.GrpcDemoApplication    : Started GrpcDemoApplication in 2.246 seconds (JVM running for 2.721)

可看到:gRPC Server started, listening on address: 0.0.0.0, port: 10081。说明服务启动正常~

Golang相关

新建项目 grpc-demo并 创建子文件夹 grpc-demo/proto,然后将 最开始的user_provider.proto拷贝进去(由于proto文件定义了RPC调用的所有细节,即所有服务提供或调用均需要保持版本的相同。拷贝似乎有些不妥~)。

生成Golang gRPC调用相关文件

该步骤,需要一些相关依赖~

代码语言:javascript
复制
protoc --go_out=plugins=grpc:. user_provider.proto 

执行成功后,会在该文件夹下生成 user_provider.pb.go 文件。

服务调用

在项目的 src目录下,新建main.go文件。

备注: 地址直接硬编码毕竟是不好的,暂不考虑服务注册发现相关内容,知道这块应该有更好的解决方案即可~

代码语言:javascript
复制
package main

import (
	"google.golang.org/grpc"
	pb "proto"
	"context"
	"log"
)

func main() {
	// java spring boot 暴露的grpc服务接口
	const addr = "127.0.0.1:10081"


	// 连接服务
	conn, err := grpc.Dial(addr, grpc.WithInsecure())
	if err != nil {
		log.Panic(err)
	}

	// 确保连接最终被关闭
	defer conn.Close()

	// 建立远程调用客户端
	client := pb.NewUserProviderClient(conn)
	reply, err := client.GetByUserId(context.Background(), &pb.UserIdRequest{Id: 1})
	if err != nil {
		log.Panic(err)
	}

	// 输出结果
	log.Println("user info:", reply.Id, reply.Username)
}
运行

执行后,可分别在服务调用和提供者日志中看到如下内容:

代码语言:javascript
复制
# Golang
2018/11/24 17:10:12 user info: 1 hello world
代码语言:javascript
复制
# Spring Boot
2018-11-24 17:10:12.123 DEBUG 60266 --- [ault-executor-1] c.l.g.g.grpcprovider.UserProvider        : grpc request: userId=1

完结

至此,已完成了Java提供服务,Golang调用服务。

项目源码:https://github.com/lpe234/grpc-demo

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 简介
  • 详细内容
    • 编写proto文件
      • Java Spring Boot 相关
        • Maven配置
        • gPPC服务提供编写
        • gRPC对外服务暴露相关配置
        • 运行
      • Golang相关
        • 生成Golang gRPC调用相关文件
        • 服务调用
        • 运行
    • 完结
    相关产品与服务
    文件存储
    文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档