乐趣区

关于golang:Go的高效开发套路

A. 背景

以后在公司进行 Go 服务端研发工作时,发现短少 Go 开发的最佳实际,而导致以下景象

  1. 用 Go 开发时会比拟迷茫,不知如何下手,怎么发展工作比拟高效。
  2. 反复造轮子比较严重。
  3. 我的项目的代码品质参差不齐,导致交付的产品质量参差不齐。
  4. 产品运行黑盒,可观测性差,能跑就行。
  5. 代码实现考验研发人员程度,但顶尖的毕竟是多数,往往比拟差,而且顶尖也说不准会犯错。
  6. 一个人负责整个性能开发,一旦人员到职,代码保护就会难上艰巨。

而我在进行产品研发工作时,意识到后续产品的性能会更加简单,不重视这些问题的话,后续恐怕呈现代码更加难以保护、产品性能难以改变、用户需要无奈疾速满足的多米诺效应。
为了尽早禁止该景象的产生,摸索一套能够在 Go 畛域进行最佳实际的范式,从而达到以下成果:

  1. 代码易保护,起码有两个人熟知代码实现目标,也容易进行代码迭代更新。
  2. 代码设计正当,防止过于奇葩、适度以及不全面的实现。
  3. 产品质量保障,交付产品可观测性强、Bug 率低。
  4. 升高反复造轮子景象,专一于业务逻辑开发,晋升研发效率。

故此从研发效力方面钻研解法,摸索从集体开发行为到团队合作上的晋升,最终在研发代码质控以及研发框架两个方面去实际各种办法,最终总结出以后的高效开发的模式,并继续优化积淀中,心愿通过实际验证该模式的成果,推广至所有应用 Go 进行服务端开发的场景实现,进步整个团队研发效力。

B. 模式简介

本模式有三个局部组成,别离为标准化研发标准、契约合作以及对立的开发框架。

  • 标准化研发标准旨在研发人员在进行代码开发时可能从代码编程格调、Git 提交标准、Review 机制能达成共识契约并严格遵守,为产品的品质负责。
  • 契约合作旨在研发人员与内部须要调用其服务的合作伙伴,造成以契约为准,单方工作发展不相互强依赖具体实现的合作模式,升高单方沟通老本。
  • 对立的开发框架旨在束缚研发人员应用对立的框架开发,积淀各种场景实现用于优化并演进框架,达到开发时可疾速复用场景、继续迭代优化各场景实现以及为将来更多场景做松软的积攒。

C. 模式实际 -Go 服务端开发

以后在理论开发业务中都有相应的实际

标准化研发标准

代码编程标准

在接手一些组件的开发时,看到代码的实现上存在格调迥异,浏览了解上比拟艰难,所以定下束缚格调的编程标准,能够晋升代码的可浏览性,代码的易维护性。
在摸索 Go 代码编程标准中,业界有 EffectiveGo 和 UberGoGuide 等比拟出名的编程标准。

  • EffectiveGo 作为 Go 官网出品的编程标准,简直所有应用 Go 语言开发的程序员都有看过并从中获益,普适性高。
  • UberGoGuide 是业界中应用 Go 语言开发的佼佼者,其开源了很多高质量的开源软件,比方 Zap;它所开源的编程标准也是在 EffectiveGo 以及其余编程标准作为根底下来扩大。

从综合思考上,Uber 有中文翻译版上手速度快,且其公司依照标准开源的软件品质实现也侧面证实了该标准的优越性,所以抉择 UberGoGuide 作为领导编程标准,但并不作为惟一参考规范,也思考能够依据理论运行的最佳实际作为相应变动。

Git 提交标准

在团队合作开发组件时,查看到 Git 的提交信息很随便,仅仅简略形容几句,但齐全不晓得理论做了什么。在回溯代码问题时,不晓得这个提交做了什么,对代码保护上造成肯定妨碍。预计参考业界优良对立标准 Conventional Commit 1.0 进行束缚。

Conventional Commit 1.0,是一种标准提交信息的轻量级规约,它提供了一些易于了解的规定用于领导咱们如何编写 commit 信息,因而这也很容易被机器进行解读,联合 SemVer 版本标准,能够很容易通过工具既能自动化治理版本号,也进一步束缚开发人员对提交信息的严谨性,毕竟如果乱打 commit 信息会间接影响到版本的制订。

因而在实践中上,严格遵守 Conventional Commit 1.0 来进行提交信息的规定,对于提交信息不明确者也能够回绝其代码提交。

Review 机制

在原先的团队单干模式中,大部分是各自开发相应的模块并间接提交到 Master 分支,而后就公布了,这样的做法尽管速度很快但交付品质却很堪忧,毕竟它很考验研发人员的综合程度,但毕竟不是人人都是神,所以它无奈防止到缺点的数量增长,不仅对整体代码品质堪忧,甚至对交付产品的品质也无奈保障,更甚会影响到整个团队的口碑。为了解决这些问题,引入 CodeReview 机制来管制代码合并到代码交付的过程,从而管控整个代码品质。

