不会飞的章鱼

熟能生巧,勤能补拙;念念不忘,必有回响。

Go高级工程师_第7课_社区优秀框架对⽐

常⻅ web 框架

httprouter

  • ⼏乎是所有 Go web 框架的 router 实现的爸爸
  • ⼀个简单的 radix tree 的实现

chi

最简单的框架:

  • 核⼼代码 1200 ⾏
  • 适合作为 web 框架⼊⻔项⽬
  • 在其基础上整合其它组件,⽅便

主要组件:

  • Router,⽀持分组
  • Middleware/Chai
  • Context

Gin

⽼牌框架

  • Star 最多
  • 核⼼代码 3000 ⾏
  • ⽤户很多很多

主要组件:

  • Router,⽀持分组
  • Middlewar
  • binding,将 decoder 和 validator 合⼆为⼀,变成了 binding 组件
  • Logger,功能⽐较弱
  • Context

echo

⽼牌框架

  • 核⼼代码 1900
  • 中规中矩

主要组件:

fiber

2020 年开始做的框架

  • 基于 fasthtt
  • 参考了 Express.js 的设计

主要组件:

  • Router,⽀持分组
  • Middleware
  • Context

Beego

元⽼框架

  • 与 martini,gin,beego 曾经是 Go 圈⼦三个最⽕的框架
  • 国⼈的第⼀个 Go 的世界级项⽬
  • MVC 框架,适合 PHP 程序员上⼿

主要组件:

  • Router,⽀持分组
  • Filter(其实就是 middleware
  • Contex
  • Task(类似 spring 框架中的定时任务
  • orm、httpclient、cache、validator、config、swagger、template 等

小结

⼤多数流⾏的 Go 开源 web 框架本身功能并不是很多,最简单的框架,只需三个组件:

  • Router
  • Middleware
  • Context

微服务框架

相⽐ web 框架,微服务框架的组件更多:

  • Config:配置管理组件
  • Logger:遵守第三⽅⽇志收集规范的⽇志组件
  • Metrics:使框架能够与 Prometheus 等监控系统集成的 metrics 组件
  • Tracing:遵守 OpenTelemetry 的 tracing 组件
  • Registry:服务发现组件
  • MQ:可以切换不同队列实现的 mq 组件
  • 依赖注⼊:wire,dig 等组件

go-micro

主要组件:

go-zero

YoYoGo

DubboGo

Kratos

如何评判框架优劣

框架设计需要考虑的问题

  • 自动化
  • 平台化
  • 集成化
  • 组件化
  • 插件化
  • 通用化

如何评判框架优劣

自动化

  • Layout 代码⾃动⽣成(DDD/Clean Arch
  • 服务上线⾃动发布
  • ⾃动⽣成接⼝⽂档
  • 服务接⼊ SDK ⾃动⽣成
  • 常⻅ code snippet(boilerplate) 内置在 CLI ⼯具内
  • 不要让⽤户去复制粘贴,我们来帮他⾃动写好

平台化

  • IDL 在平台中管理
  • 接⼝⽂档可检索
  • 服务上线/部署流⽔线化

举例

  • step 1,修改服务名,服务级别(p0, p1)
  • step 2,选择依赖资源,db,redis,mq,外部服务
  • step 3,选择服务部署集群,⾼可⽤要求
  • step 4,部署

集成化

  • 框架提供所有基础设施 SDK(log, tracing, config center,orm/sql builder,es sdk,clickhourse sdk, mq, etc..
  • 开箱即⽤,核⼼依赖⽆需外部站点寻找
  • 专⻔的 organization 下维护其它⾮核⼼依赖
  • 解决⽤户的选择困难症

组件化

  • 稳定性需求,沉淀为统⼀组件
  • 公司内历次故障经验都应尽量沉淀为避免/解决问题的组件(可以是重试组件中的规则,也可以是静态扫描⼯具中的⼀个 linter)
  • 不要让每个⼈都必须读⼀遍 Google SRE 书才能做好稳定性

插件化

  • ⾯向接⼝编程
  • 组件以 plugin 形式提供(不是 Go 语⾔的那个 plugin)

通用化

  • 主要针对开源框架
  • Leave options open by Uncle Bob
  • 让⽤户有选择权(我喜欢 etcd/zk 做注册中⼼,我偏要⽤),可以通过插件化来达成
  • Go-micro 是⼀个很好的范例

对于企业内部框架来说,通⽤并不是⼀定要追求的⽬标

小结

  • 对于企业场景来说,⼤⽽全就是好
  • 对于开源场景来说,给⽤户选择权才是好

如何看待社区观点

框架应该做薄

核⼼观点:

  • Less is more
  • 框架的核⼼只保留通⽤接⼝和简单流程
  • 复杂的选择问题交给⽤户
  • 我们写 Go,就是因为不喜欢 Java 那样臃肿的框架!

如果框架不愿意帮业务解决依赖的坑,那每个业务都要被相似的问题坑⼀遍。

OLTP 到底该不该使⽤ ORM、sql builder

如果线上出现了慢 SQL,我想要⻢上定位到代码位置呢?

使⽤规范的 SQL <-> struct 绑定⽅式,可以整合静态分析、部署⼯具直接定位到哪⼀次部署引⼊了慢 SQL

但是:⽬前没有看到任何⼀家公司实现了上述诊断链。

框架内容多,升级负担极⼤,要推每个业务⽅去升级

  • 确实是这样,但这是框架组的责任
  • 基于 service mesh 和 dapr 的架构⼀定程度上解决了这个问题

框架不应该对业务⾃⼰选内部库造成的依赖冲突负责

  • 框架是稳定性/⼯程效率交给业务研发的产品
  • 产品问题就应该让负责⼈来改进,甩锅怎么能⾏呢

⼀些可以借鉴的思路

  • IDL 之间可以使⽤技术⼿段可以互相转换(第⼆节课有提到)
  • 要做平台化,可以适当屏蔽 IDL 的语法,可以参考 openapi
  • 业务代码⼊⼝不应与任何协议绑定,如图:

References

why library?
Go Micro 初探及其底层架构
Go-Micro 微服务框架设计
Why I Recommend to Avoid Using the go-kit Library

------ 本文结束------
如果本篇文章对你有帮助,可以给作者加个鸡腿~(*^__^*),感谢鼓励与支持!