我這里類似于sass結(jié)構(gòu)的 框架使用的webman 數(shù)據(jù)庫使用的mysql8.0+thinkorm連接
業(yè)務(wù)需要:數(shù)據(jù)庫是根據(jù)每家商戶進(jìn)行分庫存儲的,通過中間件進(jìn)行數(shù)據(jù)庫動態(tài)切換連接。
現(xiàn)在動態(tài)連接各方面訪問都沒有問題,但是數(shù)據(jù)庫連接量一直遞增,目前已經(jīng)跑到了1000多。一直擔(dān)心奔潰的問題
我在中間件中使用動態(tài)連接,自動切換數(shù)據(jù)庫連接代碼如下
public function process(Request $request, callable $handler): Response
{
//請求控制器白名單,不能進(jìn)行數(shù)據(jù)庫模型操作,只用于回調(diào)接收數(shù)據(jù)
$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!']);
}
// 將當(dāng)前商戶的數(shù)據(jù)庫配置存儲在全局變量中
global $merchant_dbs;
// 等于0 屬于碩昆平臺端連接
if ($merchant_id == 0) {
$merchant_dbs[$merchant_id] = Config::get('thinkorm');
// 初始化數(shù)據(jù)庫連接
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;
}
# 獲取當(dāng)前商戶的數(shù)據(jù)庫配置
$db_config = Config::get('thinkorm');
# 檢查當(dāng)前商戶是否有對應(yīng)的數(shù)據(jù)庫配置
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) {
# 動態(tài)設(shè)置數(shù)據(jù)庫
Db::setConfig($merchant_dbs[$merchant_id]);
# 動態(tài)連接數(shù)據(jù)庫
Db::connect('merchant' . $merchant_id);
}
return $handler($request);
}
這是中間件中所執(zhí)行的動態(tài)切換 也就是根據(jù)商戶的id進(jìn)行切換到指定的庫。我發(fā)現(xiàn)這樣使用連接量大量的sleep
你這是搞復(fù)雜化了吧!建議看看
【SaaS多租戶架構(gòu)數(shù)據(jù)源動態(tài)切換解決方案】
https://mp.weixin.qq.com/s/RszdlEXlyDIzv6Bn0xNl7g
大佬 其實和這個思路是一樣的 我當(dāng)時不想再模型中寫入相關(guān)的數(shù)據(jù)庫切換操作 在中間件直接去做的調(diào)用 但是每次進(jìn)入接口都會重新連接 導(dǎo)致這種問題了 目前看看怎么改動量最小 感謝大佬
@Tinywan 文章看了,切換是沒有問題的,問題是預(yù)定義數(shù)據(jù)庫配置是寫死的,而不是動態(tài)添加的,還有一點是配置了多個,會導(dǎo)致項目啟動時候就會有很多的鏈接存在,比如200個租戶,即使是4個進(jìn)程,就會有800個鏈接存在
@doit 大佬有什么不同的看法 他這么做其實最后是我一樣的。我現(xiàn)在是一樣的問題,切換還是會存在大量sleep,哪怕是調(diào)用完成close也還是無效
DB::connect 連接和它本身內(nèi)置的切換數(shù)據(jù)庫是 同理啊 你說的多個進(jìn)程是指webman的啟用的進(jìn)程數(shù)嗎
復(fù)用一個數(shù)據(jù)庫連接,操作數(shù)據(jù)庫前用use 數(shù)據(jù)庫
語句切換數(shù)據(jù)庫。切換時機(jī)可以在中間件里自動切換吧