gRPC源码分析(三):从Github文档了解gRPC的项目细节

简介: 从这里可以看出,gRPC虽然是支持多语言,但原生的实现并不多。如果想在一些小众语言里引入gRPC,还是有很大风险的,有兴趣的可以搜索下TiDB在探索rust的gRPC的经验分享。

官方Git总览

我们先看看GRPC这个项目的总览,主要分三种:

  • 基于C实现,包括了 C++, Python, Ruby, Objective-C, PHP, C#
  • 其余语言实现的,最主要是go,java,node
  • proposal,即grpc的RFC,关于实现、讨论的文档汇总

从这里可以看出,gRPC虽然是支持多语言,但原生的实现并不多。如果想在一些小众语言里引入gRPC,还是有很大风险的,有兴趣的可以搜索下TiDB在探索rust的gRPC的经验分享。

gRPC-Go

作为一名Go语言开发者,我自然选择从最熟悉的语言入手。同时,值得注意的是,grpc-go是除了C家族系列以外使用量最大的repo,加上Go语言优秀的可读性,是一个很好的入门gRPC的阅读材料。

进入项目,整个README.md文档也不长。通常情况下,如果你能啃完这个文档及相关链接,你对这个开源项目就已经超过99%的人了。

对Repo的相关注意事项,大家逐行阅读即可,整体比较简单,我简单列举下关键点:

  1. 建议阅读官网文档(恭喜你,上次我们已经读完了官方文档)
  2. 在项目中的引入,建议用go mod
  3. 优先支持3个Go语言最新发布的版本
  4. FAQ中的常见问题,主要关注package下载问题如何开启追踪日志

通读完成,我们再深入看看文档细节,Example这块我们在官网的测试中已经看过,我们的接下来重点是godoc和具体细节的文档。

go doc

DefaultBackoffConfig

注意,这个变量被弃用,被挪到 ConnectParams里了(详情链接)。那这个所谓的连接参数是什么用呢?代码不长,我们选择几个比较重要的内容来阅读下,原链接可以点击这里

// Backoff returns the amount of time to wait before the next retry given the
// number of retries.
// 根据retries返回等待时间,可以认为是一种退避策略
func (bc Exponential) Backoff(retries int) time.Duration {
   
    if retries == 0 {
   
    // 之前没有retries过,就返回BaseDelay
        return bc.Config.BaseDelay
    }
    backoff, max := float64(bc.Config.BaseDelay), float64(bc.Config.MaxDelay)
  // 等待时间不能超过max,等待时间 = BaseDelay * Multiplier的retries次方
  // Multiplier默认1.6,并不是官方http包中的2
    for backoff < max && retries > 0 {
   
        backoff *= bc.Config.Multiplier
        retries--
    }
    if backoff > max {
   
        backoff = max
    }
    // Randomize backoff delays so that if a cluster of requests start at
    // the same time, they won't operate in lockstep.
  // 乘以一个随机因子,数值为(1-Jitter,1+Jitter),默认为(0.8,1.2),防止同一时刻有大量请求发出,引起锁的问题
    backoff *= 1 + bc.Config.Jitter*(grpcrand.Float64()*2-1)
    if backoff < 0 {
   
        return 0
    }
    return time.Duration(backoff)
}

EnableTracing

用来设置是否开启 trace,追踪日志

Code

gRPC的错误码,原代码见链接,我们大概了解其原因即可:

  • OK 正常
  • Canceled 客户端取消
  • Unknown 未知
  • InvalidArgument 未知参数
  • DeadlineExceeded 超时
  • NotFound 未找到资源
  • AlreadyExists 资源已经创建
  • PermissionDenied 权限不足
  • ResourceExhausted 资源耗尽
  • FailedPrecondition 前置条件不满足
  • Aborted 异常退出
  • OutOfRange 超出范围
  • Unimplemented 未实现方法
  • Internal 内部问题
  • Unavailable 不可用状态
  • DataLoss 数据丢失
  • Unauthenticated 未认证

