go-zero 是一個整合了各種工程實踐的 Web 和 rpc 框架,它的彈性設計保障了大併發服務端的穩定性,並且已經經過了充分的實戰檢驗。
go-zero 在設計時遵循了 “工具大於約定和文件” 的理念,所以 go-zero 包含極簡的 API 定義和生成工具 goctl,可以根據定義的 API 檔案一鍵生成 Go、iOS、Android、Kotlin、Dart、TypeScript、JavaScript 程式碼,並可直接執行。
如上圖所示,不同客戶端的請求都會先進入 go-zero 的 API 端。API 端最主要的作用是通過 ETCD 將對應的請求通過 gRPC 協議轉發到 Service 端。根據請求的具體內容,Service 端負責對資料進行查詢或儲存。如果是查詢請求,go-zero 有內建的 API 會先查詢快取層,減少資料庫的查詢壓力。
由圖可見,API 端和 Service 端中框架已經內建了非常豐富的功能,在開發過程中只需要我們填充對應的業務邏輯,即可輕鬆實現 CRDU 級的需求。
我們為什麼說 go-zero 是開箱即用的微服務架構呢?不急,我們來盤點下 go-zero 中有哪些強大的特性。
go-zero 適合做微服務快速開發的特性
Go-zero 擁有強大的專案腳手架工具 goctl。 goctl 和前端中的 Vue-cli、React-cli 一樣方便。goctl 通過配置檔案可以生成 API、rpc 和 model 等相關程式碼。 同時,go-zero 擁有較完備的專案框架。腳手架生成的專案框架足以應對常見的需求。CRDU 等需求只需要做 “填空題”,在已生成的程式碼上填充必要的業務邏輯。 其他快取鑑權等需求,框架中也早已內建。
另外,go-zero 擁有獨特的“漸進式”框架。“漸進式”是前端 Vue 框架的一大特性,大意是“易於上手,還便於與第三方庫或既有專案整合”。本文借用這個概念是想表明 go-zero 對專案的入侵性較少,go-zero 生成的程式碼可以拆開使用,逐步對老專案進行改造。
低耦合的模組設計,豐富的中介軟體,外掛和工具:
-
go-zero 中各模組耦合程度低,我們可以通過文件中的元件中心尋找合適的中介軟體或自研中介軟體。
-
如果覺得 goctl 不能滿足需求,goctl 還支援 plugin 命令對 goctl 進行擴充套件。
-
go-zero 的很多配置檔案是自定義語法。 go-zero 還提供了 intellij 和 vscode 外掛,提供了語法高亮錯誤檢查等編輯增強功能。
goctl 介紹
goctl 是 go-zero 微服務框架下的程式碼生成工具。使用 goctl 可顯著提升開發效率,讓開發人員將時間重點放在業務開發上。
goctl 的命令可歸納為如下幾類:
-
API 命令,快速生成一個 API 服務
-
rpc 命令,支援 proto 模板生成和 rpc 服務程式碼生成
-
model 命令,目前支援識別 mysql ddl 進行 model 層程式碼生成
-
plugin 命令,支援針對 API 自定義外掛
-
其他命令,目前是釋出相關
goctl 的命令眾多,本次涉及到的只是其中 API、rpc 和 model 相關的基礎命令。
使用 goctl 的基本流程
使用 goctl 生成程式碼的流程大致可以分為 4 步:
-
使用命令 a 生成預設的配置檔案;
-
按照業務需求編輯該配置檔案;
-
使用命令 b 按照配置檔案生成預設的程式碼檔案;
-
按照業務邏輯填充對應的程式碼檔案。
什麼情況不適宜使用 go-zero 做微服務快速開發?
看完上面的介紹,想必大家對於 go-zero 開發微服務已經有點躍躍欲試了吧。不過經過一番實踐,我認為當出現以下情況時,不適宜採用 go-zero 作為開發微服務的框架。
當前需求與 goctl 的理念相沖突
go-zero 的一大賣點是腳手架工具 goctl,如果定製需求過多可能與 goctl 生成的程式碼相沖突。但是如果放棄 goctl 手動編寫程式碼的話,開發效率會大大降低。
舉個例子,如上圖所示,go-zero 在 Service 端目前只支援 gRPC,在資料庫層只支援 Mysql、MongoDB 和 ClickHouse,服務發現只支援 ETCD。在這種情況下如果想實現 PostgreSQL 替換 Mysql、Consul 替換 ETCD 等定製操作,goctl 生成的程式碼執行時很可能會出現異常。
希望框架提供的功能非常完善
go-zero 大部分元件是自研,比如 sqlx,httpx 等。這些自研元件滿足 CRDU 的操作綽綽有餘,但是與 gorm、gin 等專攻某一方向的開源專案相比還是有非常大的差距的。
所以隨著公司業務發展需求越來越五花八門,當前的主要矛盾從“快速開發”變成“精細化開發”時,會發現該框架有這樣或那樣的不足。這種情況下就需要提 RP 或自己 fork 一份魔改了。個人覺得這種情況比 Spring 或 Django 那樣一個“全家桶” 改動起來要省力省心。