CodeView 机制参加的人员角色有代码提交者(Commiter)以及代码审核者(Reviewer),代码提交者每次提交代码后,均须要由代码审核者进行代码,审核通过后能力合并代码进主分支,从而达到可公布的可能性。

这样的机制履行下,须要能够做到以下方面成果:

  • 使研发人员在每次提交中,有其余视角去验证代码实现计划、解决思路,保障肯定的客观性。
  • 负责 Reviewr 角色的人员,须要在过程做到辨认 bugs、是否有逻辑问题还有是否有笼罩全边缘场景,这样能够保障实现的思路足够全面。

其益处列举如下:

  • 常识共享:团队外部在进行 Review 就能晓得代码的实现、应用的设计等进行共享,有利于团队代码程度的进步。
  • 能够更早的发现 bug:防止在性能推出后才发现 Bug,做到及时止损。
  • 确保合规性:程序员的背景不同导致各自的代码格调不同,但通过标准规范束缚我的项目代码的合规性。
  • 加强安全性:当有平安技术背景的业余人员加入到 review 中时,安全性的等级是十分高的。
  • 加强团队单干意识:当团队成员一起去解决一个问题,这样有利于晋升他们各自的 OwnerShip 思维以及团队的归属感。

以后也须要做到以下约定:

  1. Reviewr 和 Commiter 在一次提交上,严格意义上不能为同一个人。
  2. Comment 时须要是善意的就事论事,单方均须要以案例和谨严的逻辑斟酌去进行探讨,而且只有 Reviewr 批准后能力终止 Comment。
  3. 提交代码前须要本身曾经通过编译以及测试。
  4. 一次提交尽量做到外围代码不超过 400 行的。
  5. 一次 Review 尽量低于 1 小时。
  6. 须要知会到 Reviewr 清晰晓得这次提交的实现目标,最终冀望是什么。
  7. 如果胆怯提交的代码写的不好,那就将代码实现达到本身认可的水平先。
  8. 单次提交如果代码量过大或逻辑简单能够设置两个以上的 Reviewer 进行 Review。
  9. Reviewer 和 Commiter 存在连带责任,Commiter 提交的代码在生产呈现问题并呈现价值损失时,Reviewer 也须要承当主要责任。
  10. Review 机制很容易会被忽视并绕过,但其结果有时候是很惨痛的,所以须要团队人员统一认可并恪守,能力做得好。

契约合作

PB 文件既契约模式

在开发人员进行 API 开发到实现后,往往都须要提供文档给他人去调用,这样的做法有以下毛病:

  1. 接口文档交付迟缓,接口需求方须要期待接口文档给出能力进行开发,这样对于需求方来说会更加开发危险会减少。
  2. 接口更新不及时,当开发人员在更改 API 时,90% 的概率会遗记更新文档,导致第三方在调用时呈现很多情况须要沟通,这样减少单方的沟通老本,升高了单方的开发效率。

为了解决以上问题,推广 Protobuf 文件(以下简称 PB 文件)既契约的模式。
该模式遵循 Google API 指南,实现了对应通信协议反对,并且恪守了 gRPC API 应用 HTTP 映射性能进行 JSON/HTTP 的反对。因而能够做到通过定义 PB 文件即可定义出 REST 和 RPC API,通过相似 GoogleAPI 的仓库形式进行 API Schema 的治理。

再者联合丰盛的 Protoc 插件能够自动化 Swagger 文档或生成不同语言类型的代码,如下:

  • Go HTTP API:通过 protoc-gen-go-http 插件进行生成 Go 版的 Http 相干代码
  • Go gRPC API:通过 protoc-gen-go-grpc 插件生成 Go 版的 gPRC 相干代码
  • Swagger 文档:通过 protoc-gen-openapiv2 插件生成

因而,研发人员通过 PB 文件即可清晰晓得 API 的定义,参数、返回内容等 bin 并能根据 PB 文件生成相应的代码(Server 和 Client)就可进行各自的开发,也能够间接生成 Swagger 文档来查看应用,极大的升高了沟通的老本。

该模式也须要恪守以下规定:

  1. 新契约变更须要告诉到对方
  2. 已运行一段时间的旧契约遇到 BreakChange 需要,应思考新起契约,不应在原有根底改变。
  3. 新契约定制时需先通过需求方 Review 后,再持续开发,防止返工,也保障需要实现准确性。
  4. 契约尽量以清晰简洁明了的构造体定义为优先,对于非凡需要再应用 Map、PBValue 等。

对立的开发框架

对于框架的入门应用有另外一篇文章进行领导

开发框架选型

在过往的编程教训中,对一个框架的积攒积淀有助于晋升整体的开发效力,毕竟前人栽树后人乘凉,前人曾经摸清楚框架的应用,就有足够的信念领导前人以此进行开发、优化框架代码以及建设起整套的周边生态,能够有余力应酬将来的简单业务场景。

因以后团队人力无限仅 4 人,即便有心也有力去做到自研框架这种须要大量脑力心力且须要积攒积淀的工作,于是放弃自研框架,抉择借力开源产品。

