webman 1.2版本支持think-orm插件,可自動安裝think-orm并配置webman。該插件需要webman>=1.2.1,如果你的webman版本是舊版本,請參考以下文檔手動配置安裝think-orm。
安裝ThinkOrm
composer require topthink/think-orm
配置文件 config/thinkorm.php
內(nèi)容如下:
<?php
return [
'default' => 'mysql',
'connections' => [
'mysql' => [
// 數(shù)據(jù)庫類型
'type' => 'mysql',
// 服務(wù)器地址
'hostname' => '127.0.0.1',
// 數(shù)據(jù)庫名
'database' => 'test',
// 數(shù)據(jù)庫用戶名
'username' => 'root',
// 數(shù)據(jù)庫密碼
'password' => '',
// 數(shù)據(jù)庫連接端口
'hostport' => '3306',
// 數(shù)據(jù)庫連接參數(shù)
'params' => [],
// 數(shù)據(jù)庫編碼默認(rèn)采用utf8
'charset' => 'utf8',
// 數(shù)據(jù)庫表前綴
'prefix' => '',
// 斷線重連
'break_reconnect' => true,
// 關(guān)閉SQL監(jiān)聽日志
'trigger_sql' => false,
],
],
];
建立數(shù)據(jù)庫初始化文件
新建support/bootstrap/ThinkOrm.php
,內(nèi)容如下:
<?php
namespace support\bootstrap;
use Webman\Bootstrap;
use Workerman\Timer;
use think\facade\Db;
class ThinkOrm implements Bootstrap
{
// 進(jìn)程啟動時調(diào)用
public static function start($worker)
{
// 配置
Db::setConfig(config('thinkorm'));
// 維持mysql心跳
if ($worker) {
Timer::add(55, function () {
$connections = config('thinkorm.connections', []);
foreach ($connections as $key => $item) {
if ($item['type'] == 'mysql') {
Db::connect($key)->query('select 1');
}
}
});
}
}
}
進(jìn)程啟動配置
打開config/bootstrap.php
,加入如下配置:
return [
// 這里省略了其它配置 ...
support\bootstrap\ThinkOrm::class,
];
進(jìn)程啟動時會執(zhí)行一遍
config/bootstrap.php
里配置的類的start方法。我們利用start方法來初始化ThinkORM的配置,業(yè)務(wù)就直接可以使用ThinkORM了。
使用
<?php
namespace app\controller;
use support\Request;
use think\facade\Db;
class Foo
{
public function get(Request $request)
{
$user = Db::table('user')->where('uid', '>', 1)->find();
return json($user);
}
}
ThinkORM使用文檔
單庫和一主一從可以用,但是我今天恰好遇到了一個問題
我是4個數(shù)據(jù)庫,2主,2從架構(gòu)
數(shù)據(jù)量較大,可能會存在這個情況
因為webman啟動后,orm常駐內(nèi)存,所以用過之后就不會銷毀,那么問題來了,
當(dāng)使用think-orm的模型進(jìn)行增刪改查的操作室,這個$this->linkWrite和$this->linkRead,除了第一次沒有值,之后永遠(yuǎn)有值,不管后面是第幾個請求過來,這個時候數(shù)據(jù)庫架構(gòu)就變成了 1主1從,因為是常駐內(nèi)存,另外一個主和另外一個從沒有機(jī)會參與選取,
我也試著讓他參數(shù)選取“自定義”的一個參數(shù)master_election,讓程序在執(zhí)行mysql操作的時候,在兩個主庫之間進(jìn)行二選一
事實證明是可行的,可以隨機(jī)在兩個主庫當(dāng)中選擇一個
但是問題又來了,
假如A用戶在執(zhí)行事務(wù)操作,那么這個時候,讀寫都應(yīng)該是在一個主庫進(jìn)行(因為數(shù)據(jù)量一大有很大幾率卡主從),A將master_election(自定義的一個參數(shù))設(shè)置為false ,因為是常駐內(nèi)存,與此同時B用戶設(shè)置master_election(自定義的一個參數(shù))為 true,這個時候就存在B用戶污染了A用戶,導(dǎo)致A在主庫1執(zhí)行了新增操作,由于數(shù)據(jù)量大,卡了一下主從,A在讀取時兩個master進(jìn)行選舉,選到了主庫2,查詢沒有數(shù)據(jù),事務(wù)失敗
想請教一下樓主怎么解決這個的思路是什么,(有一種辦法是一直傳參數(shù),從最上層傳到最底層,但是不現(xiàn)實)