Gin 简介
Gin是一个轻量级的Web框架,用于构建高性能的Go语言Web应用程序。提供了路由管理、中间件支持、参数绑定和验证、错误处理、静态文件服务等功能。
Gin框架解决了什么问题和痛点
1.golang http 标准库本身提供了比较简单的路由注册能力,只支持精确匹配,而实际开发时难免会遇到需要使用通配、路径参数的场景。(gin可以使用路由组,来实现通配)
2 标准库需要我们手动从请求中读取数据、反序列化,响应时手动序列化、设置Content-Type、写响应内容,比较麻烦 (gin 使用 bind shouldBind)
3. 实际开发中, 我们对请求或响应进行一些前置或后置处理,接基于标准库开发,业务和非业务代码难免会耦合在一起 ,(gin可以使用中间件等 做一些统一的前置处理)
Gin快速和高性能的原因
轻量级设计:Gi只提供了一些基本的功能和组件,避免了不必要的复杂性。相比于其他框架,Gin的代码量更少,运行时的资源消耗也较低。
高效的路由引擎:Gin使用了高效的路由引擎,基于压缩前缀树(radix tree)和参数树(trie tree)实现了快速的路由匹配。这种路由匹配算法具有较低的时间复杂度。O(k),其中k是键的长度。
优化的上下文处理:Gin在处理请求时使用了上下文(Context)对象,它封装了请求和响应的相关信息。Gin对上下文对象进行了优化,采用了对象池(pool)技术,避免了频繁的对象创建和销毁操作,减少了内存分配的开销。
支持并发处理:Gin框架天生支持并发处理请求。每个请求都会在独立的goroutine中进行处理,这使得多个请求可以同时被处理,提高了并发处理能力。此外,Gin还提供了对goroutine的调度和管理,确保了请求的同步和顺序处理。
中间件机制: Gin的中间件机制允许开发者在请求到达处理函数之前或之后执行一些通用的逻辑。中间件可以用于身份验证、日志记录、错误处理等操作。由于中间件是按照顺序执行的,它们可以在请求处理链中灵活地插入和组合,而不会对性能造成明显的影响。
优化的JSON解析:Gin使用了快速的JSON解析库,如jsoniter,来提高JSON数据的解析速度。这对于处理大量的JSON请求和响应非常有利,可以减少CPU时间的消耗。
Gin使用流程
基于gin开发的一般流程可总结为:
1 创建并初始化Engine对象 gin.default()
2 注册middleware gin.use() (默认会注册Logger()和Recovery()这两个中间件函数)
3 注册路由 (路由组RouterGroup ,可以实现对路由分组,复用前缀 )
4 处理函数 (使用bind shouldbind解析传参->业务逻辑处理->返回结果)
5 服务端口监听
6 在mian函数中加入:gin.run()
Gin中间件
Gin框架中的中间件(Middleware)是一种用于在请求处理过程中执行通用逻辑的机制。中间件可以在请求处理之前或之后执行一些操作
使用中间件:
注册中间件:使用r.Use()方法将中间件注册到Gin的路由器实例上。
中间件顺序:注册的中间件函数会按照注册的顺序依次执行。
中间件的工作原理:
请求流程:当收到一个HTTP请求时,Gin框架会根据请求的URL和HTTP方法查找匹配的路由。如果有注册的中间件,Gin会将请求传递给中间件链。中间件链中的每个中间件函数都会在请求处理前执行
上下文传递:每个中间件函数都接收一个gin.Context参数,它包含了请求的上下文信息。中间件可以通过Context对象访问和操作请求和响应的数据、路由信息等。中间件可以使用c.Next()方法将请求传递给下一个中间件或路由处理函数,继续处理请求。
中间件分类
其中(Logger,Recovery中间件会默认注册)
Logger(日志记录中间件):Logger中间件用于记录请求和响应的详细信息,例如请求方法、路径、响应状态码等。
Recovery(恢复中间件):Recovery中间件用于在发生panic时恢复应用程序的正常运行。它会捕获并处理应用程序中的异常,防止应用程序崩溃,并返回一个恢复后的响应。
CORS(跨域资源共享中间件):CORS中间件用于处理跨域资源共享的问题。它可以设置响应头,允许跨域请求,并控制响应头中的CORS相关字段,例如Access-Control-Allow-Origin、Access-Control-Allow-Methods
Auth(身份验证中间件):Auth中间件用于验证请求的身份和权限。它可以检查请求中的身份凭证,例如JWT令牌或会话ID,并验证其有效性。
Rate Limiting(限流中间件):Rate Limiting中间件用于限制请求的频率和数量。它可以根据IP地址、用户ID或其他标识符来计算请求的速率,并拒绝超过限制的请求。
Cache(缓存中间件):Cache中间件用于缓存响应数据,以减少对后端服务的请求。它可以根据请求的URL或其他标识符来检查缓存,并返回缓存的响应,而不必重新计算或查询数据。
Gin.Context
Gin框架中,上下文(Context)对象(通常表示为c)是一个关键的组件,它在请求处理过程中承担了多个角色和提供了多种功能
gin.contex 是一个context.Context实现,因此可以将该结构传递到所有接收context.Context的方法或函数中。
gin.context中封装了 http.Request和ResponseWriter对象,因此可以通过context对http请求响应进行操作。 ,
context中还封装了HandlersChain处理器链和当前处理位置索引,因此可以很方便地访问处理器。
type Context struct {writermem responseWriterRequest *http.Request // http请求Writer ResponseWriter // http响应输出流Params Params // URL路径参数handlers HandlersChain // 处理器链index int8 // 当前的处理进度,即处理链路处于函数链的索引位置fullPath stringengine *Engine...mu sync.RWMutex // 用于保护 map 的读写互斥锁// 提供对外暴露的 Get 和 Set 接口向用户提供了共享数据的存取服务,相关操作都在读写锁的保护之下,能够保证并发安全Keys map[string]any // 缓存 handlers 链上共享数据的 map,由于使用的map,避免了设置多个值时context形成链表...queryCache url.Values // 查询参数缓存,使用时调用`Request.URL.Query()`,该方法每次都会对原始的查询字符串进行解析,所以这里设置缓存避免冗余的解析操作formCache url.Values // 表单参数缓存,作用同上...
}
前缀树和压缩前缀树
前缀树(Trie tre)
前缀树也称Trie树或字典树,是一种基于字符串公共前缀构建树形结构,来降低查询时间和提高效率的目的。前缀树一般用于统计和排序大量的字符串,其核心思想是空间换时间。
1根节点不包含字符,除根节点外每一个节点都只包含一个字符。
2从根节点到某一节点路径上所有字符连接起来,就是该节点对应的字符串。
3每个节点任意子节点包含的字符都不相同。
压缩前缀树(Radix Tree)
压缩前缀树是一种更节省空间的前缀树。对于压缩前缀树的每个节点,
如果某一个节点是其父节点的唯一子节点,则会与父节点合并
gin框架就采用的是压缩前缀树实现。