急如閃電快如風,彩虹女神躍長空,Go語言高效能Web框架Iris專案實戰-初始化專案ep00

語言: CN / TW / HK

在Golang Web程式設計的世界裡,君不言高效能則已,言高效能必稱Iris。彩虹女神的名號響徹寰宇、名動江湖,單論一個快字,無人能出其右,就連以簡潔輕量著稱於世的Gin也難以望其項背,只見彩虹女神Iris回眸一笑撩人心扉:“雖然你們也不是那麼慢,但我還是快那麼一點點......”,本次就讓我們來一睹彩虹女神Iris的芳顏,感受宇宙最快Web框架的神乎其神。

女神本神(Iris)

選擇一款框架有諸多的參考層面,比如靈活性、擴充套件性、API友好程度、文件詳細程度、專案活躍度、社群貢獻等等,但是效能和記憶體佔用絕對是優先參考的一個重要層面,原因無他,天下武功,唯快不破,正所謂一快遮百醜,經濟下行,降本增效的大背景之下,高效能框架無疑佔據極大的優勢,說白了,成本相仿的前提下,我單位時間內網路請求吞吐量是你的一倍,還沒用力,你就倒下了,你怎麼跟我打?遊戲還沒開始,就已經結束了。

空口白牙,不足為據,參見2022年最新請求吞吐量對比圖:

事實上,Iris本質上也是社群驅動的Go語言Web框架,支援http2/3,完備的MVC支援,奉行極簡主義風格,輕量化與簡明風格比起Gin來說,也不遑多讓,與此同時,社群活躍度和文件支援都非常到位,但其擁有的極其恐怖的高效能特性,其他框架則是望塵莫及。在Iris身上,我們可以看到她對效能的近乎於偏執的完美追求,Iris為了優化效能,不惜自己開發和整合最快的元件,比如日誌記錄內建了golog模組,比如json序列化就選擇了第三方庫jsoniter,從框架設計的態度上,極盡完美之能事。

建立專案IrisBlog

參照Iris官網文件: https://github.com/kataras/iris/blob/master/README_ZH.md,我們藉助彩虹女神Iris的垂愛,打造一款史上最快的線上部落格系統,首先建立資料夾IrisBlog:

mkdir IrisBlog
cd IrisBlog

隨後通過go mod命令初始化專案:

C:\Users\liuyue\www\iriblog>go mod init IrisBlog  
go: creating new go.mod: module IrisBlog

對於go mod不熟的朋友,請移玉步至 層次分明井然有條,Go lang1.18入門精煉教程,由白丁入鴻儒,Go lang包管理機制(package)EP10 ,關於go mod的使用,這裡不再贅述。

接著,由於諸位可以理解的原因,請確保使用國內的安裝源:

go env -w GOPROXY=https://goproxy.cn,direct

隨後安裝彩虹女神Iris:

go get -u github.com/kataras/iris

系統返回:

