Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Penjelasan terperinci tentang kod sumber Enjin Gin

Penjelasan terperinci tentang kod sumber Enjin Gin

Golang菜鸟
Golang菜鸟ke hadapan
2023-08-04 17:41:43707semak imbas

Apakah gin?

Gin ialah rangka kerja web HTTP yang ditulis dalam Go (Golang). Ia mempunyai API seperti Martini tetapi berprestasi 40 kali lebih pantas daripada Martini. Jika anda memerlukan prestasi yang melampau, gunakan Gin.

gin Kenapa cepat?

Mari kita lihat ujian penanda aras rasmi dahulu Alamat[1]

Penjelasan terperinci tentang kod sumber Enjin Gin

Ini hanyalah sebahagian daripadanya, anda boleh pergi ke alamat di atas untuk melihat versi lengkap.

Kita boleh melihatnya melalui ujian prestasigin prestasi dalam memproses permintaan Ia sememangnya lebih baik daripada yang lain (27,31,35,.05);font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;word-break: break-all;">web rangka kerja adalah lebih pantas . gin 在处理请求的性能上确实比其他的web 框架快上不少。

性能问题主要是使用 httprouter[2],而httprouter使用 Trie Tree(字典树)作为路径存储结构,具有高性能的查找。

gin.Engine 源码

// Engine is the framework's instance, it contains the muxer, middleware and configuration settings.
// Create an instance of Engine, by using New() or Default()
type Engine struct {
   RouterGroup       // 用于注册根路由组使用
    ...
    pool             sync.Pool    // 用于 gin.context 对象池
    trees            methodTrees  // 用于保存的请求路径
    ...
}

在 gin 的Engine

Masalah prestasi terutamanya disebabkan oleh penggunaan 🎜httprouter🎜🎜[2]🎜, dan httprouterGunakan<code style="font-size: 14px;word-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin: 0 2px;color: #1e6bb8;background-color : rgba( 27,31,35,.05);font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;word-break: break-all;">Trie Tree (pokok kamus) sebagai struktur storan laluan, carian berprestasi tinggi. 🎜🎜🎜🎜gin.Kod sumber enjin🎜
// HandlerFunc defines the handler used by gin middleware as return value.
type HandlerFunc func(*Context)

// HandlersChain defines a HandlerFunc array.
type HandlersChain []HandlerFunc

// RouterGroup is used internally to configure router, a RouterGroup is associated with
// a prefix and an array of handlers (middleware).
type RouterGroup struct {
    Handlers HandlersChain
    basePath string
    engine   *Engine
    root     bool
}
🎜 dalam gin Enjin Antaranya, yang paling penting ialah tiga bidang ini. 🎜

gin.RouterGroup 源码

// HandlerFunc defines the handler used by gin middleware as return value.
type HandlerFunc func(*Context)

// HandlersChain defines a HandlerFunc array.
type HandlersChain []HandlerFunc

// RouterGroup is used internally to configure router, a RouterGroup is associated with
// a prefix and an array of handlers (middleware).
type RouterGroup struct {
    Handlers HandlersChain
    basePath string
    engine   *Engine
    root     bool
}

RouterGroupHandlers存放的是当前分组的所有中间件,也可以说:请求到这个分组,那么Handlers 中的函数都会根据索引从小到大的按顺序执行。

basePath 就是存放这个分组的基础路由路径。可能直接解释过于抽象;我们来分析它的调用链来看:

  1. Penjelasan terperinci tentang kod sumber Enjin Gin
  2. Penjelasan terperinci tentang kod sumber Enjin Gin
  3. Penjelasan terperinci tentang kod sumber Enjin Gin

gin.New() 函数中我们可以看到 basePath 默认是 /Penjelasan terperinci tentang kod sumber Enjin Gin

而新的RouterGroup是通过Engine调用Group函数产生的;也就是我们自己的Group

Penjelasan terperinci tentang kod sumber Enjin Gin

那么以后在这个Group注册的路径都会自动加上/user的路径。

为什么会自动添加路径,后面还会分析相关细节。

gin.methodTree 源码

type node struct {
   path      string
   indices   string
   wildChild bool
   nType     nodeType
   priority  uint32
   children  []*node // child nodes, at most 1 :param style node at the end of the array
   handlers  HandlersChain
   fullPath  string
}

type methodTree struct {
    method string
    root   *node
}

type methodTrees []methodTree

对于node的添加和查找我就不展开讲了,如果不懂的可以自行搜索字典树和查看 httprouter[3] 的实现。

我们刚刚在gin.New 函数中可以看到,trees是一个methodTree的切片,并在在初始化给了默认容量为9是容量不是长度哦

Penjelasan terperinci tentang kod sumber Enjin Gin

addRoute 函数中可以看到trees的添加:

Penjelasan terperinci tentang kod sumber Enjin Gin

