新聞中心
本文由
golang教程欄目給大家介紹怎么用 GIN 構(gòu)建一個(gè) web 服務(wù),希望對(duì)需要的朋友有所幫助!

創(chuàng)新互聯(lián)專注于湟源網(wǎng)站建設(shè)服務(wù)及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗(yàn)。 熱誠(chéng)為您提供湟源營(yíng)銷型網(wǎng)站建設(shè),湟源網(wǎng)站制作、湟源網(wǎng)頁(yè)設(shè)計(jì)、湟源網(wǎng)站官網(wǎng)定制、小程序制作服務(wù),打造湟源網(wǎng)絡(luò)公司原創(chuàng)品牌,更為您提供湟源網(wǎng)站排名全網(wǎng)營(yíng)銷落地服務(wù)。
快速啟動(dòng)一個(gè) api
目錄
├── api \\ 服務(wù)入口 ├── cmd \\ 服務(wù)啟動(dòng)入口 ├── config ├── doc └── chaper1.md├── go.mod ├── internal \\ 業(yè)務(wù)邏輯 ├── main.go ├── pkg \\ 三方包初始化 └── router \\ Api 路由
GIN && Cobra
一般 WEB 服務(wù),都會(huì)包含多個(gè)模塊: API 接口、定時(shí)任務(wù)、消費(fèi) MQ 常駐進(jìn)程等等,在這種情況下,很顯然直接使用 GIN 來(lái)啟動(dòng)就只能開(kāi)啟 API 模塊,十分不便。
我們用 Cobra 來(lái)管理項(xiàng)目的啟動(dòng),現(xiàn)在不用關(guān)心 Cobra 如何使用,現(xiàn)在要的是滿足我們需求。
初始化一個(gè) rootCmd 來(lái)管理項(xiàng)目中所有的模塊
// main.go
func main() {
cmd.Execute()}
// cmd/root.go
var rootCmd = &cobra.Command{
Use: "提供WebApi服務(wù)", Short: "webApi",}
func init() {
rootCmd.AddCommand(apiCmd)}
func Execute() {
if err := rootCmd.Execute(); err != nil { fmt.Println("[錯(cuò)誤]啟動(dòng)失敗:", err) }}
// cmd/api.go
var httpServer *http.Server
var apiCmd = &cobra.Command {
Use: "api",
Short: "apiCmd",
Long: `apiCmd 提供api接口服務(wù)`,
Run: func(cmd *cobra.Command, args []string) {
address := fmt.Sprintf("%v:%v", "0.0.0.0", 8080)
engine := gin.New()
httpServer = &http.Server{
Addr: address,
Handler: engine,
IdleTimeout: time.Minute,
}
if err := httpServer.ListenAndServe(); err != nil && err != http.ErrServerClosed {
fmt.Println("啟動(dòng)失敗", err)
}},
}
}
這個(gè)時(shí)候啟動(dòng)一下, 可以看到需要傳一個(gè)命令行參數(shù):
gin-web-layout git:(master) go run main.go webApi Usage: 提供WebApi服務(wù) [command] Available Commands: api apiCmd completion Generate the autocompletion script for the specified shell help Help about any command
使用 go run main.go api 就可以啟動(dòng)服務(wù)了
gin-web-layout git:(master) go run main.go api [GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production. - using env: export GIN_MODE=release - using code: gin.SetMode(gin.ReleaseMode)
首先開(kāi)始接入路由, 所見(jiàn)即所得,能快速的看到自己寫(xiě)的成果
router/router.go
func InitRouter(engine *gin.Engine) {
engine.GET("/", func(c *gin.Context) { c.JSON(200, "ok") })}
在 cmd/api.go 增加以下代碼
engine := gin.New()
router.InitRouter(engine)
這樣一個(gè) hello world 就完成了,這個(gè)也是 gin 快速開(kāi)始的內(nèi)容。 啟動(dòng)后訪問(wèn)一下:
gin-web-layout git:(master) curl http://0.0.0.0:8080 "ok"%
這個(gè)時(shí)候我們來(lái)完善一下啟動(dòng)模塊的代碼,加上平滑重啟,設(shè)置 5 秒后退出
// cmd/api.go
// 只展示核心代碼,完整代碼可以在 github 查看
// 等待 5 秒 timeout = 5 *time.sencond
func OnServiceStop(timeout time.Duration) {
quit := make(chan os.Signal)
signal.Notify(quit, signals.Get()...)
<-quit
ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()
err := httpServer.Shutdown(ctx)
if err != nil {
log.Fatalf("service stop error:%v", err)
}
log.Println("service is stopping")
}
這樣就支持了熱啟動(dòng),然后就編譯啟動(dòng),ctrl+c, 他為什么沒(méi)阻塞 5 秒,直接就退出了?
因?yàn)?ctrl+c 的時(shí)候,會(huì)檢查是否有待處理的請(qǐng)求,如沒(méi)有就會(huì)直接退出。我們可以模擬一個(gè)耗時(shí)請(qǐng)求:
// router/router.go
engine.GET("/", func(c *gin.Context) {
time.Sleep(5 * time.Second)
c.JSON(200, "ok")
})
重新啟動(dòng)后,再次 ctrl+c 會(huì)發(fā)現(xiàn) 5 秒后項(xiàng)目才退出完成。
題外話,線上的服務(wù)是如何發(fā)布部署的?
一般線上服務(wù)都會(huì)用網(wǎng)關(guān)調(diào)度流量,當(dāng)我們一個(gè)服務(wù)接受到 kill(重啟腳本一般用 kill,殺掉 pid) 信號(hào),就不再接受新請(qǐng)求。
這一點(diǎn)可以用我們剛配置的熱重啟驗(yàn)證一下,把 timeout 設(shè)置 10s, 偽造一個(gè)耗時(shí) 10s 的請(qǐng)求,啟動(dòng)后執(zhí)行退出(用 ctrl+c 或者 kill, 本質(zhì)都是發(fā)送一個(gè)信號(hào)), 然后再訪問(wèn)服務(wù),
會(huì)得到
gin-web-layout git:(master) curl http://0.0.0.0:8080 curl: (7) Failed to connect to 0.0.0.0 port 8080: Connection refused
網(wǎng)關(guān)和服務(wù)會(huì)有心跳監(jiān)測(cè),無(wú)法提供服務(wù)后,網(wǎng)關(guān)自動(dòng)踢掉服務(wù),不再發(fā)流量,待恢復(fù)后再重新發(fā)流量。但是實(shí)際部署部署是另有方案,因?yàn)樾奶怯虚g隔的,這個(gè)間隔期間服務(wù)退出了,就會(huì)造成大量的 502
分享名稱:教你用GIN構(gòu)建一個(gè)WEB服務(wù)
網(wǎng)頁(yè)地址:http://m.fisionsoft.com.cn/article/ccoesog.html


咨詢
建站咨詢
