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标 ...
随机推荐
- win10自动更新导致的任务栏假死,右键单击任务栏延迟菜单延迟出现
系统是win10企业版,前天晚上回家之前,电脑还是好好的,然后前天早上跑过来以后,发现电脑自动重启了,我还以为是办公室停电了之类的(现在想了一下愚蠢,停电不会自动开机),没想到是自动更新 然后我发现, ...
- 【JS设计模式笔记】给我一张名片-工厂方法模式(创建型)
广告展现 例如,关于计算机培训广告资源需要投放,一批是Java的用绿色字体,一批是PHP的,用黄色字体,红色背景. // 创建Java学科类 var Java = function (content) ...
- ArgoWorkflow教程(四)---Workflow & 日志归档
上一篇我们分析了argo-workflow 中的 artifact,包括 artifact-repository 配置以及 Workflow 中如何使用 artifact.本篇主要分析流水线 GC 以 ...
- 前端项目通过 Nginx 发布至 Linux,并通过 rewrite 配置访问后端接口
〇.前言 本文通过将 arco 框架的前端项目,部署至 CentOS 7,并访问同服务器的 WebAPI 接口,来简单演示一下,如何将前端项目发布至 Linux 系统. 关于 ASP.NET WebA ...
- CF228E 题解
CF228E 题解 题目简述 给定一个 \(n\) 个点,\(m\) 条边的无向图,每条边都为 \(0\) 或 \(1\),可以进行若干次操作,与此点相连的所有点权值取反,求一种方案使得所有边都变为 ...
- Linux工具:Winscp显示隐藏的文件
事件起因: 需要用Winscp上传文件到服务器,然后发现文件被隐藏了 解决办法: Winscp软件的快捷键 : Ctrl + Alt + HWindscp软件的设置方法: 菜单栏 选项 -> 面 ...
- UEFI原理与编程(四)(dec dsc inf文件)
1 .inf文件 以下面 .inf文件为例 [Defines] # 块用于定义模块的属性和其他变量,块内定义的变量可被其他块引用 INF_VERSION = 0x00010006 #INF 标准的版本 ...
- Java实用小工具系列2---使用StopWatch统计多个任务耗时分布
在Java中经常需要统计程序的使用时间,如果只是一个时间段统计比较好处理,可以直接使用System.currentTimeMillis().但如果一个程序中包含多个步骤,需要统计每个步骤耗时,并且需要 ...
- Android复习(三)清单文件中的元素——>grant-uri-permission、instrumentation、intent-filter、manifest、meta-data
<grant-uri-permission> 语法: <grant-uri-permission android:path="string" android:pa ...
- harbor磁盘爆满,执行垃圾回收清理镜像
1.在使用Jenkins发版操作时发现,推送私有仓库harbor报错: received unexpected HTTP status: 500 Internal Server Error 2.想要登 ...