Jika tiada laluan akar yang sepadan dengan kaedah pada permulaannod objek, Satu akan dibuat, dan kemudian pendaftaran laluan yang sepadan akan ditambah. <code style="font-size: 14px;word-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin: 0 2px;color: #1e6bb8;background-color: rgba(27,31,35,.05);font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;word-break: break-all;">node对象,就会创建一个出来,然后再去添加对应的路由注册。

整体的流程分析

gin框架中,主要可以使用下面几种注册方式:

  • 对应的http请求方法的名称(get,post,put...
  • 通过Group分组路由减少路径的填写
  • 通过Any 注册所有http方法路由

这些注册在下面其实都是调用的同一个方法,我们接下来就要来翻开她的外衣看看里面是什么样的。Penjelasan terperinci tentang kod sumber Enjin Gin

可以看到都是调用的group.handle

Analisis proses keseluruhan

Penjelasan terperinci tentang kod sumber Enjin GinDalamgin rangka kerja, anda boleh menggunakan kaedah pendaftaran berikut terutamanya:
  • Nama kaedah permintaan http yang sepadan (dapatkan,siarkan,letakkan...)
  • MengikutKumpulanPenghalaan kumpulan mengurangkan pengisian laluan
  • Lulus Mana-mana Daftar semuahttpmethod routing

Pendaftaran di bawah ini sebenarnya adalah kaedah yang sama dipanggil, kami akan melakukannya seterusnya Mari buka kot dia dan lihat apa dalam. Penjelasan terperinci tentang kod sumber Enjin Gin

🎜Anda boleh lihat semuanya dipanggilkaedah group.handle🎜🎜🎜Mari kita lihat apa yang dilakukan oleh kaedah ini:🎜
  • Kira laluan penghalaangroup.calculateAbsolutePath(relativePath) seksyen >
  • group.calculateAbsolutePath(relativePath)
  • 为当前注册的路径增加中间件函数,并将注册的函数放在最后面
  • 添加到全局路由表中
  • 返回一个IRoutes接口
  • combineHandlers 支持最大的函数数量为63-1个Penjelasan terperinci tentang kod sumber Enjin Gin

    Group 函数

    现在来看Group的实现,通过调用这个方法会产生一个新的RouterGroup 并根据参数设置的基础路径,和全局engine实体,并把基础的中间件也复制到其中。

    Penjelasan terperinci tentang kod sumber Enjin Gin

    使用分组路由最后也是调用group.handle方法进行注册,只是其中的basePath

    Tambah fungsi middleware pada laluan yang didaftarkan pada masa ini dan letakkan fungsi berdaftar di hujung

    Tambahkannya pada jadual penghalaan global🎜 🎜KembalikanIRoutesAntaramuka ul>🎜combineHandlers menyokong bilangan maksimum fungsi 63-1 individu Penjelasan terperinci tentang kod sumber Enjin Gin🎜

    Fungsi kumpulan

    🎜Sekarang lihatKumpulan, memanggil kaedah ini akan menghasilkan basePath telah ditetapkan semasa pengumpulan, serta laluan semasa mendaftarkan fungsi, ini ialah laluan penghalaan permintaan. 🎜🎜Satu perkara yang perlu diperhatikan ialah selepas saya berfikir tentang menggunakan ·Kumpulan· sebelum ini, pendaftaran seterusnya tidak menggunakan nilai pulangan Bagaimana laluan yang didaftarkan didaftarkan dalam jadual laluan global, saya hanya memahaminya selepas membaca kod sumber. 🎜
    Penjelasan terperinci tentang kod sumber Enjin Gin

    添加路由的时候,是获取的全局engine 实体,所以也是添加到全局路由表中的。

    最后需要注意的

    在使用注册中间件和注册路由的时候,需要注意他们注册的顺序。

    上一点错误的注册方式代码:

    package main
    
    import (
     "github.com/gin-gonic/gin"
    )
    
    func main() {
     eng := gin.New()
     eng.POST("login", func(context *gin.Context) {
      // 处理登录信息
     })
     eng.Use(gin.Logger())
    
     userGroup := eng.Group("/user")
     userGroup.GET("info", func(context *gin.Context) {
      // 参数验证
    
      // 处理逻辑
     })
    
     adminGroup := eng.Group("/admin")
     adminGroup.GET("info", func(context *gin.Context) {
      // 参数验证
    
      // 处理逻辑
     })
    
     eng.Use(gin.Recovery())
     adminGroup.PUT("info", func(context *gin.Context) {
      // 参数验证
    
      // 处理逻辑
     })
     eng.GET("logout", func(context *gin.Context) {
      // 处理登录信息
     })
     eng.Run(":8080")
    }

    运行结果:

    Penjelasan terperinci tentang kod sumber Enjin Gin

    可以看到在注册路由之后,再注册中间件,那么前面注册过的路由是没有这个中间件的。

    Atas ialah kandungan terperinci Penjelasan terperinci tentang kod sumber Enjin Gin. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

    Kenyataan:
    Artikel ini dikembalikan pada:Golang菜鸟. Jika ada pelanggaran, sila hubungi admin@php.cn Padam