Gin框架执行流程

本文深入剖析了Gin框架如何利用net/http库实现Web请求处理,详细解释了从Gin.Run()启动到ServeHTTP方法的调用过程,以及中间件和控制器的执行顺序。通过协程goc.serve(connCtx)进行请求处理,并展示了 Gin框架内部的数据结构,如Engine、Server和Conn,揭示了请求生命周期中的关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Gin框架通过net/http 网络库实现的来一个请求,开一个携程的处理方式

go c.serve(connCtx)

其中间件的运行与控制器的业务,按照顺序放入handle切片中,循环处理。

func (c *Context) Next() {
   c.index++
   for s := int8(len(c.handlers)); c.index < s; c.index++ {
      c.handlers[c.index](c)
   }
}

对于中间件中有调用Next()方法的,会先执行下一个handle,在继续Next()后面的代码。

 

如下是gin启动的一个web请求的流程。

// gin.go

gin.Run() // gin启动
http.ListenAndServe(address, engine)


// server.go
server := &Server{Addr: addr, Handler: handler}
server.ListenAndServe()

ln, err := net.Listen("tcp", addr) // 网络监听
srv.Serve(ln)


c := srv.newConn(rw) // 网络连接
c := &conn{
		server: srv,
		rwc:    rwc,
	}
go c.serve(connCtx) // 开启协程处理请求



serverHandler{c.server}.ServeHTTP(w, w.req)
// engine 实现了ServeHTTP 方法

// gin.go
func (engine *Engine) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	c := engine.pool.Get().(*Context)
	c.writermem.reset(w)
	c.Request = req
	c.reset()

	engine.handleHTTPRequest(c)

	engine.pool.Put(c)
}

 以下是各个变量的数据结构

// 先来看下engine的数据结构

gin 框架

type Engine struct {
    RouterGroup
    RedirectTrailingSlash  bool
    RedirectFixedPath      bool
    HandleMethodNotAllowed bool
    ForwardedByClientIP    bool
    AppEngine              bool
    UseRawPath             bool
    UnescapePathValues     bool
    MaxMultipartMemory     int64
    delims                 render.Delims
    secureJsonPrefix       string
    HTMLRender             render.HTMLRender
    FuncMap                template.FuncMap
    allNoRoute             HandlersChain
    allNoMethod            HandlersChain
    noRoute                HandlersChain
    noMethod               HandlersChain
    pool                   sync.Pool
    trees                  methodTrees
}

allocateContext() *Context
Delims(left string, right string) *Engine
SecureJsonPrefix(prefix string) *Engine
LoadHTMLGlob(pattern string)
LoadHTMLFiles(files ...string)
SetHTMLTemplate(templ *template.Template)
SetFuncMap(funcMap template.FuncMap)
NoRoute(handlers ...HandlerFunc)
NoMethod(handlers ...HandlerFunc)
Use(middleware ...HandlerFunc) IRoutes // 将中间件,控制器,塞到handle切片中,逐一处理
rebuild404Handlers()
rebuild405Handlers()
addRoute(method string, path string, handlers HandlersChain)
Routes() (routes RoutesInfo)
Run(addr ...string) (err error)
RunTLS(addr string, certFile string, keyFile string) (err error)
RunUnix(file string) (err error)
ServeHTTP(w http.ResponseWriter, req *http.Request)  // 实现Handler接口
HandleContext(c *Context)
handleHTTPRequest(c *Context)
// server := &Server{Addr: addr, Handler: handler}
// net/http server
type Server struct {
    Addr              string
    Handler           Handler
    TLSConfig         *tls.Config
    ReadTimeout       time.Duration
    ReadHeaderTimeout time.Duration
    WriteTimeout      time.Duration
    IdleTimeout       time.Duration
    MaxHeaderBytes    int
    TLSNextProto      map[string]func(*Server, *tls.Conn, Handler)
    ConnState         func(net.Conn, ConnState)
    ErrorLog          *log.Logger
    BaseContext       func(net.Listener) context.Context
    ConnContext       func(ctx context.Context, c net.Conn) context.Context
    inShutdown        atomicBool
    disableKeepAlives int32
    nextProtoOnce     sync.Once
    nextProtoErr      error
    mu                sync.Mutex
    listeners         map[*net.Listener]struct{}
    activeConn        map[*conn]struct{}
    doneChan          chan struct{}
    onShutdown        []func()
}

newConn(rwc net.Conn) *conn
maxHeaderBytes() int
initialReadLimitSize() int64
getDoneChan() <-chan struct{}
getDoneChanLocked() chan struct{}
closeDoneChanLocked()
Close() error
Shutdown(ctx context.Context) error
RegisterOnShutdown(f func())
numListeners() int
closeIdleConns() bool
closeListenersLocked() error
ListenAndServe() error
shouldConfigureHTTP2ForServe() bool
Serve(l net.Listener) error
ServeTLS(l net.Listener, certFile string, keyFile string) error
trackListener(ln *net.Listener, add bool) bool
trackConn(c *conn, add bool)
idleTimeout() time.Duration
readHeaderTimeout() time.Duration
doKeepAlives() bool
shuttingDown() bool
SetKeepAlivesEnabled(v bool)
logf(format string, args ...interface{})
ListenAndServeTLS(certFile string, keyFile string) error
setupHTTP2_ServeTLS() error
setupHTTP2_Serve() error
onceSetNextProtoDefaults_Serve()
onceSetNextProtoDefaults()
ExportAllConnsIdle() bool
// 连接信息
type conn struct {
    server     *Server
    cancelCtx  context.CancelFunc
    rwc        net.Conn
    remoteAddr string
    tlsState   *tls.ConnectionState
    werr       error
    r          *connReader
    bufr       *bufio.Reader
    bufw       *bufio.Writer
    lastMethod string
    curReq     atomic.Value
    curState   struct {
        atomic uint64
    }
    mu         sync.Mutex
    hijackedv  bool
}


hijacked() bool
hijackLocked() (rwc net.Conn, buf *bufio.ReadWriter, err error)
readRequest(ctx context.Context) (w *response, err error)
finalFlush()
close()
closeWriteAndWait()
setState(nc net.Conn, state ConnState)
getState() (state ConnState, unixSec int64)
serve(ctx context.Context)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

RenBingo

一点一滴源于你的鼓励

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值