相关链接:

grpc:

https://grpc.io/docs/languages/go/quickstart/

protobuf:

https://protobuf.dev/programming-guides/proto3/

protobuf语法:

示例:

syntax = "proto3";

// 声明请求参数
message SearchRequest {
string query = 1;
int32 page = 2;
int32 page_size = 3;
}

说明:

  1. 声明proto文件使用的语法版本,目前是proto2 和proto3, 如果不声明的话, 他会默认使用protocol2,并且语法声明必须是在非空格的第一行
  2. 声明数据使用message,里面定义参数的类型,名称,索引位置(注意从1开始), 以分号结尾
  3. 索引的取值范围为:1 ~ 536,870,911
  4. 索引的值必须保证唯一性

枚举类型:

enum Status {
STATUS_UNSPECIFIED = 0;
STATUS_OK = 1;
STATUS_FAIL = 2;
}

通过enum关键字定义枚举类型,

  1. 枚举是一个Int32类型
  2. 第一个枚举类必须从0开始,可以使用XXX_UNSPECIFIED作为占位符
  3. 不推荐出现负数

字段标签:

optional:

  • FileOptions —— 文件级别
  • MessageOptions —— 消息级别
  • FieldOptions —— 字段级别
  • ServiceOptions —— service级别
  • MethodOptions —— method级别

repeated:只有标量,枚举,message类型可以被修饰使用

标识被重复人一次(包括0次),可标识当前修饰类型的变长数组

// repeated
message RepeatedMessage {
repeated SearchRequest requests = 1;
repeated Status status = 2;
repeated int32 number = 3;
}

map:

message MapMessage{
map<string, string> message = 1;
map<string, SearchRequest> request = 2;
}

any:

any类型可以包含一个不需要指定类型的任意的序列化消息。要使用any类型,需要import google/protobuf/any.proto。any类型字段的encode/decode交由各语言的运行时各自实现,例如在Go语言中可以这样读写any类型的字段:

...
import "google/protobuf/any.proto";
...
message AnyMessage {
string message = 1;
google.protobuf.Any details = 2;
}
...

oneof

Protocol buffer compiler安装

【源码】

自定义安装->linux/mac

# 1.卸载老版编译器
apt remove protobuf-compiler
# 2.下载并解压
wget https://github.com/protocolbuffers/protobuf/releases/download/v23.0/protoc-23.0-linux-x86_64.zip
unzip protoc-23.0-linux-x86_64.zip -d protoc-23.0
# 3.设置环境变量
export PATH="$PATH:/usr/local/src/protoc-23.0/bin" # 4.测试
protoc --version
# libprotoc 23.0

window需要到github上下载压缩包到本地并将bin目录下的protoc.exe文件加入环境变量即可

https://github.com/protocolbuffers/protobuf/releases/tag/v23.4

Go 支持

# 1.安装
$ go install google.golang.org/protobuf/cmd/protoc-gen-go@latest $ go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest # 2.添加环境变量
export PATH="$PATH:$(go env GOPATH)/bin"

相关命令:

# 根据.proto文件,生成xxx.pb.go 和 xxx_grpc.pb.go
protoc --go_out=. --go_opt=paths=source_relative \
--go-grpc_out=. --go-grpc_opt=paths=source_relative \
helloworld/helloworld.proto

protoc -I=pb \
--go_out=pb --go_opt=paths=source_relative \
--go-grpc_out=pb --go-grpc_opt=paths=source_relative \
pb/addsrv.proto

Demo示例:
1.初始化项目

mkdir user-service
cd user-service go mod init user-service

mkdir service

2.在Service目录中添加users.proto文件

syntax = "proto3";

package service;

option go_package="user-service/service";

// 请求消息
message UserRequest {
string email = 1;
int32 id = 2;
} // 响应数据
message User {
string id = 1;
string first_name = 2;
string last_name = 3;
int32 age = 4;
} message UserResponse {
User user = 1;
} service Users {
rpc GetUser(UserRequest) returns (UserResponse) {}
}