在从框架选型上,从以后团队需要场景考量,团队须要的是一套能够束缚实现标准、生态欠缺、用户自主性强、后盾性能要求不高以及反对微服务化的框架。

在 Go 这边选型中预选了 GVA、Gin 和 Kratos 作为比对并进行实际,总结 GVA、Gin 以及 Kratos 三者比对如下

  1. Gin, 为一个根底轻量级高性能的 Web 框架,实现场景案例较多,但代码实现无约束标准须要靠开发者本人摸索,普适性较强。
  2. GVA,是一个前后端配套的框架,次要解决是疾速开发 web 利用,但框架代码实现上并没有很好的理论指导以及标准束缚,整体应用后的代码品质较差难保护,应答简单业务需要能力差,最让人诟病的是滥用的公共变量。
  3. Kratos,bilibli 业务验证出品,配套健全的微服务框架,设计上遵循整洁架构以及 DDD 思维,实现的模块耦合度低,用户自主性强,应答简单的业务需要能力强,但总体设计理念上偏向于标准规范定制,整体性能方面中上,需本人扩大模块实现更高性能。
框架 类型 协定反对 扩展性 领导力 易保护 生态 性能 框架代码品质 GitHubStar 数
GVA Web 前后端框架 HTTP 不欠缺 11.8k
Gin 后端 HTTP 框架 HTTP 欠缺 56.1k
Kratos 微服务框架 HTTP/gRPC 欠缺 16.9k

最终采纳 Kratos 作为对立的开发框架,具体决策依据如下

  1. 多协定:默认反对 HTTP/gRPC,可自主依照标准定制扩大,反对采纳 gin 来实现 transport 外围。
  2. API 契约理念:反对 PB 文件定义,可生成服务端、客户端代码以及 Swagger 文档,并提供在线实时文档性能。
  3. DDD 思维分层开发:领导开发人员进行开发时,能依照畛域驱动的形式进行开发,让性能更加聚焦,实现更加精炼,且耦合度低,比方将 ClickHouse 替换为 SLS 时只须要改变基础设施层实现即可。
  4. 框架结构模块化清晰:简直涵盖微服务框架开发中所波及的模块,比方认证、注册、自监控等,并这些模块均可自定义实现,适配性强。
  5. 高扩展性的中间件设计:极强扩展性的中间件设计,灵便扩大各种业务所需中间件模块。
  6. 框架代码品质:总体代码品质下层,模块依赖解耦明显,用户浏览上手容易,自主定制优化可行。
  7. 性能方面:当初业务临时或未来 1~2 年均以 Web 后端利用以及微服务为主,所以性能要求方面不刻薄,且如需高性能时也可自主实现扩大模块实现。

开发框架积淀

以后组内已在 Kratos 框架有肯定的积攒,为后续进步后端开发进步很好的根底,具体如下:

  1. Layout 疾速开发:依附 Kratos 的 Layout 能力,定制合乎本身的 Layout 模板,在后续开发中能够疾速应用,以后 Layout 实现上已蕴含各层的写法模板、Prom 指标集成、Opentelemetry 全链路集成、本地缓存实现等。
  2. 自定义 API 文档信息的写法领导:已充沛踩坑如何丰盛 API 文档,对于任何自定义信息需要均能满足。
  3. 疾速应用 Kratos 开发的指南:配合 Layout,助力疾速上手框架,疾速进行业务开发。
  4. 通过在线 API 文档生成前端 SDK:通过 Swagger-gen 疾速生成前端 SDK,前端无需手写 SDK,可保护强。
    之后也会积淀更多的场景到框架和文档中,丰盛框架的应用场景,以助力开发提效。

实际成果

以后将该模式在外部我的项目中实际,有以下成果晋升

  1. Bug 状况:在通过次实际后代码级别的 bug 数量从我的项目开始到当初低于 10 个,需要级别 Bug 数量低于 15 个。
  2. 前后端合作效率:前后端以后沟通协商根本只在需要协商、协定定义和理论联调阶段进行协商,整体交付性能速度均低于 2 个星期。
  3. 个性实现速度:后端服务交付实现个性,均低于 5 天一周期,我的项目停顿卡点不在后端实现上。
  4. 团队单干气氛:review 机制的退出,让团队成员更加富裕凝聚力以及更违心做常识分享,晋升了团队人员整体能力。
  5. 交付服务自监控欠缺:落地全链路监控,晋升前后端全链路可观测性,定位问题低于 5 分钟内。

总体的成果是合乎预期设计的,但还有许多优化的空间比方 API 治理、Error 标准、CICD 标准化,将持续积淀优化该模式,晋升后续个性以及将来新我的项目的交付速率,晋升开发人员幸福感,升高开发成本。

Reference

  • https://github.com/uber-go/gu…
  • https://go.dev/doc/effective_go
  • https://www.conventionalcommi…
  • https://semver.org/
  • https://www.bookstack.cn/read…
  • https://google.aip.dev/
  • https://developers.google.com…
  • https://developers.google.com…
  • https://colobu.com/2017/03/16…
  • https://go-kratos.dev/docs/
  • https://about.gitlab.com/topi…
  • https://www.perforce.com/blog…
退出移动版