天天看點

效率提高80%,Go開發必備的庫與工具!

效率提高80%,Go開發必備的庫與工具!

不知不覺寫 ​

​Go​

​ 已經快一年了,上線了大大小小好幾個項目;心态也經曆了幾輪變化。

因為我個人大概前五年時間寫的是 ​

​Java​

​​ ,中途寫過一年多的 ​

​Python​

​​,是以剛接觸到 Go 時的感覺如下圖:

效率提高80%,Go開發必備的庫與工具!

既沒有 ​

​Java​

​​ 的生态,也沒有 ​

​Python​

​ 這麼多文法糖。

寫到現在的感覺就是:

效率提高80%,Go開發必備的庫與工具!

這裡就不讨論這幾門語言誰強誰弱了;重點和大家分享下我們日常開發中所使用到的一些第三方庫與工具。

這裡我主要将這些庫分為兩類:

  • 業務開發
  • 基礎工具開發

業務開發

首先是業務開發,主要包含了 ​

​web​

​​、資料庫、​

​Redis​

​ 等。

Gin ⭐️⭐️⭐️⭐️⭐️

首先是 Gin,一款 HTTP 架構,使用簡單、性能優秀、資料衆多;你還在猶豫選擇哪款架構時,那就選擇它吧,基本沒錯。

當然和它配套的 github.com/swaggo/gin-swagger swagger 工具也是剛需;利用它可以生成 swagger 文檔。

GORM ⭐️⭐️⭐️⭐️⭐️

GORM 也沒啥好說的,如果你喜歡 ​

​orm​

​ 的方式操作資料庫,那就選它吧;同樣的也是使用簡單、資料較多。

如果有讀寫分離需求,也可以使用 ​

​GORM​

​​ 官方提供的插件 https://github.com/go-gorm/dbresolver ,配合 ​

​GORM​

​ 使用也是非常簡單。

errors ⭐️⭐️⭐️⭐️⭐️

Go 語言自身提供的錯誤處理比較簡單,https://github.com/pkg/errors 提供了更強大的功能,比如:

  • 包裝異常
  • 包裝堆棧等。

常用的有以下 API:

// WithMessagef annotates err with the format specifier.
func WithMessagef(err error, format string, args ...interface{}) error

// WithStack annotates err with a stack trace at the point WithStack was called.
func WithStack(err error) error      

zorolog ⭐️⭐️⭐️⭐️⭐️

Go 裡的日志列印庫非常多,日志在日常開發中最好就是存在感低;也就是說性能強(不能影響到業務代碼)、使用 API 簡單。

"github.com/rs/zerolog/log"
log.Debug().Msgf("OrderID :%s", "12121")      

excelize

https://github.com/qax-os/excelize是一個讀寫 Excel 的庫,基本上你能遇到的 Excel 操作它都能實作。

now ⭐️⭐️⭐️⭐️

https://github.com/jinzhu/now 是一個時間工具庫:

  • 擷取目前的年月日、時分秒。
  • 不同時區支援。
  • 最後一周、最後一個月等。
import "github.com/jinzhu/now"

time.Now() // 2013-11-18 17:51:49.123456789 Mon

now.BeginningOfMinute()        // 2013-11-18 17:51:00 Mon
now.BeginningOfHour()          // 2013-11-18 17:00:00 Mon
now.BeginningOfDay()           // 2013-11-18 00:00:00 Mon
now.BeginningOfWeek()          // 2013-11-17 00:00:00 Sun
now.BeginningOfMonth()         // 2013-11-01 00:00:00 Fri
now.BeginningOfQuarter()       // 2013-10-01 00:00:00 Tue
now.BeginningOfYear()          // 2013-01-01 00:00:00 Tue

now.EndOfMinute()              // 2013-11-18 17:51:59.999999999 Mon
now.EndOfHour()                // 2013-11-18 17:59:59.999999999 Mon
now.EndOfDay()                 // 2013-11-18 23:59:59.999999999 Mon
now.EndOfWeek()                // 2013-11-23 23:59:59.999999999 Sat
now.EndOfMonth()               // 2013-11-30 23:59:59.999999999 Sat
now.EndOfQuarter()             // 2013-12-31 23:59:59.999999999 Tue
now.EndOfYear()                // 2013-12-31 23:59:59.999999999 Tue

