惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
Threatpost
aimingoo的专栏
aimingoo的专栏
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
T
Tailwind CSS Blog
J
Java Code Geeks
博客园_首页
Google Online Security Blog
Google Online Security Blog
Hugging Face - Blog
Hugging Face - Blog
C
CXSECURITY Database RSS Feed - CXSecurity.com
I
Intezer
P
Palo Alto Networks Blog
V
Vulnerabilities – Threatpost
雷峰网
雷峰网
O
OpenAI News
SecWiki News
SecWiki News
小众软件
小众软件
酷 壳 – CoolShell
酷 壳 – CoolShell
美团技术团队
N
News | PayPal Newsroom
Project Zero
Project Zero
Forbes - Security
Forbes - Security
IT之家
IT之家
A
Arctic Wolf
WordPress大学
WordPress大学
Jina AI
Jina AI
T
Tor Project blog
博客园 - 三生石上(FineUI控件)
S
Secure Thoughts
Google DeepMind News
Google DeepMind News
Attack and Defense Labs
Attack and Defense Labs
博客园 - 聂微东
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
P
Privacy International News Feed
Cloudbric
Cloudbric
G
GRAHAM CLULEY
博客园 - 叶小钗
H
Hacker News: Front Page
腾讯CDC
量子位
Help Net Security
Help Net Security
人人都是产品经理
人人都是产品经理
C
Cyber Attacks, Cyber Crime and Cyber Security
月光博客
月光博客
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
宝玉的分享
宝玉的分享
爱范儿
爱范儿
L
Lohrmann on Cybersecurity
Hacker News - Newest:
Hacker News - Newest: "LLM"
Recorded Future
Recorded Future
C
CERT Recently Published Vulnerability Notes

Razeen`s Blog

Let's Encrypt 推出 Gen Y 根证书架构:揭示 Web PKI 的五大未来趋势 通过 Wi-Fi 自动备份你的 iPhone 到 Nas 管理培训感悟:从技术视角看管理之路 UPS 一拖多:保护你的 NAS 和 Linux 服务器 从影音中心到 AI 助手:我的50款 Homelab 服务清单 从SSL证书有效期将缩短到47天聊开去 部署一个自己的 Running Page 谈谈特斯拉 Model Y 用车一年的感受和费用分析 弃用 Disqus 评论,使用自建 Waline 使用 Prometheus 和 Grafana 搭建你的证书监控面板 服务器迁移记:一次磁盘换板引发的Linux分区与挂载的学习 改善信息来源, 利用 RSS 高效获取资讯 (RSShub + Reeder5 + WeWe RSS) 多种 Docker 镜像拉取解决方案与实践 App分享 | AppCleaner - Mac上的卸载神器 Azure OpenAI API 申请和使用 如何开通 OneKey 虚拟信用卡,并充值消费 如何拥有一个可长期在国内使用的国外手机号码 分享开通 ChatGPT Plus 过程 如何开通 Depay 虚拟信用卡,并充值消费 如何开通欧易Web3钱包, 交易入账 如何5分钟内1块钱注册 ChatGPT 如何注册美区的 Apple ID (2023年/无需科学上网) NAS折腾记(11): NASTool3.0体验和降级 NAS折腾记(10): Docker版本的NASTool配置 NAS折腾记(9): NASTool与微信交互,微信发送消息远程下载电影【多图】 NAS折腾记(8):群晖安装 NASTool 实现影音半自动化【多图】 内网穿透(2):Tailscale 组网实现内网穿透,操作简单,无成本 内网穿透(1):总结了11中内网穿透的方式,总有一种适合你 NAS折腾记(7):从零开始设置(黑)群晖系统 NAS折腾记(6):黑群晖系统安装好后怎么洗白? NAS折腾记(5):群晖硬盘休眠设置与分析 NAS折腾记(4): 20分钟手把手带你完美安装 DS918+ 黑群晖7.1.1 NAS折腾记(3):NAS 装机 NAS折腾记(2):B360-ITX 双M.2 双2.5G网口 6 SATA主版 开箱 NAS折腾记(1):328元的4盘位Nas机箱开箱 Openwrt + Clash 全局科学上网 Newifi3 刷入 OpenWrt 固件 v21.02 利用 Markdown 画一些流程图、时序图、甘特图等 Homelab(8): 搭建自用 Gitlab 与 Docker 仓库 Nginx Tcp 转发保留客户端真实 IP (PROXY Protocol) Homelab (7):IPSec VPN(基于证书认证)客户端设置 Homelab (6): 基于自签发证书的 IPSec VPN 搭建 Homelab (5): DDNS 动态域名解析 Homelab (4): Linux 服务器基础环境准备 Homelab (3): 整体网络与基础硬件介绍 Go学习笔记(十)老项目迁移 go module 大型灾难记录 Github Actions 初体验之自动化部署 Hexo 博客 记一次 Nginx DNS 缓存导致转发问题 Homelab (2): 电信悦me网关修改桥接模式,路由器拨号 Homelab (1):5分钟上手黑群晖 NAS 终极 Bash 脚本指南 Typora 自动上传图片到七牛云 Ubuntu 20.04 LTS 有线网卡驱动安装 折腾 Ubuntu 20.04 LTS 开发环境 Go学习笔记(九) 计时器的生命周期[译] 利用 git hook 规范你的代码与 commit message 规范 git commit message 与自动化版本控制 超详细 vim 配置 (with MacVim) Golang 中的 RESTful API 最佳实践 折腾服务器(开篇) 我的第一台个人服务器 Newifi3 实现低成本家庭级科学上网 Go学习笔记(八) | 使用 os/exec 执行命令 如何用 Go 调用 Windows API Mac OS 自动根据 WI-FI 名字改变网络位置 关于 Docker 清理 MIME Types 速查表 Go学习笔记(七) | 理解OAuth 2.0并实现一个客户端 我又又又把博客迁移了 Go学习笔记(六) | 使用swaggo自动生成Restful API文档 Go学习笔记(五) | 使用代码片段(snippets)提高编码效率 书单 - 2018 IPFS 初体验,利用 IPFS 托管你的静态网站 记一次 PostgreSQL LIKE 索引优化,联合字段 LIKE 查询优化。 Disqus 添加有趣的 Reactions 的功能 TLS 1.3 详解 (RFC 8446解读) gRPC在Go中的使用(三)gRPC实现TLS加密通信与流模式 gRPC在Go中的使用(二)gRPC实现简单通讯 CentOS 安装 tshark 抓包工具 Go学习笔记(四) | win上使用VSCode搭建Go开发环境 日常 Postgres 数据库点滴记录 简单了解 PKCS 规范 美食篇 | DIY戚风蛋糕(烤箱做蛋糕) Go学习笔记(三) | 怎么写Go基准测试(性能测试) TLS1.3正式更新,为Nginx添加TLS1.3的支持 一次诡异的数据库删除 GitHub Pages自定义域名开启HTTPS 证书透明度是什么?它是怎么工作的? Go学习笔记(二) | 我对 recover 的一点误解 搭建证书透明度(certificate-transparency)日志服务之从入门到放弃 修复远程登陆 Centos 时,出现 UTF-8 Warning HTTPS篇之SSL握手过程详解 Go学习笔记(一) | postgres与golang点点滴滴 AWS 命令行界面(aws-cli)从安装到快速上手 数字证书分类及怎么区分各类数字证书 常用 linux 命令小结(一)文件目录操作 云服务器搭建 hexo 博客,git hooks自动更新 SSH 免密登陆, SSH Config 配置 Golang CGO Mac 交叉编译 Windows 使用 goose 让数据库迁移更加轻松 开始使用Ghost
gRPC在Go中的使用(一)Protocol Buffers语法与相关使用
2018-07-16 · via Razeen`s Blog

