求助 - Gin框架SAAS模式下多租户数据连接隔离问题

mi1688 · 2020-08-22 10:51:37 · 4001 次点击 · 大约8小时之前 开始浏览    置顶
这是一个创建于 2020-08-22 10:51:37 的主题,其中的信息可能已经有所发展或是发生改变。

各位大神帮指点下. 我在做一个多租户系统,给予gin / xorm 开发, 大概流程是这样的

  1. 登陆总后台,添加一个租户,
  2. 根据租户分配的数据库链接地址 生成租户的数据库(一租户一库).
  3. 添加租户的域名.后台管理域名,前台域名

======= 问题来了 ========

  1. 同一套代码,租户登陆租户后台,执行操作,数据库链接有可能不一样,数据库名一定不一样. 
  2. 租户登陆的时候在中间件里根据域名判定是哪个租户登陆 然后找到这个租户对应的数据库配置,
  3. 链接数据库, DB链接指针放到 gin.Context里面
  4. 每次查询的时候,从context获取链接地址

问题是,如果函数调用比较深, 每次都传context, 这样感觉代码太冗余. 有什么好办法不?


有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

4001 次点击  
加入收藏 微博
11 回复  |  直到 2021-01-01 20:37:41
4color
4color · #1 · 4年之前

我目前是这么做的,可以一起讨论。把所有数据链接放在一个全局集合变量里。每次进来时根据域名去匹配

jfliuyun
jfliuyun · #2 · 4年之前

我前段时间刚好做过一个就是在调用API的时候获取请求的Referer 然后把这个做为参数来匹配响应的数据库

datasources:

  • dataSourceLabel: default mysqlUrl: mysql 连接串
  • dataSourceLabel: yyy.domain.com mysqlUrl: mysql 连接串
mi1688
mi1688 · #3 · 4年之前

@4color
我现在也是通过域名来匹配数据库链接, 有一个问题, 就是如果不同的商户共用一套代码, 由于go的特殊性, 会导致数据库链接变量污染。 就是如果A商户的链接是a-conn, B的是b-conn, 高并发的情况下, 灰a-conn b-conn分不清。

mi1688
mi1688 · #4 · 4年之前

@jfliuyun 目前是web请求的域名来绑定数据库链接。 现在同够context传数据库进去。感觉有点不优雅。

pangxianfei
pangxianfei · #5 · 4年之前

我也遇到这类的问题。加QQ群讨论下。qq群:50403087,加入备注下:saas

focusonline
focusonline · #6 · 4年之前
mi1688mi1688 #3 回复

@4color 我现在也是通过域名来匹配数据库链接, 有一个问题, 就是如果不同的商户共用一套代码, 由于go的特殊性, 会导致数据库链接变量污染。 就是如果A商户的链接是a-conn, B的是b-conn, 高并发的情况下, 灰a-conn b-conn分不清。

高并发 会导致获取到的全局数据出问题? 根据key获取A租户的连接变成了B租户? go这么差劲?

zhushiqiang
zhushiqiang · #7 · 4年之前
focusonlinefocusonline #6 回复

#3楼 @mi1688 高并发 会导致获取到的全局数据出问题? 根据key获取A租户的连接变成了B租户? go这么差劲?

估计数据库全局变量用了同一个

focusonline
focusonline · #8 · 4年之前
zhushiqiangzhushiqiang #7 回复

#6楼 @focusonline 估计数据库全局变量用了同一个

这个可能性不大吧, 这应该是基本常识, 出这种错误可是太小儿科了

eudore
eudore · #9 · 4年之前

1、数据库连接对象放到控制器里面就好了,然后使用基于host的路由匹配。

2、使用有状态控制器,在控制器init的时候根据host去加载sql.DB

4color
4color · #10 · 4年之前

3楼 @mi1688 做数据库对象集合,不过我目前没有做高并发测试。

//项目的链接池,有多个项目就建多个

var XEngineXm []DbPool

//项目对应的业务数据源。如果相关信息,比如IP,账户,密码修改后,请清理数据源缓存或重启此程序。

var XEngineBiz []DbPool

我这个还是多重集合,每一个租户下,还可以建自己的业务库连接。

pangxianfei
pangxianfei · #11 · 4年之前
4color4color #10 回复

3楼 @mi1688 做数据库对象集合,不过我目前没有做高并发测试。 //项目的链接池,有多个项目就建多个 var XEngineXm []DbPool //项目对应的业务数据源。如果相关信息,比如IP,账户,密码修改后,请清理数据源缓存或重启此程序。 var XEngineBiz []DbPool 我这个还是多重集合,每一个租户下,还可以建自己的业务库连接。

目前,我是连接对象保存到MAP里,写入上下文,在控制器里取连接对象查询数据库。

添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传