now.WeekStartDay = time.Monday // Set Monday as first day, default is Sunday
now.EndOfWeek()                // 2013-11-24 23:59:59.999999999 Sun      

Decimal ⭐️⭐️⭐️⭐️

當業務上需要精度計算時 https://github.com/shopspring/decimal 可以幫忙。

import (
 "fmt"
 "github.com/shopspring/decimal"
)

func main() {
 price, err := decimal.NewFromString("136.02")

 quantity := decimal.NewFromInt(3)
 fee, _ := decimal.NewFromString(".035")
 taxRate, _ := decimal.NewFromString(".08875")

 subtotal := price.Mul(quantity)

 preTax := subtotal.Mul(fee.Add(decimal.NewFromFloat(1)))

 total := preTax.Mul(taxRate.Add(decimal.NewFromFloat(1)))

 fmt.Println("Subtotal:", subtotal)                      // Subtotal: 408.06
 fmt.Println("Pre-tax:", preTax)                         // Pre-tax: 422.3421
 fmt.Println("Taxes:", total.Sub(preTax))                // Taxes: 37.482861375
 fmt.Println("Total:", total)                            // Total: 459.824961375
 fmt.Println("Tax rate:", total.Sub(preTax).Div(preTax)) // Tax rate: 0.08875
}      

基本上你能想到的精度轉換它都能做到;配合上 ​

​GORM​

​​ 也可以将 ​

​model​

​​ 字段聲明為 ​

​decimal​

​​ 的類型,資料庫對應的也是 ​

​decimal​

​ ,這樣使用起來時會更友善。

Amount decimal.Decimal `gorm:"column:amout;default:0.0000;NOT NULL" json:"amout"`       

configor ⭐️⭐️⭐️⭐️

https://github.com/jinzhu/configor 是一個配置檔案讀取庫,支援 ​

​YAML/JSON/TOML​

​ 等格式。

go-cache ⭐️⭐️⭐️

https://github.com/patrickmn/go-cache 是一個類似于 Java 中的 ​

​Guava cache​

​,線程安全,使用簡單;不需要分布式緩存的簡單場景可以考慮。

c := cache.New(5*time.Minute, 10*time.Minute)
 // Set the value of the key "foo" to "bar", with the default expiration time
 c.Set("foo", "bar", cache.DefaultExpiration)      

copier ⭐️⭐️⭐️

https://github.com/jinzhu/copier 看名字就知道這是一個資料複制的庫,與 ​

​Java​

​​ 中的 ​

​BeanUtils.copy()​

​​ 類似;可以将兩個字段相同但對象不同的  ​

​struct​

​ 進行資料複制,也支援深拷貝。

func Copy(toValue interface{}, fromValue interface{}) (err error)       

在我們需要一個臨時 struct 來存放資料時很有用,特别是一個 struct 中字段非常多時,一個個來回指派确實有點費手指。

但也要注意不要什麼情況都使用,會帶來一些弊端:

  • 當删除字段時,不能利用編譯器提示。
  • 當一些字段需要額外人工處理時,代碼不易閱讀。
  • 反射指派,有一定性能損耗。

總之在業務開發時,還是建議人工編寫,畢竟代碼是給人看的。

env ⭐️⭐️⭐️

https://github.com/caarlos0/env 這個庫可以将我們的環境變量轉換為一個 ​

​struct​

​.

type config struct {
 Home string `env:"HOME"`
}

func main() {
 cfg := config{}
 if err := env.Parse(&cfg); err != nil {
  fmt.Printf("%+v\n", err)
 }

 fmt.Printf("%+v\n", cfg)
}      

這個在我們打包代碼到不同的運作環境時非常有用,利用它可以友善的擷取不同環境變量。

user_agent ⭐️⭐️⭐️

https://github.com/mssola/user_agent 是一個格式化 ​

​user-agent​

​ 的小工具。

當我們需要在服務端收集 ​

​user-agen​

​ 時可以更快的讀取資料。

func main() {
    ua := user_agent.New("Mozilla/5.0 (Linux; U; Android 2.3.7; en-us; Nexus One Build/FRF91) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1")

    fmt.Printf("%v\n", ua.Mobile())   // => true
    fmt.Printf("%v\n", ua.Bot())      // => false
    fmt.Printf("%v\n", ua.Mozilla())  // => "5.0"
    fmt.Printf("%v\n", ua.Model())    // => "Nexus One"
    fmt.Printf("%v\n", ua.Platform()) // => "Linux"
    fmt.Printf("%v\n", ua.OS()) 
    }      

phonenumbers ⭐️⭐️⭐️

https://github.com/nyaruka/phonenumbers 手機号碼驗證庫,可以不用自己寫正規表達式了。

// parse our phone number
num, err := phonenumbers.Parse("6502530000", "US")      

基礎工具

接下來是一些基礎工具庫,包含一些主流的存儲的用戶端、中間件等。

gomonkey ⭐️⭐️⭐️⭐️⭐️

github.com/agiledragon/gomonkey 是一個 ​

​mock​

​​ 打樁工具,當我們寫單元測試時,需要對一些非接口函數進行 ​

​mock​

​ 會比較困難,這時就需要用到它了。

由于它是修改了調用對應函數時機器跳轉指令,而 CPU 架構的不同對應的指令也不同,是以在我們使用時還不相容蘋果的 M1 晶片,不過目前應該已經相容了,大家可以試試。

goconvey ⭐️⭐️⭐️⭐️⭐️

https://github.com/smartystreets/goconvey 也是配合單元測試的庫,可以相容 ​

​go test​

​ 指令。

  • 提供可視化 web UI。
  • 與 IDE 內建顯示單元覆寫率。
    效率提高80%,Go開發必備的庫與工具!

dig ⭐️⭐️⭐️⭐️⭐️

https://github.com/uber-go/dig 這是一個依賴注入庫,我們這裡暫不讨論是否應該使用依賴注入,至少目前我們使用下來還是有幾個好處:

  • 所有的對象都是單例。
  • 有一個統一的地方管理對象。
  • 使用時直接傳遞對象當做參數進來即可(容器會自動注入)。

當然也有一些不太友善的地方:

  • 不熟悉時,一個對象是如何建立的不清楚。
  • 代碼不是很好了解。

我們内部有自己開發一個業務架構,其中所有的對象都交由 dig 進行管理,使用起來倒也是比較友善。

cobra ⭐️⭐️⭐️⭐️

https://github.com/spf13/cobra是一個功能強大的指令行工具庫,我們用它來實作内部的指令行工具,同時也推薦使用 https://github.com/urfave/cli/ 我個人會更習慣用後者,要簡潔一些。

BloomRPC ⭐️⭐️⭐️⭐️

https://github.com/uw-labs/bloomrpc 一個 ​

​gRPC​

​​ 可視化工具,比起自己寫 ​

​gRPC​

​ 用戶端的代碼那确實是要簡單許多。

效率提高80%,Go開發必備的庫與工具!

但也有些小問題,比如精度。如果是 int64 超過了 2^56 服務端拿到的值會發生錯誤,這點目前還未解決。

redis ⭐️⭐️⭐️⭐️

https://github.com/go-redis/redis/ Redis 用戶端,沒有太多可說的;發展了許多年,該有的的功能都有了。

elastic ⭐️⭐️⭐️⭐️

https://github.com/olivere/elastic 這也是一個非常成熟的 ​

​elasticsearch​

​ 庫。

resty ⭐️⭐️⭐️⭐️

https://github.com/go-resty/resty/  一個 http client, 使用起來非常簡單:

// Create a Resty Client
client := resty.New()
resp, err := client.R().
    EnableTrace().
    Get("https://httpbin.org/get")      

有點 ​

​Python requests​

​ 包那味了。

pulsar-client-go ⭐️⭐️⭐️

