我这里类似于sass结构的 框架使用的webman 数据库使用的mysql8.0+thinkorm连接
业务需要:数据库是根据每家商户进行分库存储的,通过中间件进行数据库动态切换连接。
现在动态连接各方面访问都没有问题,但是数据库连接量一直递增,目前已经跑到了1000多。一直担心奔溃的问题
我在中间件中使用动态连接,自动切换数据库连接代码如下
public function process(Request $request, callable $handler): Response
{
//请求控制器白名单,不能进行数据库模型操作,只用于回调接收数据
$whiteController = Config::get('white_api_secret.white_controller');
$controller = $request->controller;
if (in_array($controller, $whiteController)) {
$merchant_id = 0;
} else {
// 获取商户ID
$merchant_id = $request->header('X-Merchant-ID');
}
// 检查商户ID是否有效
if (!isset($merchant_id) || !is_numeric($merchant_id)) {
return json(['code' => 400, 'msg' => 'Invalid merchant ID!']);
}
// 非法
if ($merchant_id < 0) {
return json(['code' => 400, 'msg' => 'Invalid merchant ID!']);
}
// 将当前商户的数据库配置存储在全局变量中
global $merchant_dbs;
// 等于0 属于硕昆平台端连接
if ($merchant_id == 0) {
$merchant_dbs[$merchant_id] = Config::get('thinkorm');
// 初始化数据库连接
Db::setConfig(Config::get('thinkorm'));
Db::connect('mysql');
}
// 商户连接
if ($merchant_id > 0) {
$merchantInfoDb = $this->selectDbShopConfig($merchant_id);
if (!is_array($merchantInfoDb)) {
return $merchantInfoDb;
}
$merchant_dbs[$merchant_id] = $merchantInfoDb;
}
# 获取当前商户的数据库配置
$db_config = Config::get('thinkorm');
# 检查当前商户是否有对应的数据库配置
if (!$db_config) {
return json(['code' => 400, 'msg' => 'Database configuration not found for the merchant!']);
}
# 如果不存在直接退出
if (!isset($merchant_dbs[$merchant_id])) {
return json(['code' => 400, 'msg' => 'Database $merchant_id not save global!']);
}
if ($merchant_id > 0) {
# 动态设置数据库
Db::setConfig($merchant_dbs[$merchant_id]);
# 动态连接数据库
Db::connect('merchant' . $merchant_id);
}
return $handler($request);
}
这是中间件中所执行的动态切换 也就是根据商户的id进行切换到指定的库。我发现这样使用连接量大量的sleep
判断下连接是否存在,存在就不再创建连接。
或者中间件里每次用完关闭连接
大佬 但是我判断连接后,数据库调用那里并不会主动切换到这个连上。而且中间件这个调用关闭连接 我不知道thinkorm怎么去调用
连接在调用 Db::connect(),连接在不调用。
不知道怎么关闭就看他们文档呗。
大佬 意思是 我判断有连接 不调用Db::connect()。但是此次进入model连接的库他并不知道查询哪个 而且会查询到默认的初始化库上面去
thinkorm文档上面没有这个玩意
所有model继承一个基类,中间件里根据条件更改基类的 $connection
明白了 感谢大佬
我试了每次用完关闭连接,接口请求的时间增加了一点
大佬 其实和这个思路是一样的 我当时不想再模型中写入相关的数据库切换操作 在中间件直接去做的调用 但是每次进入接口都会重新连接 导致这种问题了 目前看看怎么改动量最小 感谢大佬
@Tinywan 文章看了,切换是没有问题的,问题是预定义数据库配置是写死的,而不是动态添加的,还有一点是配置了多个,会导致项目启动时候就会有很多的链接存在,比如200个租户,即使是4个进程,就会有800个链接存在
连接存在会有什么问题?
@doit 大佬有什么不同的看法 他这么做其实最后是我一样的。我现在是一样的问题,切换还是会存在大量sleep,哪怕是调用完成close也还是无效
mysql的连接数量是有限制的啊,多个租户多个进程,最终会导致mysql连接数占用完,还有就是消耗资源啊。。。
DB::connect 连接和它本身内置的切换数据库是 同理啊 你说的多个进程是指webman的启用的进程数吗
是的
有解决方案吗
你这个解决了吗?
没有解决,你有什么解决方案吗
我也是刚接触😫
复用一个数据库连接,操作数据库前用
use 数据库
语句切换数据库。切换时机可以在中间件里自动切换吧