读完上面的内容,发现跟HTTP/1.1的Status Code非常相似。

CallOption

调用在客户端 Invoke 方法中,包括before发送前,after为接收后。

官方提供了几个常用的CallOption,按场景调用。

ClientConn

抽象的客户端连接。

值得注意的是,conns是一个map,所以实际可能有多个tcp连接。

CodeC

定义了Marshal和Unmarshal的接口,在grpc底层实现是proto,详细可见 codec

Compressor

压缩相关的定义

MetaData

元数据,也就是key-value,可以类比到http的header

DialOption

客户端新建连接时的选项,按场景调用。

ServerOption

服务端监听时的选项,按场景调用。

文档

文档链接

benchmark

性能测试,有兴趣的可以细看gRPC是从哪几个维度做RPC性能测试的。

Compression

可用encoding.RegisterCompressor实现自定义的压缩方法。

注意,压缩算法应用于客户端和服务端两侧。

Concurrency

支持并发,从三个角度分析:

  • ClientConn支持多个Goroutine
  • Steams中,SendMsg/RecvMsg可分别在两个Goroutine中运行,但任何一个方法运行在多个Goroutine上是不安全的
  • Server每个客户端的invoke会对应一个Server端的Goroutine

Encoding

类似Compression,可用encoding.RegisterCodec实现自定义的序列化方法。

go mock

用mock生成测试代码,详细可细看。

Authentication

认证的相关选项,包括 TLS/OAuth2/GCE/JWT ,一般用前两者即可。

Metadata

介绍了Metadata的使用,类比于HTTP/1.1的Header。

Keepalive

长连接的参数分为3类:

  • ClientParameters 客户端侧参数,主要用来探活
  • SeverParameters 服务端参数,控制连接时间
  • EnforcementPolicy 服务端加强型参数

log level

四个级别的log level,针对不同场景:

  • Info 用于debug问题
  • Warning 排查非关键性的问题
  • Error gRPC调用出现无法返回到客户端的问题
  • Fatal 导致程序无法恢复的致命问题

proxy

使用默认的HTTP或HTTPS代理。

rpc error

结合官方提供的错误码,用 status.New 或者 status.Error 创建错误。

server reflection

服务端方法映射,跟着教程走即可。

值得一提的是,采用c++中的grpc_cli模块,可以查看指定端口暴露出来的服务详情。

versioning

版本演进,一般情况下每6周一个小版本,紧急修复会打补丁号。

