Go 每日一庫之云原生 go-zero 微服務(wù)框架
0. go-zero 介紹
go-zero 是一個(gè)集成了各種工程實(shí)踐的 web 和 rpc 框架。通過彈性設(shè)計(jì)保障了大并發(fā)服務(wù)端的穩(wěn)定性,經(jīng)受了充分的實(shí)戰(zhàn)檢驗(yàn)。
go-zero 包含極簡(jiǎn)的 API 定義和生成工具 goctl,可以根據(jù)定義的 api 文件一鍵生成 Go, iOS, Android, Kotlin, Dart, TypeScript, JavaScript 代碼,并可直接運(yùn)行。
使用 go-zero 的好處:
輕松獲得支撐千萬日活服務(wù)的穩(wěn)定性 內(nèi)建級(jí)聯(lián)超時(shí)控制、限流、自適應(yīng)熔斷、自適應(yīng)降載等微服務(wù)治理能力,無需配置和額外代碼 微服務(wù)治理中間件可無縫集成到其它現(xiàn)有框架使用 極簡(jiǎn)的 API 描述,一鍵生成各端代碼 自動(dòng)校驗(yàn)客戶端請(qǐng)求參數(shù)合法性 大量微服務(wù)治理和并發(fā)工具包 
1. go-zero 框架背景
18 年初,曉黑板后端在經(jīng)過頻繁的宕機(jī)后,決定從Java+MongoDB的單體架構(gòu)遷移到微服務(wù)架構(gòu),經(jīng)過仔細(xì)思考和對(duì)比,我們決定:
基于 Go 語言 高效的性能 簡(jiǎn)潔的語法 廣泛驗(yàn)證的工程效率 極致的部署體驗(yàn) 極低的服務(wù)端資源成本 自研微服務(wù)框架 個(gè)人有過很多微服務(wù)框架自研經(jīng)驗(yàn) 需要有更快速的問題定位能力 更便捷的增加新特性
2. go-zero 框架設(shè)計(jì)思考
對(duì)于微服務(wù)框架的設(shè)計(jì),我們期望保障微服務(wù)穩(wěn)定性的同時(shí),也要特別注重研發(fā)效率。所以設(shè)計(jì)之初,我們就有如下一些準(zhǔn)則:
保持簡(jiǎn)單 高可用 高并發(fā) 易擴(kuò)展 彈性設(shè)計(jì),面向故障編程 盡可能對(duì)業(yè)務(wù)開發(fā)友好,封裝復(fù)雜度 盡可能約束做一件事只有一種方式
我們經(jīng)歷不到半年時(shí)間,徹底完成了從Java+MongoDB到Golang+MySQL為主的微服務(wù)體系遷移,并于 18 年 8 月底完全上線,穩(wěn)定保障了曉黑板后續(xù)增長,確保了整個(gè)服務(wù)的高可用。
3. go-zero 項(xiàng)目實(shí)現(xiàn)和特點(diǎn)
go-zero 是一個(gè)集成了各種工程實(shí)踐的包含 web 和 rpc 框架,有如下主要特點(diǎn):
強(qiáng)大的工具支持,盡可能少的代碼編寫 極簡(jiǎn)的接口 完全兼容 net/http 支持中間件,方便擴(kuò)展 高性能 面向故障編程,彈性設(shè)計(jì) 內(nèi)建服務(wù)發(fā)現(xiàn)、負(fù)載均衡 內(nèi)建限流、熔斷、降載,且自動(dòng)觸發(fā),自動(dòng)恢復(fù) API 參數(shù)自動(dòng)校驗(yàn) 超時(shí)級(jí)聯(lián)控制 自動(dòng)緩存控制 鏈路跟蹤、統(tǒng)計(jì)報(bào)警等 高并發(fā)支撐,穩(wěn)定保障了曉黑板疫情期間每天的流量洪峰
如下圖,我們從多個(gè)層面保障了整體服務(wù)的高可用:

4. go-zero 近期開發(fā)計(jì)劃
自動(dòng)生成 API mock server,便于客戶端開發(fā) 自動(dòng)生成服務(wù)端功能測(cè)試
5. Installation
在項(xiàng)目目錄下通過如下命令安裝:
go?get?-u?github.com/tal-tech/go-zero
6. Quick Start
編譯 goctl 工具
go?build?tools/goctl/goctl.go
把 goctl 放到$PATH 的目錄下,確保 goctl 可執(zhí)行
定義 API 文件,比如 greet.api,可以在 vs code 里安裝 goctl插件,支持 api 語法
type?Request?struct?{
??Name?string?`path:"name,options=you|me"`?//?框架自動(dòng)驗(yàn)證請(qǐng)求參數(shù)是否合法
}
type?Response?struct?{
??Message?string?`json:"message"`
}
service?greet-api?{
??@server(
????handler:?GreetHandler
??)
??get?/greet/from/:name(Request)?returns?(Response);
}
也可以通過 goctl 生成 api 模本文件,命令如下:
goctl?api?-o?greet.api
生成 go 服務(wù)端代碼
goctl?api?go?-api?greet.api?-dir?greet
生成的文件結(jié)構(gòu)如下:
├──?greet
│???├──?etc
│???│???└──?greet-api.json????????//?配置文件
│???├──?greet.go??????????????????//?main文件
│???└──?internal
│???????├──?config
│???????│???└──?config.go?????????//?配置定義
│???????├──?handler
│???????│???├──?greethandler.go???//?get/put/post/delete等路由定義文件
│???????│???└──?routes.go?????????//?路由列表
│???????├──?logic
│???????│???└──?greetlogic.go?????//?請(qǐng)求邏輯處理文件
│???????├──?svc
│???????│???└──?servicecontext.go?//?請(qǐng)求上下文,可以傳入mysql,?redis等依賴
│???????└──?types
│???????????└──?types.go??????????//?請(qǐng)求、返回等類型定義
└──?greet.api?????????????????????//?api描述文件
生成的代碼可以直接運(yùn)行:
cd?greet
go?run?greet.go?-f?etc/greet-api.json
默認(rèn)偵聽在 8888 端口(可以在配置文件里修改),可以通過 curl 請(qǐng)求:
???go-zero?git:(master)?curl?-w?"\ncode:?%{http_code}\n"?http://localhost:8888/greet/from/kevin
{"code":0}
code:?200
編寫業(yè)務(wù)代碼:
可以在 servicecontext.go 里面?zhèn)鬟f依賴給 logic,比如 mysql, redis 等 在 api 定義的 get/post/put/delete 等請(qǐng)求對(duì)應(yīng)的 logic 里增加業(yè)務(wù)處理邏輯
可以根據(jù) api 文件生成前端需要的 Java, TypeScript, Dart, JavaScript 代碼
goctl?api?java?-api?greet.api?-dir?greet
goctl?api?dart?-api?greet.api?-dir?greet
...
7. Benchmark

測(cè)試代碼見這里:https://github.com/smallnest/go-web-framework-benchmark
8. 項(xiàng)目地址
https://github.com/tal-tech/go-zero
推薦閱讀
站長 polarisxu
自己的原創(chuàng)文章
不限于 Go 技術(shù)
職場(chǎng)和創(chuàng)業(yè)經(jīng)驗(yàn)
Go語言中文網(wǎng)
每天為你
分享 Go 知識(shí)
Go愛好者值得關(guān)注
