急如閃電快如風,彩虹女神躍長空,Go語言高性能Web框架Iris項目實戰-初始化項目ep00
在Golang Web編程的世界裏,君不言高性能則已,言高性能必稱Iris。彩虹女神的名號響徹寰宇、名動江湖,單論一個快字,無人能出其右,就連以簡潔輕量著稱於世的Gin也難以望其項背,只見彩虹女神Iris回眸一笑撩人心扉:「雖然你們也不是那麼慢,但我還是快那麼一點點……」,本次就讓我們來一睹彩虹女神Iris的芳顏,感受宇宙最快Web框架的神乎其神。
女神本神(Iris)
選擇一款框架有諸多的參考層面,比如靈活性、擴展性、API友好程度、文檔詳細程度、項目活躍度、社區貢獻等等,但是性能和內存佔用絕對是優先參考的一個重要層面,原因無他,天下武功,唯快不破,正所謂一快遮百丑,經濟下行,降本增效的大背景之下,高性能框架無疑佔據極大的優勢,說白了,成本相仿的前提下,我單位時間內網絡請求吞吐量是你的一倍,還沒用力,你就倒下了,你怎麼跟我打?遊戲還沒開始,就已經結束了。
空口白牙,不足為據,參見2022年最新請求吞吐量對比圖:
事實上,Iris本質上也是社區驅動的Go語言Web框架,支持http2/3,完備的MVC支持,奉行極簡主義風格,輕量化與簡明風格比起Gin來說,也不遑多讓,與此同時,社區活躍度和文檔支持都非常到位,但其擁有的極其恐怖的高性能特性,其他框架則是望塵莫及。在Iris身上,我們可以看到她對性能的近乎於偏執的完美追求,Iris為了優化性能,不惜自己開發和集成最快的組件,比如日誌記錄內置了golog模塊,比如json序列化就選擇了第三方庫jsoniter,從框架設計的態度上,極盡完美之能事。
建立項目IrisBlog
參照Iris官網文檔://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=//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: //localhost:5000
Application started. Press CTRL+C to shut down.
還等什麼?訪問//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: //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: //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開發萬里長征的第一步,山高路遠,城高池深,雖然前路艱險,但就算是莽撞地開始,拙劣地完成,也好過眼高手低而不去做,你同意嗎?