通用連接池幫你解決資源管理難題


前言

群里老有同學問,go-zero數據庫redis 庫是否有連接池支持。先說結論:有的,可以放心大膽用!

從框架設計來說,對於數據庫連接這種資源當然是盡可能減少頻繁操作:

  1. 為業務減負
  2. 提升框架自身的性能
  3. 池化技術是一個通用化技術,本身就應該作為一個通用庫支撐框架的上層業務

所以不管是 sqlxredis,以及 mongo,等以后可能要支持的數據源類型,底層的池化處理都是通用的;所以當開發者需要一個池化處理組件時,go-zero 也是提供的。

池化技術支持的庫就位於:core/resourcemanager.go。下面來看看這個庫的使用~~

使用

使用的話,我們直接來看 sqlx ,它是怎么用的:

// 1. 初始化
var connManager = syncx.NewResourceManager()

func getCachedSqlConn(driverName, server string) (*db, error) {
  val, err := connManager.GetResource(server, func() (io.Closer, error) {
    // 2. 此處才是真正創建連接的地方
    conn, err := newDBConnection(driverName, server)
    ...
    // 3. 將連接返回給連接池【內部也肯定是存起來】
    return &db{
      DB: conn,
    }, nil
  })
  ...
  return val.(*db), nil
}

說說其中的要點:

  1. NewResourceManager:創建一個池子
  2. GetResource(key, createFunc):key是用來防止並發獲取資源時重復請求,createFunc 才是正在用來創建資源的函數【此函數需要有開發者自己編寫符合業務需求資源】

總結一下資源池的模型:

// 1. new
var manager = NewResourceManager()

// 2. 業務資源獲取函數
func getResource(key string) (*resource, error) {
  return manager.GetResource(key, createFunc);
}

// 3.業務資源創建函數【由開發者自己編寫,此處只是一個樣例】
func createFunc() (io.Closer, error) {
  // 打開一個資源
  conn, err := openResource();
  // 設置一下資源配置
  conn.setConfig()
  
  return conn, err;
}

整體分析

其實流程上很簡單,其中還有我們老生常談的 sharedCalls

  1. GetResource,攜帶特定的 key,到資源池中的 map 中查找:
    • 查到了,直接返回
    • 沒有查到,調用傳入的 create() ;此處才真正創建一個真實的資源連接,並放入 map
  2. 其中對 map 的查詢和寫入,都得加鎖。
  3. 其中在對資源池進行操作時,附加上 sharedCalls :防止並發請求時無效流量請求以及共享請求結果。

關於 SharedCalls,還不清楚的同學,可以到 go-zero 官方文檔中仔細查看。

總結

本篇文章對 go-zero 的資源池庫從使用到結構進行了分析。大家也可以在業務中常發生資源申請的邏輯處,加上 resourcemanager,本質上也是給資源加上一個緩存,節省反復創建。

關於 go-zero 更多的設計和實現文章,可以關注『微服務實踐』公眾號。

項目地址

https://github.com/tal-tech/go-zero

歡迎使用 go-zero 並 star 支持我們!

微信交流群

關注『微服務實踐』公眾號並點擊 交流群 獲取社區群二維碼。

go-zero 系列文章見『微服務實踐』公眾號


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM