go與go mod命令使用方式以及遇到的問題
go包版本更新引起的一些問題
在使用go mod tidy或者go run命令時,通常會下載最新版本的golang的依賴包,但是有些包更新后,與之前的版本不兼容,如函數(shù)方法傳參、返回類型、參數(shù)數(shù)目等都可能發(fā)生變化,這樣就會經常出現(xiàn)之前能夠正常運行的程序,在無意中引入新版本的golang包后,出現(xiàn)一些莫名的異常,下面就記錄幾個遇到的這方面的問題,并給出排查問題的經過,及解決問題,以給遇到相似問題的同學們一些參考。
jwt和iris版本更新問題
在使用golang iris框架進行后端開發(fā)時,使用go run命令運行程序,出現(xiàn)
通過golangci-lint run命令,檢查代碼格式,出現(xiàn):
cannot load github.com/klauspost/compress/snappy: module github.com/klauspost/compress@latest found .......
原因:
在使用go mod tidy或者go run的時候,默認會下載安裝最新版本的包。
在go.mod文件中,發(fā)現(xiàn)使用的iris是最新的v12.2.0-alpha2測試版,而這個版本的好多東西相比v12.1.8版本,函數(shù)的參數(shù),返回值發(fā)生了變化,引起其他包也可能出錯。
module github.com/xxxxxx/huoxing go 1.13 require ( github.com/Joker/jade v1.0.0 // indirect github.com/Masterminds/squirrel v1.5.0 github.com/Shopify/goreferrer v0.0.0-20210407190730-c9ba3cb61340 // indirect github.com/aliyun/alibaba-cloud-sdk-go v1.61.1117 github.com/aliyun/aliyun-oss-go-sdk v2.1.8+incompatible github.com/andybalholm/brotli v1.0.3 // indirect github.com/astaxie/beego v1.12.3 github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f // indirect github.com/flosch/pongo2 v0.0.0-20200913210552-0d938eb266f3 // indirect github.com/flosch/pongo2/v4 v4.0.2 // indirect github.com/fsnotify/fsnotify v1.4.9 github.com/gavv/monotime v0.0.0-20190418164738-30dba4353424 // indirect github.com/golang/snappy v0.0.3 // indirect github.com/google/uuid v1.2.0 // indirect github.com/gorilla/schema v1.2.0 // indirect github.com/guregu/null v4.0.0+incompatible github.com/iris-contrib/formBinder v5.0.0+incompatible // indirect github.com/iris-contrib/go.uuid v2.0.0+incompatible github.com/iris-contrib/httpexpect v1.1.2 // indirect github.com/iris-contrib/middleware/jwt v0.0.0-20210110101738-6d0a4d799b5d github.com/jinzhu/gorm v1.9.16 github.com/json-iterator/go v1.1.11 // indirect github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88 // indirect github.com/kataras/golog v0.1.7 // indirect github.com/kataras/iris v11.1.1+incompatible // indirect github.com/kataras/iris/v12 v12.2.0-alpha2 github.com/mailru/easyjson v0.7.7 // indirect github.com/microcosm-cc/bluemonday v1.0.9 // indirect github.com/pkg/errors v0.9.1 github.com/satori/go.uuid v1.2.0 github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect github.com/sirupsen/logrus v1.8.1 github.com/spf13/viper v1.7.1 github.com/tdewolff/minify/v2 v2.9.17 // indirect github.com/tdewolff/parse/v2 v2.5.16 // indirect github.com/valyala/fasthttp v1.11.0 // indirect github.com/valyala/tcplisten v1.0.0 // indirect github.com/vmihailenco/msgpack/v5 v5.3.4 // indirect github.com/yudai/pp v2.0.1+incompatible // indirect golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a // indirect golang.org/x/net v0.0.0-20210525063256-abc453219eb5 // indirect golang.org/x/sys v0.0.0-20210601080250-7ecdf8ef093b // indirect golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba // indirect google.golang.org/protobuf v1.26.0 // indirect gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect )
在go.mod最后,添加如下幾行代碼,將響應的包替換為指定的版本即可。
replace ( github.com/iris-contrib/middleware/jwt => github.com/iris-contrib/middleware/jwt v0.0.0-20191219204441-78279b78a367 github.com/kataras/iris/v12 => github.com/kataras/iris/v12 v12.1.8 )
最后的go.mod內容如下:
module github.com/xxxxxx/huoxing go 1.13 require ( github.com/Joker/jade v1.0.0 // indirect github.com/Masterminds/squirrel v1.5.0 github.com/Shopify/goreferrer v0.0.0-20210407190730-c9ba3cb61340 // indirect github.com/aliyun/alibaba-cloud-sdk-go v1.61.1117 github.com/apache/thrift/lib/go/thrift v0.0.0-20210120171102-e27e82c46ba4 // indirect github.com/aliyun/aliyun-oss-go-sdk v2.1.8+incompatible github.com/andybalholm/brotli v1.0.3 // indirect github.com/astaxie/beego v1.12.3 github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f // indirect github.com/flosch/pongo2 v0.0.0-20200913210552-0d938eb266f3 // indirect github.com/flosch/pongo2/v4 v4.0.2 // indirect github.com/fsnotify/fsnotify v1.4.9 github.com/gavv/monotime v0.0.0-20190418164738-30dba4353424 // indirect github.com/golang/snappy v0.0.3 // indirect github.com/google/uuid v1.2.0 // indirect github.com/gorilla/schema v1.2.0 // indirect github.com/guregu/null v4.0.0+incompatible github.com/iris-contrib/formBinder v5.0.0+incompatible // indirect github.com/iris-contrib/go.uuid v2.0.0+incompatible github.com/iris-contrib/httpexpect v1.1.2 // indirect github.com/iris-contrib/middleware/jwt v0.0.0-20210110101738-6d0a4d799b5d github.com/jinzhu/gorm v1.9.16 github.com/json-iterator/go v1.1.11 // indirect github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88 // indirect github.com/kataras/golog v0.1.7 // indirect github.com/kataras/iris v11.1.1+incompatible // indirect github.com/kataras/iris/v12 v12.2.0-alpha2 github.com/mailru/easyjson v0.7.7 // indirect github.com/microcosm-cc/bluemonday v1.0.9 // indirect github.com/pkg/errors v0.9.1 github.com/satori/go.uuid v1.2.0 github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect github.com/sirupsen/logrus v1.8.1 github.com/spf13/viper v1.7.1 github.com/tdewolff/minify/v2 v2.9.17 // indirect github.com/tdewolff/parse/v2 v2.5.16 // indirect github.com/valyala/fasthttp v1.11.0 // indirect github.com/valyala/tcplisten v1.0.0 // indirect github.com/vmihailenco/msgpack/v5 v5.3.4 // indirect github.com/yudai/pp v2.0.1+incompatible // indirect golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a // indirect golang.org/x/net v0.0.0-20210525063256-abc453219eb5 // indirect golang.org/x/sys v0.0.0-20210601080250-7ecdf8ef093b // indirect golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba // indirect google.golang.org/protobuf v1.26.0 // indirect gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect ) replace ( github.com/iris-contrib/middleware/jwt => github.com/iris-contrib/middleware/jwt v0.0.0-20191219204441-78279b78a367 github.com/kataras/iris/v12 => github.com/kataras/iris/v12 v12.1.8 )
impala和thrift版本更新問題
2021.06.07問題更新與解決記錄。
執(zhí)行完go mod tidy后,發(fā)現(xiàn)之前正常使用的impala報錯:
github.com/bippio/go-impala/services/cli_service
..\..\..\..\pkg\mod\github.com\bippio\go-impala@v2.1.0+incompatible\services\cli_service\cli_service.go:721:37: not enough arguments in call to iprot.ReadStructBegin
have ()
want (context.Context)
..\..\..\..\pkg\mod\github.com\bippio\go-impala@v2.1.0+incompatible\services\cli_service\cli_service.go:727:57: not enough arguments in call to iprot.ReadFieldBegin
have ()
want (context.Context)
..\..\..\..\pkg\mod\github.com\bippio\go-impala@v2.1.0+incompatible\services\cli_service\cli_service.go:739:29: not enough arguments in call to iprot.Skip
have (thrift.TType)
want (context.Context, thrift.TType)
..\..\..\..\pkg\mod\github.com\bippio\go-impala@v2.1.0+incompatible\services\cli_service\cli_service.go:758:33: not enough arguments in call to iprot.ReadFieldEnd
have ()
want (context.Context)
..\..\..\..\pkg\mod\github.com\bippio\go-impala@v2.1.0+incompatible\services\cli_service\cli_service.go:762:32: not enough arguments in call to iprot.ReadStructEnd
have ()
want (context.Context)
..\..\..\..\pkg\mod\github.com\bippio\go-impala@v2.1.0+incompatible\services\cli_service\cli_service.go:769:29: not enough arguments in call to iprot.ReadI32
have ()
want (context.Context)
..\..\..\..\pkg\mod\github.com\bippio\go-impala@v2.1.0+incompatible\services\cli_service\cli_service.go:778:32: not enough arguments in call to iprot.ReadString
have ()
want (context.Context)
..\..\..\..\pkg\mod\github.com\bippio\go-impala@v2.1.0+incompatible\services\cli_service\cli_service.go:790:35: not enough arguments in call to oprot.WriteStructBegin
have (string)
want (context.Context, string)
..\..\..\..\pkg\mod\github.com\bippio\go-impala@v2.1.0+incompatible\services\cli_service\cli_service.go:796:33: not enough arguments in call to oprot.WriteFieldStop
have ()
want (context.Context)
..\..\..\..\pkg\mod\github.com\bippio\go-impala@v2.1.0+incompatible\services\cli_service\cli_service.go:798:33: not enough arguments in call to oprot.WriteStructEnd
have ()
want (context.Context)
..\..\..\..\pkg\mod\github.com\bippio\go-impala@v2.1.0+incompatible\services\cli_service\cli_service.go:798:33: too many errors
點擊去github.com\bippio\go-impala@v2.1.0+incompatible\services\cli_service\cli_service.go的第798行,是一個無參數(shù)的WriteStructEnd方法:
而再點進去WriteStructEnd方法,跳轉到thift的TProtocol接口定義,發(fā)現(xiàn)該方法是帶context.Context參數(shù)的,由此推斷應該是thift版本升級或者應用的包不當,造成與go-impala的版本不一致,使得impala中使用的函數(shù)參數(shù)及返回值發(fā)生改變,而導致異常。
將go.mod文件中require中的 github.com/apache/thrift/lib/go/thrift v0.0.0-20210120171102-e27e82c46ba4 // indirect 改為 github.com/apache/thrift v0.13.0 // indirect并將go-impala v2.1.0版本指定為v2.0.0版本,重新go mod tidy即可。
require ( ...... github.com/apache/thrift v0.13.0 // indirect ...... ) replace ( ...... github.com/bippio/go-impala => github.com/bippio/go-impala v2.0.0+incompatible ...... )
go mod使用
go mod是什么
go.mod是自golang1.11版本新引入的官方包管理工具,它主要用于解決之前沒有地方記錄依賴包具體版本的問題,相比vendor、dep等包管理工具,更加便于依賴包的管理。
go.mod其實就是一個modules,關于modules的官方定義為:
modules是相關go包的集合,是源代碼交換和版本控制的單元。
go命令直接支持使用modules,包括記錄和解析對其他模塊的依賴性。modules替換golang舊版本中基于GOPATH的方式,來指定使用哪些源文件。
modules和傳統(tǒng)的GOPATH不同,不需要包含例如src,bin這樣的子目錄,一個源代碼目錄甚至是空目錄都可以作為modules,只要其中包含有go.mod文件。
如何使用go.mod
1.首先將go的版本升級為1.11及以上
2.設置GO111MODULE
GO111MODULE有三個值:off, on和auto(默認值)。
- GO111MODULE=off,go命令行將不會支持module功能,尋找依賴包的方式將會沿用舊版本那種通過vendor目錄或者GOPATH模式來查找。
- GO111MODULE=on,go命令行會使用modules,不會去GOPATH目錄下查找。
- GO111MODULE=auto,默認值,使用該方式時,go命令行將會根據(jù)當前目錄來決定是否啟用module功能。
包的版本控制
在使用go build、go test、go list、go tidy等命令時,go會自動更新go.mod文件,將項目依賴的包、包版本等依賴關系寫入該文件。
使用mod進行包管理的另外一項重要功能就是包的版本控制。go.mod文件中的依賴內容,如下:
require ( github.com/Shopify/goreferrer v0.0.0-20210407190730-c9ba3cb61340 // indirect github.com/aliyun/alibaba-cloud-sdk-go v1.61.1117 github.com/aliyun/aliyun-oss-go-sdk v2.1.8+incompatible github.com/andybalholm/brotli v1.0.3 // indirect github.com/astaxie/beego v1.12.3 )
go.mod require括號里面的前面部分是包的名字,也就是項目package包中import時需要導入的依賴部分,而空格之后的是版本號,版本號遵循如下規(guī)律:
vX.Y.Z-pre.0.yyyymmddhhmmss-abcdefabcdef vX.0.0-yyyymmddhhmmss-abcdefabcdef vX.Y.(Z+1)-0.yyyymmddhhmmss-abcdefabcdef vX.Y.Z
也就是:版本號-時間戳-hash,當自己想要使用具體的版本時只需要指定版本號即可,沒有版本tag的則需要找到對應commit的時間和hash值。而默認使用的是最新版本的package。
當前最新的iris版本為v12.2.0-alpha2,如果想使用v12.1.8版本的iris,需要怎么辦呢?
只需要如下命令:
go mod edit -require="github.com/kataras/iris/v12@v12.1.8"
但是,這種方式,在下一次使用go tidy更新依賴關系的時候,又會更新成最新版本的iris,那么需要怎么辦呢?
這就需要配合replace命令,將特定包替換為指定的版本號,參看下面小節(jié)"在go-mod中指定包的版本號"。
在go-mod中指定包的版本號
在go.mod中,使用replace指定包版本號。比如將google.golang.org/grpc最新版本替換為指定的v1.26.0,可以在go.mod的最后面,添加如下信息:
replace google.golang.org/grpc => google.golang.org/grpc v1.26.0
然后,再運行go run或go build即可。
go mod常用命令
go.mod 提供了module、require、replace和exclude 四種管理包及依賴的方式。
- module 語句,表示指定包的名字(項目路徑)
- require 語句,表示項目指定的依賴項模塊
- replace 語句,表示可以替換的依賴項模塊
- exclude 語句,表示可以忽略依賴項模塊
使用go mod管理go包時,主要有以下一些命令:
其中,最常使用的命令有go init、go tidy等。
$go mod init 項目路徑 go mod init初始化go.mod文件,go.mod文件一旦創(chuàng)建后,它的內容將會被go toolchain全面掌控。go toolchain會在各類命令執(zhí)行時,比如go get、go build、go mod等修改和維護go.mod文件。 $go mod tidy go mod tidy 命令,刪除go.mod中不需要的依賴、新增需要的依賴。使用該命令,項目中需要的依賴會自動生成 require 語句
總結
以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
Jaeger?Client?Go入門并實現(xiàn)鏈路追蹤
這篇文章介紹了Jaeger?Client?Go入門并實現(xiàn)鏈路追蹤的方法,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-03-03