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

前言

羣里老有同窗問,go-zero數據庫redis 庫是否有鏈接池支持。先說結論:有的,能夠放心大膽用!git

從框架設計來講,對於數據庫鏈接這種資源固然是儘量減小頻繁操做:github

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

因此無論是 sqlxredis,以及 mongo,等之後可能要支持的數據源類型,底層的池化處理都是通用的;因此當開發者須要一個池化處理組件時,go-zero 也是提供的。redis

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

使用

使用的話,咱們直接來看 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 系列文章見『微服務實踐』公衆號
相關文章
相關標籤/搜索