C:\Users\liuyue\www\iriblog>go get -u github.com/kataras/iris  
go: downloading github.com/kataras/iris v0.0.2  
go: downloading github.com/BurntSushi/toml v0.3.1  
go: downloading github.com/kataras/golog v0.0.18  
go: downloading github.com/kataras/pio v0.0.8  
go: downloading github.com/kataras/sitemap v0.0.5  
go: downloading github.com/BurntSushi/toml v1.2.0  
go: downloading github.com/kataras/tunnel v0.0.1  
go: downloading github.com/kataras/golog v0.1.7  
go: downloading github.com/kataras/pio v0.0.10  
go: downloading gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776  
go: downloading github.com/kataras/tunnel v0.0.4  
go: downloading gopkg.in/yaml.v3 v3.0.1  
go: downloading github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398  
go: downloading github.com/fatih/structs v1.1.0  
go: downloading github.com/andybalholm/brotli v1.0.1-0.20200619015827-c3da72aa01ed  
go: downloading github.com/iris-contrib/schema v0.0.2  
go: downloading github.com/andybalholm/brotli v1.0.4  
go: downloading github.com/iris-contrib/schema v0.0.6  
go: downloading github.com/json-iterator/go v1.1.10  
go: downloading github.com/Shopify/goreferrer v0.0.0-20220729165902-8cddb4f5de06  
go: downloading github.com/klauspost/compress v1.10.10  
go: downloading github.com/klauspost/compress v1.15.9  
go: downloading github.com/microcosm-cc/bluemonday v1.0.3  
go: downloading github.com/russross/blackfriday/v2 v2.0.1  
go: downloading github.com/vmihailenco/msgpack/v5 v5.0.0-beta.1  
go: downloading golang.org/x/net v0.0.0-20200707034311-ab3426394381  
go: downloading github.com/russross/blackfriday v1.5.2  
go: downloading github.com/vmihailenco/msgpack v4.0.4+incompatible  
go: downloading github.com/microcosm-cc/bluemonday v1.0.19  
go: downloading github.com/vmihailenco/msgpack/v5 v5.3.5  
go: downloading golang.org/x/text v0.3.3  
go: downloading golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e  
go: downloading github.com/russross/blackfriday/v2 v2.1.0  
go: downloading github.com/russross/blackfriday v1.6.0  
go: downloading google.golang.org/protobuf v1.25.0  
go: downloading golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9  
go: downloading golang.org/x/net v0.0.0-20220812174116-3211cb980234  
go: downloading google.golang.org/protobuf v1.28.1  
go: downloading golang.org/x/text v0.3.7  
go: downloading golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de  
go: downloading golang.org/x/sys v0.0.0-20200808120158-1030fc2bf1d9  
go: downloading github.com/schollz/closestmatch v2.1.0+incompatible  
go: downloading golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa  
go: downloading golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab  
go: downloading gopkg.in/ini.v1 v1.57.0  
go: downloading gopkg.in/ini.v1 v1.67.0  
go: downloading github.com/ryanuber/columnize v2.1.0+incompatible  
go: downloading github.com/CloudyKit/jet/v4 v4.1.0  
go: downloading github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible  
go: downloading github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385  
go: downloading github.com/ryanuber/columnize v2.1.2+incompatible  
go: downloading github.com/iris-contrib/jade v1.1.4  
go: downloading github.com/CloudyKit/jet v2.1.2+incompatible  
go: downloading github.com/iris-contrib/pongo2 v0.0.1  
go: downloading github.com/kataras/blocks v0.0.2  
go: downloading github.com/yosssi/ace v0.0.5  
go: downloading github.com/kataras/blocks v0.0.6  
go: downloading github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742  
go: downloading github.com/chris-ramon/douceur v0.2.0  
go: downloading github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd  
go: downloading github.com/vmihailenco/tagparser v0.1.1  
go: downloading google.golang.org/appengine v1.6.5  
go: downloading github.com/vmihailenco/tagparser v0.1.2  
go: downloading github.com/shurcooL/sanitized_anchor_name v1.0.0  
go: downloading google.golang.org/appengine v1.6.7  
go: downloading github.com/google/uuid v1.1.2-0.20200519141726-cb32006e483f  
go: downloading github.com/google/uuid v1.3.0  
go: downloading github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53  
go: downloading github.com/valyala/bytebufferpool v1.0.0  
go: downloading github.com/aymerick/douceur v0.2.0  
go: downloading github.com/gorilla/css v1.0.0  
go: downloading github.com/golang/protobuf v1.4.1  
go: downloading github.com/golang/protobuf v1.5.2  
go: downloading github.com/vmihailenco/tagparser/v2 v2.0.0  
go: added github.com/BurntSushi/toml v1.2.0  
go: added github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53  
go: added github.com/CloudyKit/jet/v4 v4.1.0  
go: added github.com/Shopify/goreferrer v0.0.0-20220729165902-8cddb4f5de06  
go: added github.com/andybalholm/brotli v1.0.4  
go: added github.com/aymerick/douceur v0.2.0  
go: added github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible  
go: added github.com/chris-ramon/douceur v0.2.0  
go: added github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385  
go: added github.com/fatih/structs v1.1.0  
go: added github.com/golang/protobuf v1.5.2  
go: added github.com/google/uuid v1.3.0  
go: added github.com/gorilla/css v1.0.0  
go: added github.com/iris-contrib/jade v1.1.4  
go: added github.com/iris-contrib/pongo2 v0.0.1  
go: added github.com/iris-contrib/schema v0.0.6  
go: added github.com/json-iterator/go v1.1.12  
go: added github.com/kataras/blocks v0.0.6  
go: added github.com/kataras/golog v0.1.7  
go: added github.com/kataras/iris v0.0.2  
go: added github.com/kataras/pio v0.0.10  
go: added github.com/kataras/sitemap v0.0.5  
go: added github.com/kataras/tunnel v0.0.4  
go: added github.com/klauspost/compress v1.15.9  
go: added github.com/microcosm-cc/bluemonday v1.0.19  
go: added github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd  
go: added github.com/modern-go/reflect2 v1.0.2  
go: added github.com/russross/blackfriday/v2 v2.1.0  
go: added github.com/ryanuber/columnize v2.1.2+incompatible  
go: added github.com/schollz/closestmatch v2.1.0+incompatible  
go: added github.com/shurcooL/sanitized_anchor_name v1.0.0  
go: added github.com/valyala/bytebufferpool v1.0.0  
go: added github.com/vmihailenco/msgpack/v5 v5.3.5  
go: added github.com/vmihailenco/tagparser v0.1.2  
go: added github.com/vmihailenco/tagparser/v2 v2.0.0  
go: added github.com/yosssi/ace v0.0.5  
go: added golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa  
go: added golang.org/x/net v0.0.0-20220812174116-3211cb980234  
go: added golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab  
go: added golang.org/x/text v0.3.7  
go: added golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9  
go: added google.golang.org/appengine v1.6.7  
go: added google.golang.org/protobuf v1.28.1  
go: added gopkg.in/ini.v1 v1.67.0  
go: added gopkg.in/yaml.v3 v3.0.1

安裝完畢之後,可以開啟專案中go.mod檔案檢視Iris的依賴列表:

module IrisBlog  
  
go 1.18  
  
require (  
	github.com/BurntSushi/toml v1.2.0 // indirect  
	github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53 // indirect  
	github.com/CloudyKit/jet/v4 v4.1.0 // indirect  
	github.com/CloudyKit/jet/v6 v6.1.0 // indirect  
	github.com/Shopify/goreferrer v0.0.0-20220729165902-8cddb4f5de06 // indirect  
	github.com/andybalholm/brotli v1.0.4 // indirect  
	github.com/aymerick/douceur v0.2.0 // indirect  
	github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible // indirect  
	github.com/chris-ramon/douceur v0.2.0 // indirect  
	github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385 // indirect  
	github.com/fatih/structs v1.1.0 // indirect  
	github.com/flosch/pongo2/v4 v4.0.2 // indirect  
	github.com/golang/protobuf v1.5.2 // indirect  
	github.com/golang/snappy v0.0.4 // indirect  
	github.com/google/uuid v1.3.0 // indirect  
	github.com/gorilla/css v1.0.0 // indirect  
	github.com/iris-contrib/jade v1.1.4 // indirect  
	github.com/iris-contrib/pongo2 v0.0.1 // indirect  
	github.com/iris-contrib/schema v0.0.6 // indirect  
	github.com/josharian/intern v1.0.0 // indirect  
	github.com/json-iterator/go v1.1.12 // indirect  
	github.com/kataras/blocks v0.0.6 // indirect  
	github.com/kataras/golog v0.1.7 // indirect  
	github.com/kataras/iris v0.0.2 // indirect  
	github.com/kataras/iris/v12 v12.2.0-beta4.0.20220813060700-f91269130ed3 // indirect  
	github.com/kataras/pio v0.0.10 // indirect  
	github.com/kataras/sitemap v0.0.5 // indirect  
	github.com/kataras/tunnel v0.0.4 // indirect  
	github.com/klauspost/compress v1.15.9 // indirect  
	github.com/mailgun/raymond/v2 v2.0.46 // indirect  
	github.com/mailru/easyjson v0.7.7 // indirect  
	github.com/microcosm-cc/bluemonday v1.0.19 // indirect  
	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect  
	github.com/modern-go/reflect2 v1.0.2 // indirect  
	github.com/russross/blackfriday/v2 v2.1.0 // indirect  
	github.com/ryanuber/columnize v2.1.2+incompatible // indirect  
	github.com/schollz/closestmatch v2.1.0+incompatible // indirect  
	github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect  
	github.com/sirupsen/logrus v1.8.1 // indirect  
	github.com/tdewolff/minify/v2 v2.12.0 // indirect  
	github.com/tdewolff/parse/v2 v2.6.1 // indirect  
	github.com/valyala/bytebufferpool v1.0.0 // indirect  
	github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect  
	github.com/vmihailenco/tagparser v0.1.2 // indirect  
	github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect  
	github.com/yosssi/ace v0.0.5 // indirect  
	golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa // indirect  
	golang.org/x/net v0.0.0-20220812174116-3211cb980234 // indirect  
	golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab // indirect  
	golang.org/x/text v0.3.7 // indirect  
	golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9 // indirect  
	google.golang.org/appengine v1.6.7 // indirect  
	google.golang.org/protobuf v1.28.1 // indirect  
	gopkg.in/ini.v1 v1.67.0 // indirect  
	gopkg.in/yaml.v3 v3.0.1 // indirect  
)

接著在專案的根目錄建立main入口檔案:

package main  
  
import "github.com/kataras/iris/v12"  
  
func main() {  
  app := iris.New()  
  app.Use(iris.Compression)  
  
  app.Get("/", func(ctx iris.Context) {  
    ctx.HTML("你好 <strong>%s</strong>!", "女神")  
  })  
  
  app.Listen(":5000")  
}

