期待已久的beego2.0來了,最簡單易用的企業級應用開發框架

  • Beego 2.0 初心

  • 模塊化與解耦

  • AOP 初次嘗試

  • 更好的可觀測性

    • tracing 和 metrics

    • logging

  • 防呆設計 ORM

  • 姍姍來遲的配置模塊優化

  • adapter 模塊和升級指南

  • 未來


Beego 2.0 初心

在鴿子精的本性屢次發作之後,我們終於官宣Beego v2.0要和大家見面了。

在得知我們開啓了 Beego 2.0 的時候,很多人問我們,你們搞 2.0 幹啥呀?

其實不論是 Beego 1.x 還是 Beego 2.0,我們的初心一直沒有改變,也就是希望能夠爲 Go 企業級應用開發提供一種一站式的解決方案,尤其是我們希望能夠爲中小型企業賦能,幫助這些企業提升研發效率、工程質量,以快速推出新產品,快速完成迭代。

我們很多大型企業都有很多規範,但是我們中小企業在規範和基礎組件上面經常是很混亂,開發早期都是怎麼快怎麼來,但是當有新同學加入或者有一個同學離職,就會導致相同功能不同的寫法引入同一功能的不同組件(例如日誌引入logrus、zap), 最終會導致維護困難重構難,遇到問題不知道怎麼查找問題點,這些都是我們很多企業遇到的困難。

而站在我們打工人的角度,我們也相信,真正的勞動者,不應該是被禁錮在流水線上的囚犯。技術應當解放生產力,將勞動者者從繁瑣枯燥的重複性勞動中解放出來,去從事具有創造性藝術性的活動。

所以,我們的設計目標,就是做一個“簡單、高效、一站式”的公司統一應用框架。具體而言則是圍繞這六個特徵進行:

  • 統一標準:讓不同層次的工程師可以基於同樣的標準寫代碼;

  • 低代碼化:自動生成重複代碼,從 CRUD 中解脫出來,專注業務;

  • 錯誤收斂:設計錯誤處理標準,大幅提升錯誤發現、排查和修復的效率;

  • 可治理性:管理應用的生命週期,讓應用能夠在開發、測試、部署和運維階段都更簡單方便;

  • 可插拔性:自由選擇使用的組件,自由接入自己的組件;

  • 可觀測性:全方位觀測應用,掌握應用的各個方面;

那麼,和原先的 Beego 比起來有什麼不同呢?讓我們一起來看看 Beego 2.0 的幾個重大變化吧!

模塊化與解耦

在準備着手 v2.0 的時候,我們做了一些調查。一方面是在社區發放調查問卷,一方面是整理 Beego 的 issue,最終我們確認了 v2.0 的總體思路,那就是:模塊化,模塊化,模塊化

其實在 v1.x 的時候,模塊化已經有了堅實的基礎:

如圖所示,很顯然 Beego 是由這八個模塊組成。而 Beego 被人詬病太重,也是因爲 Beego 一個項目就具有這麼多模塊。而實際上,各個模塊即便在 1.x 裏面也是相當獨立的,只有小部分會耦合在一起。

因此我們要做的是就是重新組織一下這些模塊,並且將模塊之間的耦合降到最低。

這方面我們參考了幾個非常優秀的開源框架,重新劃分了我們的模塊組織:

正如上圖所示,我們希望模塊之間只依賴於底層的模塊,而互相之間不會依賴。

對於一個企業來說,如果選擇 Beego,那麼它很容易就統一所有的技術選型(統一標準,擴展組件),並且帶來極高的研發效能——這對大多數的中小型企業、初創企業來說至關重要。

AOP 初次嘗試

AOP 是一個企業級應用離不開的場景。例如我們想要支持的更好的可觀測性,那麼在接入諸如 opentracing , prometheus 的時候,就需要這種無侵入式的 AOP 解決方案。

我們思考過幾個方案,比如說編譯器接口,在編譯階段通過修改 AST 注入特定的 AOP 邏輯;又或者採用代理,但是這需要一個完整的依賴注入框架支持,從開發體驗上來講,也並不是特別好;

從理論上來說,我們喜歡第一種方案,即編譯器接口的方案。可惜 Go 並未暴露這種編譯器的接口,允許我們在編譯過程中修改代碼。

在無法使用這些手段的約束下,我們只能折中設計了一個能力有限的無侵入式的 AOP 方案。

那就是使用 filter-chain 的設計模式來完成這一類的 AOP 需求。

