开始使用 gin

hanzkering · · 5413 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

# 使用 gin ## 使用 go module 要求 Go version >= 1.13 或者 Go version >= 1.11 同时将 `GO111MODULE=on` 开启。 ### 初始化 go module 创建项目目录,任意目录即可不必在 GOPATH/src 目录,并进入项目目录 ```shell mkdir ginProj cd ginProj ``` 执行 `go mod init moduleName` 初始化 go module 项目: ``` $ go mod init ginProj go: creating new go.mod: module ginProj ``` 其中 ginProj 是自定义的 moduleName,本例与目录一致,其实是任意名称。 ### 编写 main.main() 利用编辑器(推荐 GoLand),创建 `ginProj/main.go` 文件,并写入如下代码: ```go package main import "github.com/gin-gonic/gin" func main() { r := gin.Default() r.GET("/ping", func(c *gin.Context) { c.JSON(200, gin.H{ "message": "pong", }) }) r.Run() // 监听并在 0.0.0.0:8080 上启动服务 } ``` ### 运行 直接运行 `go run main.go` 即可。 ```shell $ go run main.go [GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached. [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) [GIN-debug] GET /ping --> main.main.func1 (3 handlers) [GIN-debug] Environment variable PORT is undefined. Using port :8080 by default [GIN-debug] Listening and serving HTTP on :8080 exit status 2 ``` 表示运行成功。 通过浏览器或者其他请求工具(例如 postman,curl 等),访问 localhost:8080/ping 即可获取 JSON 数据格式响应 `{"message": "pong"}`。 ## GOPATH ### 安装 利用 go get 完成下载安装。 ```shell $ go get -u github.com/gin-gonic/gin ``` ### 编写 main.main() 在 GOPATH/src 目录创建项目目录,例如 ginProj,利用编辑器(推荐 GoLand),创建 `ginProj/main.go` 文件,并写入如下代码: ```go package main import "github.com/gin-gonic/gin" func main() { r := gin.Default() r.GET("/ping", func(c *gin.Context) { c.JSON(200, gin.H{ "message": "pong", }) }) r.Run() // 监听并在 0.0.0.0:8080 上启动服务 } ``` ### 运行 直接运行 `go run main.go` 即可。 ```shell $ go run main.go [GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached. [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) [GIN-debug] GET /ping --> main.main.func1 (3 handlers) [GIN-debug] Environment variable PORT is undefined. Using port :8080 by default [GIN-debug] Listening and serving HTTP on :8080 exit status 2 ``` 表示运行成功。 通过浏览器或者其他请求工具(例如 postman,curl 等),访问 localhost:8080/ping 即可获取 JSON 数据格式响应 `{"message": "pong"}`。 ## 构建发布 直接运行 `go run main.go` 会先编译再运行。在生产部署时,应该先编译形成可执行性文件,再运行可执行性文件。使用命令 go build 完成: ```shell $ go build -o backend main.go ./backend ``` 以上命令会编译生成 backend 执行文件,若省略 -o 选项,默认生成 main 执行文件。 在生成环境部署时,应该使用 `releaseMode` 发布模式,代码中默认使用的为 `debug` 调试模式,调用函数 `gin.SetMode(gin.ReleaseMode)` 可设置为发布模式。在 main.go 中: ```go func main() { // 设置为发布模式 gin.SetMode(gin.ReleaseMode) /* 其他代码 */ r.Run() // 监听并在 0.0.0.0:8080 上启动服务 } ``` 发布模式会减少一些调试输出和做出一些特定优化等,例如路由日志在发布模式下就不会输出到终端。 ## 推荐目录结构 gin 框架对于项目目录结构没有要求,只要符合典型的包管理机制即可。根据典型的 MVC 框架的代码架构,建议的目录结构为: ``` /main.go 入口文件 /config/ 配置 /router/ 路由 api.go web.go /handler/ 请求处理器 user.go /middleware/ 中间件 jwtToken.go /model/ 模型 user.go /test/ 测试 ``` 以上结构是推荐而不是强制的。 ## 停止监听 ### 暴力停止 我们在 go run main.go 后,若需要停止监听,需要使用 `ctrl+c` 终止监听。该方案会立即终止服务器监听,同时结束正在处理的请求,也就是说若存在未处理完毕的请求,是不能继续处理的。 ### 优雅停止 代替示例代码中 `router.Run()` 方法,我们可以使用 `http.Server` 内置的 [Shutdown()](https://golang.org/pkg/net/http/#Server.Shutdown) 方法优雅地停止。所谓优雅,指的是可以将正在处理的请求处理完毕后再关闭服务器。示例代码如下 main.go : ```go package main import ( "context" "log" "net/http" "os" "os/signal" "time" "github.com/gin-gonic/gin" ) func main() { // 常规的初始化路由 router := gin.Default() router.GET("/", func(c *gin.Context) { time.Sleep(5 * time.Second) c.String(http.StatusOK, "Welcome Gin Server") }) // 定义服务器 srv := &http.Server{ Addr: ":8080", Handler: router, } // 利用 goroutine 启动监听 go func() { // srv.ListenAndServe() 监听 if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed { log.Fatalf("listen: %s\n", err) } }() // 等待中断信号以优雅地关闭服务器(设置 5 秒的超时时间) quit := make(chan os.Signal) signal.Notify(quit, os.Interrupt) // quit 信道是同步信道,若没有信号进来,处于阻塞状态 // 反之,则执行后续代码 <-quit log.Println("Shutdown Server ...") ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() // 调用 srv.Shutdown() 完成优雅停止 // 调用时传递了一个上下文对象,对象中定义了超时时间 if err := srv.Shutdown(ctx); err != nil { log.Fatal("Server Shutdown:", err) } log.Println("Server exiting") } ``` 以上代码的思路是:主 goroutine 用于监听信号,若进来信号则优雅停止。而调用的 goroutine 用于监听 HTTP 请求。 测试以上代码,结果为: ```shell $ go run main.go [GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached. [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) [GIN-debug] GET / --> main.main.func1 (3 handlers) 2019/11/05 22:49:04 Shutdown Server ... [GIN] 2019/11/05 - 22:49:07 | 200 | 5.0000438s | ::1 | GET / 2019/11/05 22:49:08 Server exiting ``` 本例测试中,请求处理器增加一个 5s 的延迟,我们用请求代理端进行请求,在服务器响应完成前,通过 `ctrl+c` 关闭服务器。测试服务器还是会将该请求处理完毕,再关闭!优雅不? > 关注 红牛慕课,或访问 [红牛慕课](http://www.hellokang.net/gin/) ![subscribe_gin.png](https://static.studygolang.com/191104/01cd42a58db0c53d411315ca5d845f85.png)

有疑问加站长微信联系(非本文作者))

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

5413 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传