91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

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

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

Go?簡單實現多租戶數據庫隔離的方法

發布時間:2023-07-28 11:45:27 來源:億速云 閱讀:130 作者:栢白 欄目:開發技術

今天小編給大家分享的是Go 簡單實現多租戶數據庫隔離的方法,相信很多人都不太了解,為了讓大家更加了解,所以給大家總結了以下內容,一起往下看吧。一定會有所收獲的哦。


多租戶

在 SaaS 系統中多租戶是一個很重要的架構,在服務上僅需運行一個軟件實例就能夠支持每個租戶的功能,它們之間的數據互相隔離。就比如 Gitee ,每個用戶或組織都擁有自己的空間。它們自己的數據僅在自己的空間內流通,彼此之間互不影響。多租戶其實就是一種軟件設計結構。
所以。租戶模型其實就是分離數據的方式:

  • 單租戶:一個應用一個數據庫。其實就是應用分離,數據分離。

  • 多租戶:一個應用多個數據庫。就是同一個應用不同數據庫。

為什么需要多租戶?

剛畢業第一家公司,接觸的第一個項目的內容主要幫助客戶提高生產力。每次有一個很大的問題就是,合作一個客戶,項目復制一份出來,然后改成該客戶定制的功能需求。這樣就導致相同功能要更新多份代碼,還要注意可能會出現因不同客戶的不同需求問題。整個過程就導致了一個很大的維護成本的支出。

多租戶應用程序的維護更容易,只需根據每個租戶專屬標志,然后提供不同的功能,且公共的功能可以集中更新升級。

數據隔離方式

在 SaaS 系統中一般分離租戶的數據有兩種模型:

  • 數據的邏輯分離:所有租戶只使用一個數據庫。它們的數據通過為每個租戶使用一個唯一標識符來分隔。

  • 數據的物理分離:一個租戶分配一個數據庫。就是一個應用對應多個數據庫。每個數據庫就是一個租戶。這種方式在客戶的增長時擴展了應用的功能,也方便擴展數據庫

物理分離詳細實現

目標:每個請求過來,應用程序能夠識別租戶,并從該租戶數據庫中進行提供數據。

  • 公共數據庫:存儲所有租戶相關全局配置和所有租戶數據庫信息。

  • 租戶數據庫:每個租戶獨立的的數據庫,根據租戶需要保存數據。

Go?簡單實現多租戶數據庫隔離的方法

啟動服務

創建 main 文件,并使用 Gin 框架。初始化一個簡單的應用程序并創建基本的路由。

func main() {
    r := gin.Default()
    r.GET("/ping", func(c *gin.Context) {
        c.JSON(http.StatusOK, gin.H{
            "message": "pong",
        })
    })
    r.Run()
}

數據庫配置

在公共數據庫創建一個保存租戶數據庫信息表并添加上租戶的數據庫。

Create Table db_tenant (
    id int primary key,
    db_name varchar(100) unique not null,
    db_domain  varchar(100) unique not null,
    conn_str varchar(200) not null,
    remark varchar(1000) ,
)

在配置文件中加入一個公共數據庫的連接配置,這樣就可以在服務啟動時第一次連接的是公共數據庫。接著需要實現根據請求連接到正確的租戶數據庫。主要使用 gorm 的 DBResolver ,多個數據庫的連接支持

func allDbConnect(db *db.gorm) (allDbs map[string]) {
     db.Model(&db_tenant).Find(&allDbs)
    var gconn []gorm.Dialector
      for _,connStr := range allDbs {
       db :=mysql.Open(connStr)
                gconn = append(gconn,db)
    }
db.Use(dbresolver.Register(dbresolver.Config{
  Sources:  gconn,
  // sources/replicas 負載均衡策略
  Policy: dbresolver.RandomPolicy{},
})
   return allDbs
}

通過使用中間件來解析每個請求連接,從而確定整個請求是由哪個租戶數據庫來提供數據讀寫。中間件中主要的處理方式是得到租戶對應的數據庫連接名,然后從連接池中拿到該連接并設置在全局變量中。在業務邏輯處理中從全局拿到數據庫連接,就可以進行數據庫讀寫。

sr.Use(middlerware.dbResolve)
func dbResolve(ctx *gin.Context) {
    dbName := ctx.Query("dbName")
    setGlobalDb(dbName)
}
func dbOperater(){
    db := getDb()
  var users []User
  db.Clauses(dbresolver.Use(dbName)).First(&users)
}

這樣就可以啟動項目,然后訪問 localhost:8003?dbName=db1 ,這樣就可以正常進行數據讀寫。

其實可以從域名上解析對應的數據庫連接。這里最重要就是對數據庫的解析。這里的例子只是實驗使用,其中還有很多可優化的點。比如可以考慮使用連接池,這樣就不用在項目啟動時都全部創建數據庫連接,造成浪費。

關于Go 簡單實現多租戶數據庫隔離的方法就分享到這里了,希望以上內容可以對大家有一定的參考價值,可以學以致用。如果喜歡本篇文章,不妨把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

go
AI

当涂县| 林芝县| 长武县| 桐城市| 嘉兴市| 定州市| 隆林| 垣曲县| 连南| 长宁县| 铁岭县| 金塔县| 南安市| 普安县| 石楼县| 平昌县| 黎城县| 慈利县| 甘谷县| 竹北市| 镇赉县| 绩溪县| 南宁市| 华池县| 丁青县| 金川县| 竹山县| 彭泽县| 方正县| 靖州| 正阳县| 博白县| 连江县| 河间市| 岫岩| 江津市| 海盐县| 华池县| 盘山县| 苍溪县| 镇赉县|