proto同级目录下生成pb.go 和grpc.pb.go文件

protoc --go_out=. --go-opt=paths=source-relative --go-grpc_out=. --go-grpc_opt=paths=source-relative users.proto

3.新增服务文件 user-service/server/server.go

package main

import (
"context"
"google.golang.org/grpc"
"log"
"net"
"os" users "user-service/service"
) func main() {
addr := os.Getenv("LISTEN_ADDR")
if len(addr) == 0 {
addr = ":5001"
} listen, err := net.Listen("tcp", addr)
if err != nil {
log.Fatal(err)
} s := grpc.NewServer()
registerServices(s) log.Fatal(startServer(s, listen))
} type userService struct {
users.UnimplementedUsersServer
} func (s *userService) GetUser(ctx context.Context, in *users.UserRequest) (*users.UserResponse, error) {
log.Printf("收到数据. 邮件:%s id:%d", in.Email, in.Id) // 返回响应数据
u := users.User{
Id: "user-id",
FirstName: "first name",
LastName: "last name",
Age: 10,
}
return &users.UserResponse{
User: &u,
}, nil
} func registerServices(s *grpc.Server) {
users.RegisterUsersServer(s, &userService{})
} func startServer(s *grpc.Server, l net.Listener) error {
return s.Serve(l)
}

4.新增客户端user-service/client/main.go文件

package main

import (
"context"
"google.golang.org/grpc"
"log"
"os"
users "user-service/service"
) func main() {
if len(os.Args) != 2 {
log.Fatal("缺少grpc服务地址")
} addr := os.Args[1]
// 初始化grpc连接
conn, err := setupGrpcConn(addr)
if err != nil {
log.Fatal(err)
}
defer conn.Close()
// 获取服务客户端实例化
c := getUserServiceClient(conn)
// 调用指定方法
user, err := getUser(c, &users.UserRequest{
Email: "liaotiam@126.com",
Id: 110,
})
if err != nil {
log.Fatal(err)
} log.Printf("响应数据: %v", user)
} func getUser(client users.UsersClient, u *users.UserRequest) (*users.UserResponse, error) {
return client.GetUser(context.Background(), u)
} func getUserServiceClient(conn *grpc.ClientConn) users.UsersClient {
return users.NewUsersClient(conn)
} func setupGrpcConn(addr string) (*grpc.ClientConn, error) {
return grpc.DialContext(
context.Background(),
addr,
grpc.WithInsecure(),
grpc.WithBlock(),
)
}

分别启动服务端与客户端, 查看是否调用成功

golang之gRPC的更多相关文章

  1. 解决$ go get google.golang.org/grpc上的包被墙的问题

    今天get grpc包的时候 $ go get google.golang.org/grpc 发现拉不下来被墙了,在github.com上搜索grpc,clone到工程目录中,运行命令 go inst ...

  2. grpc(3):使用 golang 开发 grpc 服务端和client

    1,关于grpc-go golang 能够能够做grpc的服务端和client. 官网的文档: http://www.grpc.io/docs/quickstart/go.html https://g ...

  3. window下golang使用gRPC入门案例&net core客户端

    gRPC是google开源高性能分布式RPC框架,支持http/2 双向数据流传输及Protobuff,可以在任何环境下运行. 它可以有效地将数据中心内和跨数据中心的服务与可插拔支持进行负载均衡,跟踪 ...

  4. python golang中grpc 使用示例代码详解

    python 1.使用前准备,安装这三个库 pip install grpcio pip install protobuf pip install grpcio_tools 2.建立一个proto文件 ...

  5. golang 进行grpc调用

    参考https://blog.csdn.net/qq_32744005/article/details/105606383 go get google.golang.org/grpc go get - ...

  6. 【Go】Golang实现gRPC的Proxy的原理

    背景 gRPC是Google开始的一个RPC服务框架, 是英文全名为Google Remote Procedure Call的简称. 广泛的应用在有RPC场景的业务系统中,一些架构中将gRPC请求都经 ...

  7. 使用Golang搭建gRPC服务提供给.NetCore客户端调用

    目录 gRPC概述 RPC gRPC又是什么呢 安装 Golang IDE(Goland) Protocol Buffer 下载Protocal Buffer 配置Protocal Buffer编译器 ...

  8. grpc基础讲解和golang实现grpc通信小案例

    grpc简介 gRPC由google开发,是一款语言中立.平台中立.开源的远程过程调用系统 gRPC客户端和服务端可以在多种环境中运行和交互,例如用java写一个服务端,可以用go语言写客户端调用 g ...

  9. 十分钟学会Golang开发gRPC服务

    gRPC是Google发起的一个开源RPC框架,使用HTTP/2传输协议,使用Protocol Buffers编码协议,相比RESTful框架的程序性能提高不少,而且当前流行的编程语言基本都已经支持. ...

  10. golang下的grpc

    facebook的thrift也是开源rpc库,性能高出grpc一倍以上,grpc发展的较晚,期待以后有长足的进步.简单来说thrift = grpc + protobuf gRPC基于HTTP/2标 ...

