gin源码分析

一、高性能
  • 使用sync.pool解决频繁创建的context对象,在百万并发的场景下能大大提供访问性能和减少GC

    // ServeHTTP conforms to the http.Handler interface.
    // 每次的http请求都会从sync.pool中获取context,用完之后归还到pool中
    func (engine *Engine) ServeHTTP(w http.ResponseWriter, req *http.Request) {
         
    	c := engine.pool.Get().(*Context)
    	c.writermem.reset(w) //重置 responsewriter
    	c.Request = req
    	c.reset() //重置使用过的context各个属性
    
    	engine.handleHTTPRequest(c)
    
    	engine.pool.Put(c)
    }
    
    // 这里给pool指定了一个创建新对象的函数,注意不是所有的请求共用一个context,context在高并发场景下可能会分配多个,但是远远小于并发协程数量。 sync.pool.new是可能并发调用的,所以内部的逻辑需要保障线程安全
    func New(opts ...OptionFunc) *Engine {
         
    	... 
    	engine.RouterGroup.engine = engine
    	engine.pool.New = func() any {
         
    		return engine.allocateContext(engine.maxParams)
    	}
    	return engine.With(opts...)
    }
    
    //每次http请求都需要分配一个context,这个初始context初始化了两个数组的最大容量
    func (engine *Engine) allocateContext(maxParams uint16) *Context {
         
    	v := make(Params, 0, maxParams)
    	skippedNodes := make([]skippedNode, 0, engine.maxSections)
    	return &Context{
         engine: engine, params: &v, skippedNodes: &skippedNodes}
    }
    
  • 前缀树路由(类似httprouter的路由,提升性能近40倍)

    gin在v1.0版本开始放弃了 github.com/julienschmidt/httprouter,重新实现了一套路由;对比gin新实现的路由基本上采用了httprouter的逻辑,但是和框架结合的更加完整,比如说把httprouter中router的能力提到了engine中。

  • json序列化优化

    gin提供了四种可选的json序列化方式,默认情况下会使用encoding/json

    /github.com/gin-gonic/gin@v1.10.0/internal/json
    	-- go_json.go ("github.com/goccy/go-json")
    	-- json.go  ("encoding/json")
    	-- jsoniter.go ("github.com/json-iterator/go")
    	-- sonic.go ("github.com/bytedance/sonic")
    

    需要在编译期间指定tag来决定使用哪种序列化工具

    go run -tags={
         go_json|jsoniter
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值