今天就跟大家聊聊有关如何进行Redigo源码浅析,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。
使用 Redigo 比较多,为了方便学习。进而阅读了它的源码,加深理解。
// 一段 redigo demo RedisConn = &redis.Pool{ MaxIdle: setting.RedisSetting.MaxIdle, MaxActive: setting.RedisSetting.MaxActive, IdleTimeout: setting.RedisSetting.IdleTimeout, Dial: func() (redis.Conn, error) { c, err := redis.Dial("tcp", setting.RedisSetting.Host) if err != nil { return nil, err } if setting.RedisSetting.Password != "" { if _, err := c.Do("AUTH", setting.RedisSetting.Password); err != nil { c.Close() return nil, err } } return c, err }, TestOnBorrow: func(c redis.Conn, t time.Time) error { _, err := c.Do("PING") return err }, } conn := RedisConn.Get() reply, err := redis.Bytes(conn.Do("GET", key)) conn.Close()
这段代码主要是用来初始化 redis.Pool 的,顺着代码往下走。 用来获取连接池中的一个 conn 对象。
type Pool struct { Dial func() (Conn, error) TestOnBorrow func(c Conn, t time.Time) error MaxIdle int MaxActive int IdleTimeout time.Duration Wait bool MaxConnLifetime time.Duration chInitialized uint32 // set to 1 when field ch is initialized mu sync.Mutex // mu protects the following fields closed bool // set to true when the pool is closed. active int // the number of open connections in the pool ch chan struct{} // limits open connections when p.Wait is true idle idleList // idle connections } type idleList struct { count int front, back *poolConn } type poolConn struct { c Conn t time.Time created time.Time next, prev *poolConn } type conn struct { // Shared mu sync.Mutex pending int err error conn net.Conn // Read readTimeout time.Duration br *bufio.Reader // Write writeTimeout time.Duration bw *bufio.Writer // Scratch space for formatting argument length. // '*' or '$', length, "\r\n" lenScratch [32]byte // Scratch space for formatting integers and floats. numScratch [40]byte } RedisConn.Get() func (p *Pool) get(ctx interface { Done() <-chan struct{} Err() error }) (*poolConn, error) { ... p.active++ p.mu.Unlock() c, err := p.Dial() if err != nil { c = nil p.mu.Lock() p.active-- if p.ch != nil && !p.closed { p.ch <- struct{}{} } p.mu.Unlock() } return &poolConn{c: c, created: nowFunc()}, err }
首次连接:
连接池在首次进入的时候是空的,会先进行自定义的 Dial 函数(匿名函数)进行连接,生成 conn 连接对象。 连接数+1,并返回连接池对象 poolConn。
执行操作:
从连接池中获取一个可用 conn 连接对象。 并通过 DoWithTimeout 函数向 conn 输出缓冲区写入数据。数据内容遵从 RESP 协议。
关闭操作:
1.因为 Get 拿到的是一个activeConn 对象,所以关闭连接调用的是 func (ac *activeConn) Close() 函数。
2.首先会向 Redis 发送一个空字符的命令。(没懂意义何在)
3.紧接着不是删除这次的链接而是把 conn 对象 put 到 idleList (双向链表实现) 的前驱节点上 链表的长度由 MaxIdle 所限定,超出则抛弃
4.继续调用 conn 的 Close() 函数, 跳转到 net 的 Close() 函数
5.通过 runtime.SetFinalizer(fd, nil) 解除绑定并执行对应函数下一次gc在进行清理 并关闭基础文件描述符
看完上述内容,你们对如何进行Redigo源码浅析有进一步的了解吗?如果还想了解更多知识或者相关内容,请关注亿速云行业资讯频道,感谢大家的支持。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。