隨後在終端啟動Iris服務:

go run main.go

系統返回:

Iris Version: 12.2.0-beta4  
  
Now listening on: http://localhost:5000  
Application started. Press CTRL+C to shut down.

還等什麼?訪問http://localhost:5000

萬喚千呼始出來。

使用快捷鍵control+C可以終止服務,隨後可以再次執行go run main.go來重新編譯啟動服務。

Iris專案熱重啟機制:fresh

眾所周知,由於Go lang是編譯型語言,每次修改程式碼之後都需要重新編譯,Iris目前沒有內建程式碼熱更新的工具,這裡我們可以使用三方包:fresh,如此,可以大幅提高我們的Iris開發效率,在非專案目錄執行命令:

go get github.com/pilu/fresh

注意,這裡一定不能在專案的目錄中執行安裝命令,因為go mod模式會認為是專案依賴包,而不會在當前系統的bin目錄下生成可執行命令fresh。

隨後進入專案目錄:

cd IrisBlog

使用fresh命令啟動Iris服務:

C:\Users\liuyue\www\iriblog>fresh  
0:19:33 runner      | InitFolders  
0:19:33 runner      | mkdir ./tmp  
0:19:33 watcher     | Watching .  
0:19:33 main        | Waiting (loop 1)...  
0:19:33 main        | receiving first event /  
0:19:33 main        | sleeping for 600 milliseconds  
0:19:33 main        | flushing events  
0:19:33 main        | Started! (5 Goroutines)  
0:19:33 main        | remove tmp\runner-build-errors.log: The system cannot find the file specified.  
0:19:33 build       | Building...  
0:19:44 runner      | Running...  
0:19:45 main        | --------------------  
0:19:45 main        | Waiting (loop 2)...  
0:19:46 app         | Iris Version: 12.2.0-beta4  
0:19:46 app         |  
0:19:46 app         | Now listening on: http://localhost:5000  
Application started. Press CTRL+C to shut down.

此時,專案內所有包檔案都會被監控,當代碼被修改後,會自動觸發編譯動作,原理大概相當於Python中Tornado框架的事件迴圈機制。

當我們修改程式碼之後,fresh會監控到修改動作,然後立刻build:

Application started. Press CTRL+C to shut down.  
0:28:02 watcher     | sending event ".\\main.go": MODIFY  
0:28:02 watcher     | sending event ".\\main.go": MODIFY  
0:28:02 main        | receiving first event ".\\main.go": MODIFY  
0:28:02 main        | sleeping for 600 milliseconds  
0:28:02 main        | flushing events  
0:28:02 main        | receiving event ".\\main.go": MODIFY  
0:28:02 main        | Started! (8 Goroutines)  
0:28:02 main        | remove tmp\runner-build-errors.log: The system cannot find the file specified.  
0:28:02 build       | Building...  
0:28:10 runner      | Running...  
0:28:10 runner      | Killing PID 11276  
0:28:11 main        | --------------------  
0:28:11 main        | Waiting (loop 3)...  
0:28:12 app         | Iris Version: 12.2.0-beta4  
0:28:12 app         |  
Now listening on: http://localhost:5000  
Application started. Press CTRL+C to shut down.

如此,就不需要手動觸發程式碼的編譯了,簡單方便。

如果有定製化需求,可以為當前專案新增配置檔案runner.conf:

root:              .  
tmp_path:          ./fresh  
build_name:        runner_build  
build_log:         runner_build_errors.log  
valid_ext:         .go, .tpl, .tmpl, .html, .md, .log  
no_rebuild_ext:    .tpl, .tmpl, .html  
ignored:           assets, tmp, log  
build_delay:       3000  
colors:            1  
log_color_main:    cyan  
log_color_build:   yellow  
log_color_runner:  green  
log_color_watcher: magenta  
log_color_app:     red

可以定製化諸如監聽的檔案、編譯日誌、忽略檔案和目錄,編譯延遲等等操作。

修改定製化配置檔案後,針對配置檔案啟動fresh服務:

fresh -c runner.conf

如此,fresh服務會根據配置檔案來進行監聽編譯動作。

結語

最低的系統資源開銷,最高的單位時間網路請求吞吐量,這是彩虹女神Iris對開發者們最好的饋贈,當我們安裝好Iris並且配置好熱重啟機制時,我們也就走下了Go語言web開發萬里長征的第一步,山高路遠,城高池深,雖然前路艱險,但就算是莽撞地開始,拙劣地完成,也好過眼高手低而不去做,你同意嗎?