随机推荐

  1. jstack排查cpu占用高的步骤

    通过jstack排查cpu占用高的问题 1.通过top命令找到cpu占用高的应用程序进程 2.通过top -H -p pid查看该应用中占用CPU高的线程. 3.通过printf "%x\n ...

  2. 如何保证 Redis 的高并发和高可用?讨论redis的单点,高可用,集群

    如何保证 Redis 的高并发和高可用?讨论redis的单点,高可用,集群. 打开GitHub搜索redis,边可以看到,该项目的介绍是这样的: Redis is an in-memory datab ...

  3. 前端解决Long类型精度丢失的问题

    问题 数据库数据: 前端得到的数据: 出现了Long类型的数据出现精度丢失问题! 原因 JS中Long最大值:9007199254740992 JAVA中Long最大值:922337203685477 ...

  4. hexo使用小技巧

    1.在博客中加入图片 使用语法 {% asset_img 1.jpg %} 这样hexo会自动渲染1.jpg.,然后1.jpg的位置需要放在同文件名的文件夹中,比如这篇博客叫hexo使用小技巧,那么这 ...

  5. SQL无法解决排序规则 Chinese_PRC_CI_AS 和 Latin1_General_CI_AS 的冲突

    最近在执行一些跨库关联查询语句的时候提示了 "Cannot resolve the collatior conflict between "Chinese_PRC_Ci As&qu ...

  6. 鸿蒙应用开发:如何与组件库(Glide)衔接?

    ​ Android 发展到现在不仅提供了很多 API,还提供了很多第三方库.这降低了我们开发者的开发难度,提升了开发效率,让应用开发更加的简单高效.众所周知,HarmonyOS 除了提供 16000  ...

  7. QT疑难杂症之如何使用自定义模型实现文件系统模型?类似QFileSystemModel,却比QFileSystemModel更好用

    简介 本文讨论了QT文件系统模型QFileSystemModel的不足之处,并且讨论了改进目标,如何实现自定义文件系统模型,以及进一步改进的空间. 目录 QFileSystemModel的不足之处 改 ...

  8. Unreal Engine4 GPU崩溃或3D设备丢失的解决方案

    起因: Unreal Engine4 在渲染时报错GPU崩溃或3D设备丢失 解决办法: regedit  打开注册表 在以下2个路径下 新建 DWORD(32-bit) Value 命名为  TdrD ...

  9. Serilog文档翻译系列(六) - 可用的接收器、增强器、格式化输出

    01.提供的接收器 Serilog 使用接收器将日志事件以各种格式写入存储.许多接收器由更广泛的 Serilog 社区开发和支持:可以通过在 NuGet 上搜索 serilog 标签找到. 02.增强 ...

  10. @Primary ,@Qualifier ,@Autowired ,@Resource作用与区别

    首先阐述 @Autowired 和 @Resource 的区别 @Resource 是JDK自带的注解 可以按名称注入也可以按类型注入,默认是按名称注入,没有显式指定名称时,在spring容器中匹配与 ...