在gRPC官网用了一句话来介绍:“一个高性能、开源的通用RPC框架”,同时介绍了其四大特点:

  • 定义简单
  • 支持多种编程语言多种平台
  • 快速启动和缩放
  • 双向流媒体和集成身份验证

gRPC在go中使用系列中,关于其简介与性能我就不多介绍,相信在社区也有很多关于这些的讨论。这里我主要从三个层次来总结我以往在Go中使用gRPC的一些经验,主要分为:

  1. Protocol Buffers语法与相关使用
  2. gRPC实现简单通讯
  3. gRPC服务认证与双向流通讯

*注:下面Protocol Buffers简写protobuf.

这篇我们先介绍protobuf的相关语法、怎么书写.proto文件以及go代码生成。

简介

要熟练的使用GRPC,protobuf的熟练使用必不可少。

gRPC使用protobuf来定义服务。protobuf是由Google开发的一种数据序列化协议,可以把它想象成是XML或JSON格式,但更小,更快更简洁。而且一次定义,可生成多种语言的代码。

定义

首先我们需要编写一些.proto文件,定义我们在程序中需要处理的结构化数据。我们直接从一个实例开始讲起,下面是一个proto文件:

syntax = "proto3";

option go_package = "github.com/razeencheng/demo-go/grpc/demo1/helloworld";

package helloworld;

import "github.com/golang/protobuf/ptypes/any/any.proto";

message HelloWorldRequest {
  string greeting = 1;
  map<string, string> infos  = 2;
}

message HelloWorldResponse {
  string reply = 1;
  repeated google.protobuf.Any details = 2;
}

service HelloWorldService {
  rpc SayHelloWorld(HelloWorldRequest) returns (HelloWorldResponse){}
}

版本

文件的开头syntax="proto3"也就指明版本,主要有proto2proto3,他们在语法上有一定的差异,我这里主要使用的是后者。

包名

第二行,指定生成go文件的包名,可选项,默认使用第三行包名。

第三行,包名。

导包

第四行,类似你写go一样,protobuf也可以导入其他的包。