具體做法是,我們爲主要模塊設計了 filter-chain 。這些接口大抵類似,只是參數略有不同。例如在 httplib 中,其接口是:

type FilterChain func(next Filter) Filter
type Filter func(ctx context.Context, req *BeegoHTTPRequest) (*http.Response, error)

用戶很容易可以通過擴展 Filter 接口來完成自定義的功能,例如日誌:

func myFilter(next httplib.Filter) httplib.Filter {
    return func(ctx context.Context, req *httplib.BeegoHTTPRequest) (*http.Response, error) {
        r := req.GetRequest()
        logs.Info("hello, here is the filter: ", r.URL)
        // 別忘了調用下一個filter
        return next(ctx, req)
    }
}

這個例子只是記錄了一下請求 URL。實際上,如果你要實現熔斷限流和容錯處理,都可以藉助這些 Filter 來完成。

目前,總的來說,AOP 是一個初次嘗試的東西。當前的這種機制還不是特別通用。它被侷限在一個模塊暴露的公共 API 部分,也就是模塊入口和出口部分。而且它也不是聲明式的。我們所期望的,理想中的 AOP 應當是聲明式的,更加貼近 Java Spring 那種聲明式 AOP 框架。

更好的可觀測性

在 Beego 1.x 中,可觀測性三個方面, tacing , metricslogging ,其中 logging 已經得到了很好的支持。

tracing 和 metrics

我們的目標是支持 opentracingprometheus 。選擇 opentracing ,是因爲它頗有一種業界標準的感覺。大多數有影響力的 tacing 框架,都會考慮提供 opentracing API 的支持。這意味着,用戶可以自行選擇他們青睞的 tracing 框架,只需要在啓動的時候注入特定的實現即可。

promethues 雖然不具備 opentracing API 那種普適性。但是它已經是業界事實上的標準了。

還有一個候選者,就是 opentelemetry 。雖然它號稱是下一代的 tracing 標準,但是目前來說,它還不具備 opentracing 那麼大的影響力。它自身的實現也很粗糙,因此排除了它。

我們的重點目標是,讓使用 Beego 的應用可以實現無縫連接。

例如,假如我用 Beego 同時有 A 和 B 兩個應用,而且 A 會調用 B,那麼我只需要開啓了 tracing 功能,那麼我在 A 上使用 httplib 調用 B 的 http 接口,就能實現端到端的鏈路監控

而實際上,我們也達到了這個目標。例如我測試時候一個效果圖,這裏我選擇了 zipkin 作爲 opentracing 的實現:

logging

logging 方面,這一次我們也加進去了一個呼聲很高的特性——自定義日誌格式。自定義日期格式是一個很實用的功能,一方面是公司可能有日誌格式方面的要求,一方面則是更好支持日誌分析的需求。當然,品位,或者說個人偏好也一併滿足了。

爲了降低大家編寫自定義日誌格式支持的難度,我們額外提供了一個實現 PatternLogFormatter 。例如我們傳入一個期望的日誌格式 %F:%n|%w%t>> %m 那麼最終輸出的日誌如:

/User/go/beego/main.go:10|2020-12-11[E]>> message

防呆設計 ORM

每次有人問你們爲什麼要設計新的 ORM 的事務接口?我們都是統一回答:因爲用戶頻繁誤用,導致我們回答 issue 不堪其擾。

那麼原來的 ORM 有什麼弊端呢?

原來的 ORM,如果按照文檔來使用,是毫無破綻的。只不過原本的 ORM 是一個有狀態的東西,比如說裏面有一個 isTx 標記,標記創建的 ORM 對象當前是否處於一個事務中。

然後這就會導致,用戶在不同的 goroutine 之中使用同一個 ORM 對象的時候,經常出現併發問題。

這一次我們就改進了這個問題。當然“防呆設計”是一個開玩笑的說法。畢竟一個 API 經常被誤用,本身就說明了它在設計上是不夠直觀的。

我們這一次摒棄了原本維持 isTx 的做法,而是在開啓一個事務的時候,返回一個全新的 TxOrm 。這個對象是一次性的,隨取隨用,用完即丟。

而且,爲了減輕手動管理事務的負擔,我們提供了一個利用閉包管理事務的 API,用起來很方便:

    err := o.DoTx(func(ctx context.Context, txOrm orm.TxOrmer) error {
        // data
        user := new(User)
        user.Name = "test_transaction"
        // insert data
        // Using txOrm to execute SQL
        _, e := txOrm.Insert(user)
        // if e != nil the transaction will be rollback
        // or it will be committed
        return e
    })