目录
相关文章
|
3月前
|
开发工具 git 开发者
2024最简七步完成 将本地项目提交到github仓库方法
该文章提供了一个简洁的七步教程,指导用户如何将本地项目提交到GitHub仓库。
2024最简七步完成 将本地项目提交到github仓库方法
|
1月前
|
编解码 Oracle Java
java9到java17的新特性学习--github新项目
本文宣布了一个名为"JavaLearnNote"的新GitHub项目,该项目旨在帮助Java开发者深入理解和掌握从Java 9到Java 17的每个版本的关键新特性,并通过实战演示、社区支持和持续更新来促进学习。
76 3
|
3月前
|
JavaScript 搜索推荐 资源调度
使用VitePress静态网站生成器创建组件库文档网站并部署到GitHub
本文详细介绍了如何使用 Vue3、TypeScript 和 Vite 开发并发布一个名为 Vue Amazing UI 的组件库至 npm。文章首先引导读者安装配置 VitePress,创建文档网站,并编写组件库文档。接着,通过一系列配置实现网站主题定制、全局样式设置以及 Algolia 搜索功能集成。最后,文章提供了自动化脚本,帮助开发者一键打包部署静态网站至 GitHub,并发布组件库到 npm。通过这些步骤,读者可以轻松搭建并维护一个美观且功能齐全的组件库文档网站。
使用VitePress静态网站生成器创建组件库文档网站并部署到GitHub
|
3月前
|
资源调度 搜索推荐 Shell
使用VitePress静态网站生成器创建组件库文档网站并部署到GitHub
本文介绍了如何使用 Vue3、TypeScript 和 Vite 开发组件库并将其发布到 npm。文章详细描述了安装依赖、配置项目、创建文档网站以及编写组件文档的步骤。通过使用 VitePress,可以轻松搭建组件库的文档站点,并实现 Algolia 搜索功能。此外,还提供了自动化脚本用于部署静态网站至 GitHub 以及发布组件库到 npm。最后,展示了完整的目录结构和网站效果。
使用VitePress静态网站生成器创建组件库文档网站并部署到GitHub
|
3月前
|
Rust 前端开发 JavaScript
Github 2024-05-20 开源项目周报 Top15
根据Github Trendings的统计,2024年5月20日当周共有15个项目上榜。按开发语言分类,项目数量如下:Python项目5个,TypeScript项目3个,C++项目2个,Jupyter Notebook项目2个,C、Go、Rust和C#项目各1个。介绍了多个值得关注的项目,包括ChatGPT桌面应用程序、Fooocus图像生成软件、Jellyfin媒体系统等。这些项目涵盖了多种功能和技术领域,值得关注和研究。
60 3
|
3月前
|
SQL JavaScript 前端开发
Github 2024-08-05 开源项目周报 Top15
根据 Github Trendings 的统计,本周(2024年8月5日统计)共有15个项目上榜。以下是根据开发语言汇总的项目数量: - Go 项目:4个 - JavaScript 项目:3个 - Python 项目:3个 - Java 项目:2个 - TypeScript 项目:2个 - C 项目:1个 - Shell 项目:1个 - Dockerfile 项目:1个 - 非开发语言项目:1个
111 2
|
3月前
|
人工智能 Rust JavaScript
Github 2024-08-26 开源项目周报Top15
根据Github Trendings的统计,本周共有15个项目上榜。以下是按开发语言汇总的项目数量:Python项目8个,TypeScript、C++ 和 Rust 项目各2个,Jupyter Notebook、Shell、Swift 和 Dart 项目各1个。其中,RustDesk 是一款用 Rust 编写的开源远程桌面软件,可作为 TeamViewer 的替代品;Whisper 是一个通用的语音识别模型,基于大规模音频数据集训练而成;初学者的生成式人工智能(第2版)则是由微软提供的18门课程,教授构建生成式AI应用所需的知识。
126 1
|
3月前
|
Rust Dart 前端开发
Github 2024-08-19 开源项目周报Top15
根据Github Trendings的统计,本周(2024年8月19日统计)共有15个项目上榜。按开发语言分类,上榜项目数量如下:Python项目最多,有7项;其次是JavaScript和TypeScript,各有3项;Dart有2项;HTML、PowerShell、Clojure和C++各1项。此外,还介绍了多个热门项目,包括Bootstrap 5、RustDesk、ComfyUI、易采集、Penpot等,涵盖了Web开发、远程桌面、自动化测试、设计工具等多个领域。
110 1
|
3月前
|
JavaScript 前端开发 Go
Github 2024-08-12 开源项目周报 Top14
本周Github Trendings共有14个项目上榜,按开发语言汇总如下:Python项目7个,TypeScript项目5个,C项目2个,JavaScript项目2个,Go和Batchfile项目各1个。其中亮点包括开发者职业成长指南、Windows激活工具、ComfyUI图形界面、AFFiNE知识库、易采集可视化爬虫等项目,涵盖多种实用工具和开源平台。
125 1
|
3月前
|
存储 JavaScript 前端开发
Github 2024-07-29 开源项目周报Top15
根据 Github Trendings 的统计,本周(2024年7月29日统计)共有15个项目上榜。按开发语言分类,项目数量如下:Python、Java、HTML 和 C 项目各有2项;TypeScript、JavaScript、Vue 和 Go 各有1项;另有1项非特定语言项目、1项 Dart 项目、1项 C++ 项目、1项 Rust 项目及1项 Jupyter Notebook 项目。这些项目涵盖了多种领域,如API开发、照片管理、PDF处理、AI技术等。
62 1