消息定义

后面message开头的两个结构就是我们需要传递的消息类型。所有的消息类型都是以message开始,然后定义类型名称。结构内字段的定义为字段规则 字段类型 字段名=字段编号

  • 字段规则主要有 singularrepeated。如其中greetingreply的字段规则为singular,允许该消息中出现0个或1个该字段(但不能超过一个),而像details字段允许重复任意次数。其实对应到go里面也就是基本类型和切片类型。
  • 字段类型,下表是proto内类型与go类型的对应表。
.proto TypeNotesGo Type
doublefloat64
floatfloat32
int32使用可变长度编码。 无效编码负数 - 如果您的字段可能具有负值, 请改用sint32。int32
int64使用可变长度编码。 无效编码负数 - 如果您的字段可能具有负值,请改用sint64。int64
uint32使用可变长度编码。uint32
uint64使用可变长度编码。uint64
sint32使用可变长度编码。 带符号的int值。 这些比常规的int32更有效地编码负数。int32
sint64使用可变长度编码。 带符号的int值。 这些比常规的int64更有效地编码负数。int64
fixed32总是四个字节。 如果值通常大于228,则比uint32效率更高。uint32
fixed64总是八个字节。 如果值通常大于256,则会比uint64更高效。uint64
sfixed32总是四个字节。int32
sfixed64总是八个字节。int64
boolbool
string字符串必须始终包含UTF-8编码或7位ASCII文本。string
bytes可能包含任何字节序列。[]byte

看到这里你也许会疑惑,go里面的切片,map,接口等类型我怎么定义呢?别急,下面一一替你解答。

1.map类型,HelloWorldRequestinfos就是一个map类型,它的结构为map<key_type, value_type> map_field = N 但是在使用的时候你需要注意map类型不能repetead

2.切片类型,我们直接定义其规则为repeated就可以了。就像HelloWorldResponse中的details字段一样,它就是一个切片类型。那么你会问了它是什么类型的切片?这就看下面了~

3.接口类型在proto中没有直接实现,但在google/protobuf/any.proto中定义了一个google.protobuf.Any类型,然后结合protobuf/go也算是曲线救国了~

  • 字段编号

    最后的1,2代表的是每个字段在该消息中的唯一标签,在与消息二进制格式中标识这些字段,而且当你的消息在使用的时候该值不能改变。1到15都是用一个字节编码的,通常用于标签那些频繁发生修改的字段。16到2047用两个字节编码,最大的是2^29-1(536,870,911),其中19000-19999为预留的,你也不可使用。

服务定义

如果你要使用RPC(远程过程调用)系统的消息类型,那就需要定义RPC服务接口,protobuf编译器将会根据所选择的不同语言生成服务接口代码及存根。就如:

service HelloWorldService {
  rpc SayHelloWorld(HelloWorldRequest) returns (HelloWorldResponse){}
}

protobuf编译器将产生一个抽象接口HelloWorldService以及一个相应的存根实现。存根将所有的调用指向RpcChannel(SayHelloWorld),它是一个抽象接口,必须在RPC系统中对该接口进行实现。具体如何使用,将在下一篇博客中详细介绍。

生成Go代码

安装protoc

首先要安装protoc,可直接到这里下载二进制安装到 $PATH里面,也可以直接下载源码编译。除此之外,你还需要安装go的proto插件protoc-gen-go

// mac terminal
go get -u github.com/golang/protobuf/{proto,protoc-gen-go}
// win powershell
go get -u github.com/golang/protobuf/proto
go get -u github.com/golang/protobuf/protoc-gen-go

生成go代码

接下来,使用protoc命令即可生成。

### mac terminal
protoc -I ${GOPATH}/src --go_out=plugins=grpc:${GOPATH}/src ${GOPATH}/src/github.com/razeencheng/demo-go/grpc/demo1/helloworld/hello_world.proto
### win powershell
protoc -I $env:GOPATH\src --go_out=plugins=grpc:$env:GOPATH\src $env:GOPATH\src\github.com\razeencheng\demo-go\grpc\demo1\helloworld\hello_world.proto

如上所示 -I指定搜索proto文件的目录,--go_out=plugins=grpc:指定生成go代码的文件夹,后面就是需要生成的proto文件路径。

注意: 如果你使用到了其他包的结构,-I需要将该资源包括在内。

例如我导入了github.com/golang/protobuf/ptypes/any/any.proto 我首先需要

go get -u github.com/golang/protobuf获取该包,然后在使用时资源路径(-I)直接为GOPATH\src

最后生成的hello-world.pb.go文件。内容大概如下图所示,点这里可查看全部。

图中我们可以看到两个message对应生成了两个结构体,同时会生成一些序列化的方法等。

而定义的service则是生成了对应的clientserver接口,那么这到底有什么用?怎么去用呢?下一篇博客将为你详细讲解~

看到这,我们简单的了解一下protobuf语法,如果你想了解更多,点这里看官方文档。