golang之gRPC
相关链接:
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;
}
说明:
- 声明proto文件使用的语法版本,目前是proto2 和proto3, 如果不声明的话, 他会默认使用protocol2,并且语法声明必须是在非空格的第一行
- 声明数据使用message,里面定义参数的类型,名称,索引位置(注意从1开始), 以分号结尾
- 索引的取值范围为:1 ~ 536,870,911
- 索引的值必须保证唯一性
枚举类型:
enum Status {
STATUS_UNSPECIFIED = 0;
STATUS_OK = 1;
STATUS_FAIL = 2;
}
通过enum关键字定义枚举类型,
- 枚举是一个Int32类型
- 第一个枚举类必须从0开始,可以使用XXX_UNSPECIFIED作为占位符
- 不推荐出现负数
字段标签:
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的更多相关文章
- 解决$ go get google.golang.org/grpc上的包被墙的问题
今天get grpc包的时候 $ go get google.golang.org/grpc 发现拉不下来被墙了,在github.com上搜索grpc,clone到工程目录中,运行命令 go inst ...
- grpc(3):使用 golang 开发 grpc 服务端和client
1,关于grpc-go golang 能够能够做grpc的服务端和client. 官网的文档: http://www.grpc.io/docs/quickstart/go.html https://g ...
- window下golang使用gRPC入门案例&net core客户端
gRPC是google开源高性能分布式RPC框架,支持http/2 双向数据流传输及Protobuff,可以在任何环境下运行. 它可以有效地将数据中心内和跨数据中心的服务与可插拔支持进行负载均衡,跟踪 ...
- python golang中grpc 使用示例代码详解
python 1.使用前准备,安装这三个库 pip install grpcio pip install protobuf pip install grpcio_tools 2.建立一个proto文件 ...
- golang 进行grpc调用
参考https://blog.csdn.net/qq_32744005/article/details/105606383 go get google.golang.org/grpc go get - ...
- 【Go】Golang实现gRPC的Proxy的原理
背景 gRPC是Google开始的一个RPC服务框架, 是英文全名为Google Remote Procedure Call的简称. 广泛的应用在有RPC场景的业务系统中,一些架构中将gRPC请求都经 ...
- 使用Golang搭建gRPC服务提供给.NetCore客户端调用
目录 gRPC概述 RPC gRPC又是什么呢 安装 Golang IDE(Goland) Protocol Buffer 下载Protocal Buffer 配置Protocal Buffer编译器 ...
- grpc基础讲解和golang实现grpc通信小案例
grpc简介 gRPC由google开发,是一款语言中立.平台中立.开源的远程过程调用系统 gRPC客户端和服务端可以在多种环境中运行和交互,例如用java写一个服务端,可以用go语言写客户端调用 g ...
- 十分钟学会Golang开发gRPC服务
gRPC是Google发起的一个开源RPC框架,使用HTTP/2传输协议,使用Protocol Buffers编码协议,相比RESTful框架的程序性能提高不少,而且当前流行的编程语言基本都已经支持. ...
- golang下的grpc
facebook的thrift也是开源rpc库,性能高出grpc一倍以上,grpc发展的较晚,期待以后有长足的进步.简单来说thrift = grpc + protobuf gRPC基于HTTP/2标 ...
随机推荐
- 神经网络之卷积篇:详解卷积神经网络示例(Convolutional neural network example)
详解卷积神经网络示例 假设,有一张大小为32×32×3的输入图片,这是一张RGB模式的图片,想做手写体数字识别.32×32×3的RGB图片中含有某个数字,比如7,想识别它是从0-9这10个数字中的哪一 ...
- 开发一个属性名提示友好的Vue组件
这两天开发了一个组件,开发好之后想着先本地npm link 用一用试试,然后在vue3 项目中link了过来,发现VSCODE没有属性提示,鉴于考虑到一个好的组件应该是提示友好的,于是给组件准备加上属 ...
- pycharm批量注释
pycharm批量注释不像是spyder可以鼠标右键选择,pycharm是要用快捷键的,选中要注释的代码,然后快捷键就可以了. 注释代码和取消注释代码的快捷键都一样ctrl + /
- CSS & JS Effect – Loading Button
效果 一个按钮, 点击以后中间出现 loading, 然后旋转. 思路 1. 监听点击, hide text, show loading 2. loading 定位中心 3. loading 是通过 ...
- MVC模式与三层架构
MVC 模式 三层架构 MVC 模式 与 三层架构 的关系
- T2回家(home)题解
T2回家(home) 现在啥也不是了,虽然会了逆元,但是对期望概率题还是一窍不通,赛时相当于只推出了 \(n=1\) 的情况,结果运用到所有情况,理所应当只有20分. 题目描述 小Z是个路痴.有一天小 ...
- ModbusTCP通信协议分析
前言 大家好!我是付工.前面给大家介绍了一系列关于RS485与Modbus的知识. 终于有人把RS485说清楚了 终于有人把Modbus说明白了 通透!终于把ModbusRTU弄明白了 今天跟大家聊聊 ...
- emmc寿命
EMMC器件寿命 1)先确认EMMC器件NAND FLASH类型,是MLC还是TLC,一般是TLC,器件手册标称1000-3000次,取平均值2000次作为评估: 2)在OS下查看EMMC器件当前使用 ...
- 2024年9月中国数据库流行度排行榜:TiDB重回前三,GoldenDB问鼎前五
9月墨天轮数据社区的中国数据库流行度排行榜如约而至.除了冠亚两位,排名第三至第五的数据库产品均经历了位次的变动.榜单之上,稳健的老牌强者.崛起的新兴产品.以及那些在背后默默积蓄力量.准备厚积薄发的竞争 ...
- iOS中异常处理机制使用小结
在iOS开发中经常会由于数组越界,添加数据为空,通信或者文件错误,内存溢出导致程序终端运行而引入异常处理机制.常用的处理方式是try catch机制.不过有几个专业术语需要解释,异常句柄.异常处理域断 ...