Pulsar 官方出品的 go 語言用戶端,相對于 Java 來說其他語言的用戶端幾乎都是後娘養的;功能會比較少,同時更新也沒那麼積極;但卻沒得選。

go-grpc-middleware ⭐️⭐️⭐️

https://github.com/grpc-ecosystem/go-grpc-middleware 官方提供的 ​

​gRPC​

​ 中間件,可以自己實作内部的一些鑒權、中繼資料、日志等功能。

go-pilosa ⭐️⭐️⭐️

https://github.com/pilosa/go-pilosa 是一個位圖資料庫的用戶端,位圖資料庫的場景應用比較有限,通常是有标簽需求時才會用到;比如求 N 個标簽的交并補集;資料有一定規模後營運一定會提相關需求;可以備着以備不時之需。

pb ⭐️⭐️⭐️

https://github.com/cheggaaa/pb 一個指令行工具進度條,編寫指令行工具時使用它互動會更優雅。

效率提高80%,Go開發必備的庫與工具!

總結

最後我彙總了一個表格,友善檢視:

名稱 類型 功能 星級
Gin 業務開發

​HTTP​

​ 架構
⭐️⭐️⭐️⭐️⭐️
GORM 業務開發

​ORM​

​ 架構
⭐️⭐️⭐️⭐️⭐️
errors 業務開發 異常處理庫 ⭐️⭐️⭐️⭐️⭐️
zorolog 業務開發 日志庫 ⭐️⭐️⭐️⭐️⭐️
excelize 業務開發

​Excel​

​相關需求
⭐️⭐️⭐️⭐️⭐️
now 業務開發 時間處理 ⭐️⭐️⭐️⭐️️
Decimal 業務開發 精度處理 ⭐️⭐️⭐️⭐️️
configor 業務開發 配置檔案 ⭐️⭐️⭐️⭐️️
go-cache 業務開發 本地緩存 ⭐️⭐️⭐️
copier 業務開發 資料複制 ⭐️⭐️⭐️️️
env 業務開發 環境變量 ⭐️⭐️⭐️️️
user_agent 業務開發 讀取 ​

​user-agent​

⭐️⭐️⭐️️️
phonenumbers 業務開發 手機号碼驗證 ⭐️⭐️⭐️️️
gomonkey 基礎工具

​mock​

​工具
⭐️⭐️⭐️⭐️⭐
goconvey 基礎工具 單測覆寫率 ⭐️⭐️⭐️⭐️⭐
dig 基礎工具 依賴注入 ⭐️⭐️⭐️⭐️⭐
cobra 基礎工具 指令行工具 ⭐️⭐️⭐️⭐
cli 基礎工具 指令行工具 ⭐️⭐️⭐️⭐
BloomRPC 基礎工具

​gRPC​

​ 調試用戶端
⭐️⭐️⭐️⭐
redis 基礎工具 Redis 用戶端 ⭐️⭐️⭐️⭐
elastic 基礎工具

​elasticsearch​

​ 用戶端
⭐️⭐️⭐️⭐
resty 基礎工具 http 用戶端 ⭐️⭐️⭐️⭐
pulsar-client-go 基礎工具

​Pulsar​

​ 用戶端
⭐️⭐️⭐️
go-grpc-middleware 基礎工具

​gRPC​

​ 中間件
⭐️⭐️⭐
go-pilosa 基礎工具

​pilosa​

​ 用戶端
⭐️⭐️⭐️
pb 基礎工具 指令行工具進度條 ⭐️⭐️⭐️
星級評分的規則主要是看實際使用的頻次。

最後夾帶一點私貨(其實也談不上)

文中提到了我們内部有基于以上庫整合了一個業務開發架構;也基于該架構上線了大大小小10幾個項目,改進空間依然不少,目前還是在快速疊代中。

大概的用法,入口 ​

​main.go​

​​:

效率提高80%,Go開發必備的庫與工具!
效率提高80%,Go開發必備的庫與工具!

最後截取我在内部的分享就概括了整體的思想​​

​--引用自公司一司姓同僚​

​。