姍姍來遲的配置模塊優化

這一次我們在配置模塊裏面加入了三個很有意思的方法:

 
   Unmarshaler(prefix string, obj interface{}, opt ...DecodeOption) error
   Sub(key string) (Configer, error)
   OnChange(key string, fn func(value string))

說起來這三個方法也只能算是終於把應該有的東西支持了。

不過我們還是想要額外提及一下, Unmarshaler + Sub 簡直是神器,能夠讓用戶非常簡單的就按照自己的模塊組織配置,而後將這些配置反序列化爲特定對象。

並且,我們這一次終於迎來第一個遠程配置中心的實現 etcd 。用戶只需要引入 etcd 的實現,就可以使用了!

其它遠程配置中心的支持,歡迎大家來提 PR 啊!

adapter 模塊和升級指南

這一次,因爲項目結構發生了重大變更。爲了減輕升級的負擔,我們特意開發了一個 adapter 模塊。該模塊的結構和原有的結構一樣,只不過所有的內部實現都用 2.x 的 API。

用戶只需要將包名從 v1.x 的包名換成 adapter 的包名就可以了。

這種替換,我們在 bee 裏面也做了支持,只需要執行:

bee fix -t 2

未來

我們的願景是成爲“最簡單易用的企業級應用開發框架!”。

接下來我們的工作也會以前面提到的六個特徵作爲指導,圍繞以下方面進行:

  • 統一標準:着重解決當前業務開發測試難的問題,爲 ORM 等模塊提供便利的測試支持;

  • 錯誤收斂:爲全部組件設計統一的錯誤碼和標準化的錯誤信息;

  • 可治理性:增強現有的治理功能,例如暴露 cache 的統計信息,模塊的錯誤信息。同時支持 Beego 應用集羣維度監控和治理能力;

  • 可觀測性:繼續在 Beego 內部加多埋點和日誌信息,並且允許設定參數開啓或者關閉(包括部分開啓和部分關閉)。也希望能夠提供全面的 benchmark 測試,對所有模塊的性能做到心中有數;

技術方向

從技術發展方向而言,我們的三個核心詞彙就是:泛型,容器(DI),雲原生。

泛型會是我們的第一個目標。因爲,每一次泛型出現,都會導致已有的模式發生巨大的變化。例如說現在的 ORM 接口幾乎就是隻接收 interface 對象,基本上無法享受到編譯期的檢查。我們也希望我們能夠在泛型出來之時,能夠迅速搶佔技術高地,對外輸出我們的實踐標準。

容器,包括依賴注入,應用生命週期管理,AOP 方面,會是我們的第二個目標。AOP 這是爲了將用戶從無聊的創建對象,管理對象和銷燬對象中解放出來。而 AOP,前面已經提及了,這是一個做企業級應用開發框架不得不解決的一個問題。

第三個目標雲原生則是,探索如何利用好雲原生的技術,增強 Beego 應用的可用性、穩定性,減輕對 Beego 應用的運維管理負擔。

在此我們先立一個 Flag,希望泛型正式發佈的時候,我們已經做好準備了

致謝

感謝這些爲 Beego2.0 做出貢獻的人員(Github ID):

flycash, jianzhiyao, AllenX2018, IamCathal, tayoogunbiyi, wangle201210, mlboy, askuy, flutterWang, higker,  weirubo, yitea, Cadenguo, unknowon, vinicio, ACrushTest.

還有那些未列出來但是參與我們社區討論,在 issue 裏面給我們提出很多建議的人。

特別感謝 askuy,他可以說是 Beego 2.0 的總架構師,他豐富的經驗,使我們更有底氣,更有自信。

尤其感謝謝大,爲我們把控方向,給予了我們充分的信任,讓我們能夠在 Beego 裏面大展身手。

最後要感謝我們的社區,給了我們很多有用的建議和反饋。以及對我們鴿了好幾次的無限包容(我們還是希望你們多來催催我們不然就更加容易鴿了)。

歡迎大家來使用我們 Beego!我們準備了文檔和例子,還等什麼, 一起來啊!

- 官網: https://beego.me

- 例子 https://github.com/beego/beego-example

- Release Note:https://github.com/beego/beedoc/blob/master/en-US/intro/releases.md

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章