溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

如何進行Redigo源碼淺析

發(fā)布時間:2021-12-18 18:02:23 來源:億速云 閱讀:128 作者:柒染 欄目:大數(shù)據(jù)

今天就跟大家聊聊有關(guān)如何進行Redigo源碼淺析,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。

使用 Redigo 比較多,為了方便學(xué)習(xí)。進而閱讀了它的源碼,加深理解。

// 一段 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 函數(shù)(匿名函數(shù))進行連接,生成 conn 連接對象。 連接數(shù)+1,并返回連接池對象 poolConn。

執(zhí)行操作:

  • 從連接池中獲取一個可用 conn 連接對象。 并通過 DoWithTimeout 函數(shù)向 conn 輸出緩沖區(qū)寫入數(shù)據(jù)。數(shù)據(jù)內(nèi)容遵從 RESP 協(xié)議。

關(guān)閉操作:

  • 1.因為 Get 拿到的是一個activeConn 對象,所以關(guān)閉連接調(diào)用的是 func (ac *activeConn) Close() 函數(shù)。

  • 2.首先會向 Redis 發(fā)送一個空字符的命令。(沒懂意義何在)

  • 3.緊接著不是刪除這次的鏈接而是把 conn 對象 put 到 idleList (雙向鏈表實現(xiàn)) 的前驅(qū)節(jié)點上 鏈表的長度由 MaxIdle 所限定,超出則拋棄

  • 4.繼續(xù)調(diào)用 conn 的 Close() 函數(shù), 跳轉(zhuǎn)到 net 的 Close() 函數(shù)

  • 5.通過 runtime.SetFinalizer(fd, nil) 解除綁定并執(zhí)行對應(yīng)函數(shù)下一次gc在進行清理 并關(guān)閉基礎(chǔ)文件描述符

看完上述內(nèi)容,你們對如何進行Redigo源碼淺析有進一步的了解嗎?如果還想了解更多知識或者相關(guān)內(nèi)容,請關(guān)注億速云行業(yè)資訊頻道,感謝大家的支持。

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI