github.com/gin-gonic/gin的源码学习

先创建一个简单的demo,执行后的调用链路在这里

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()
}

运行后,请求一下127.0.0.1:8080/ping 最终的调用链路如下:

|-goroutine-1 created by runtime.main
  |-main.main
    |-github.com/gin-gonic/gin.Default
      |-engine.Use(Logger(), Recovery())                   // 注册了两个中间件 
    |-github.com/gin-gonic/gin.(*RouterGroup).handle
    |-github.com/gin-gonic/gin.(*Engine).Run
      |-github.com/gin-gonic/gin.resolveAddress
      |-net/http.ListenAndServe(address, engine.Handler()) // 这里最终还是用的net/http包起的服务
                                                           // 不同的是serverMux使用的自定义的
                                                           // engine.Handler()

|-goroutine-18 created by net/http.(*Server).Serve.func3
  |-net/http.(*conn).serve
    |-net/http.(*conn).readRequest
    |-net/http.serverHandler.ServeHTTP
      |-github.com/gin-gonic/gin.(*Engine).ServeHTTP
        |-sync.(*Pool).Get                                  // 循环利用context对象内存
        |-github.com/gin-gonic/gin.(*Engine).handleHTTPRequest
          |-root := engine.trees[i].root                    // 匹配对应请求类型的tree
          |-value := root.getValue(rPath, c.params, ...)    // 匹配对应路由的handler
          |-github.com/gin-gonic/gin.LoggerWithConfig.func1
            |-github.com/gin-gonic/gin.CustomRecoveryWithWriter.func1
              |-main.main.func1
                |-github.com/gin-gonic/gin.(*Context).Query // 获取get参数
                  |-github.com/gin-gonic/gin.(*Context).GetQueryArray
                    |-net/url.(*URL).Query                  // 首次调用需要实例一个map对象
                      |-net/url.parseQuery
        |-sync.(*Pool).Put
    |-net/http.(*response).finishRequest

结合上一篇的文章,我们可以发现gin的服务器流程和net/http包的差不多,只是在响应连接的时候使用了自己的serverMux。gin号称自己是内存零分配,那么在接受请求和返回数据的时候,是否真的是零分配呢?

本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!