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标 ...
随机推荐
- 【YashanDB知识库】YAS-02024 lock wait timeout, wait time 0 milliseconds
[标题]错误码处理 [问题分类]锁等待超时 [关键字]YAS-02024 [问题描述]执行语句时候,因锁等待超时执行语句失败 [问题原因分析]数据库默认锁等待时间为0秒,如果执行语句存在锁等待过长会执 ...
- 动态规划——详解leetcode518 零钱兑换 II
动态规划 零钱兑换 II 参考书目:<程序员代码面试指南:IT名企算法与数据结构题目最优解> 给定不同面额的硬币和一个总金额.写出函数来计算可以凑成总金额的硬币组合数.假设每一种面额的硬币 ...
- ES6中的Set数据结构
Set是ES6新推出的数据结构,Set结构里面的每个元素都是唯一的: 如何创建一个Set? // Set 构造函数接收一个数组进行初始化;如果什么都不传则创建一个空Set; var set = new ...
- sql 查询表数据
SELECT s.Name AS SchemaName, t.Name AS TableName, p.rows AS RowCounts--, --CAST(ROUND((SUM(a.used_pa ...
- C# 开源教程带你轻松掌握数据结构与算法
前言 在项目开发过程中,理解数据结构和算法如同掌握盖房子的秘诀.算法不仅能帮助我们编写高效.优质的代码,还能解决项目中遇到的各种难题. 给大家推荐一个支持C#的开源免费.新手友好的数据结构与算法入门教 ...
- Angular Material 18+ 高级教程 – CDK Table
前言 CDK Table 是 Angular Material 对 <table> 的抽象 (无 styles) 封装. 无 styles 的 table 有什么好封装的呢? CDK Ta ...
- MySQL服务无法启动 服务没有报告任何错误
安装MYSQL后 启动服务 出现错误 在启动MySQL服务时 出现该报错 解决方法: 将原本在MySQL根目录下的my.ini文件移动到bin目录下(my.ini文件参考:这里) 删除根目录下的 ...
- Python条件语句 if
语法: 示例: if elif else:
- ajax发送 put和delete请求
AJAX发送 PUT和DELETE请求(转载) 转自:https://blog.csdn.net/liuyuanjiang109/article/details/78972644 ajax使用r ...
- VM Ware 安装mac OS xxx 系统
1. unlock 文件破解Vm Ware 默认不能安装苹果系统 :https://drive.google.com/file/d/1_AUeYh5JYltqjnuztQh-5UTomAIVBcLZ/ ...