作者 邓超

优化数据库,mysql链接

... ... @@ -115,7 +115,7 @@ class SendJob {
// 查询邮箱
$email = db()->first(\Model\emailSql::first($data['email_id']));
// 更新状态
$upStatus = \Model\sendJobsSql::upStatus($data['id'],1,db());
$upStatus = \Model\sendJobsSql::upStatus($data['id'],1);
_echo('更新任务状态 '.$data['id'].' ==> '.$upStatus);
// 是否是单发送
if($data['maildata']['massSuit']??0){
... ... @@ -225,12 +225,9 @@ class SendJob {
// 写入日志
\Lib\Log::getInstance()->write();
// 结束后要关闭数据库链接,不然链接一直暂用
db()->close();
// 删除占用
redis()->delete('send_job_run_id_'.$data['id']);
redis()->close();
_echo('执行任务完成'.$data['id']);
... ...
... ... @@ -111,11 +111,6 @@ function start(){
// 写入日志
\Lib\Log::getInstance()->write();
// 关闭数据库链接
db()->close();
// 关闭redis链接
redis()->close();
});
});
... ... @@ -189,10 +184,6 @@ function start(){
// 写入日志
\Lib\Log::getInstance()->write();
// 关闭数据库链接
db()->close();
// 关闭redis链接
redis()->close();
});
... ...
... ... @@ -14,34 +14,42 @@ function posix_pid(){
return $pid ? $pid : 0;
}
/**
* redis 驱动
* @return \Lib\RedisPool
* @return \Lib\RedisPool|\Lib\Redis
* @author:dc
* @time 2023/2/13 9:44
*/
function redis():\Lib\RedisPool {
function redis():\Lib\RedisPool|\Lib\Redis {
if(co::getCid()){
return new \Lib\RedisPool();
}
return \Lib\RedisPool::instance(posix_pid().'_'.co::getCid());
return \Lib\Redis::instance();
}
/**
* 操作db
* @return \Lib\DbPool
* @return \Lib\Db|\Lib\DbPool
* @author:dc
* @time 2023/2/13 14:15
*/
function db():\Lib\DbPool{
return \Lib\DbPool::instance(posix_pid().'_'.co::getCid());
function db():\Lib\Db|\Lib\DbPool{
// 池子
if(co::getCid()){
return new \Lib\DbPool();
}
// 非池子
return \Lib\Db::instance();
}
/**
* 记录日志
* @param $message
... ...
<?php
namespace Lib;
/**
* db
* @author:dc
* @time 2023/2/13 15:03
* Class Db
* @package Lib
*/
class Db {
use DbQuery;
/**
* @var \Lib\Db
*/
static $instance;
/**
* @return mixed
* @author:dc
* @time 2023/2/13 9:12
*/
public function getClient(){
if(!$this->client){
$this->connect();
}
try {
// 判断是否链接中
if($this->client->getAttribute(\PDO::ATTR_CONNECTION_STATUS)===false){
$this->connect();
}
}catch (\Throwable $e){
$this->connect();
}
return $this->client;
}
public function __construct()
{
$this->connect();
}
/**
* 连接sql
* @author:dc
* @time 2023/3/23 9:14
*/
public function connect(){
$tryNum = 0;
DBPOOLCONNECTFOR:
try {
$this->client = new \PDO(
'mysql:charset=utf8mb4;dbname='.DB_DATABASE.';host='.DB_HOST.';port='.DB_PORT,
DB_USER,
DB_PASSWORD,
[
\PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC,
\PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8mb4'",
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
]
);
}catch (\Throwable $e){
// 重新链接3次
if($tryNum < 3){
$tryNum++;
goto DBPOOLCONNECTFOR;
}
logs($e->getMessage().$e->getTraceAsString());
}
}
/**
* @return Db
* @author:dc
* @time 2023/2/13 9:39
*/
public static function instance(){
if(empty(static::$instance)){
static::$instance = new Db();
}
if(!static::$instance->ping()){
static::$instance->close();
static::$instance = new Db();
}
return static::$instance;
}
/**
* 结束
*/
public function __destruct(){
$this->close();
}
public function close(){
$this->client = null;
}
}
... ...
... ... @@ -2,6 +2,9 @@
namespace Lib;
use Swoole\Database\PDOConfig;
use Swoole\Database\PDOPool;
/**
* db 池
* @author:dc
... ... @@ -11,384 +14,43 @@ namespace Lib;
*/
class DbPool {
/**
* @var \Lib\DbPool[]
*/
static $instance = [];
/**
* @var \PDO
*/
private $client;
use DbQuery;
/**
* @var
* @var \Swoole\Database\PDOPool
*/
private $cid;
static $pool = null;
public $lastTimer;
/**
* @return mixed
* @author:dc
* @time 2023/2/13 9:12
* 实例
* DbPool constructor.
*/
public function getClient(){
if(!$this->client){
$this->connect();
}
try {
// 判断是否链接中
if($this->client->getAttribute(\PDO::ATTR_CONNECTION_STATUS)===false){
$this->connect();
}
}catch (\Throwable $e){
$this->connect();
}
$this->lastTimer = time();
return $this->client;
}
public function __construct($cid)
public function __construct()
{
$this->cid = $cid;
$this->connect();
}
/**
* 连接sql
* @author:dc
* @time 2023/3/23 9:14
*/
public function connect(){
$this->lastTimer = time();
$tryNum = 0;
DBPOOLCONNECTFOR:
try {
$this->client = new \PDO(
'mysql:charset=utf8mb4;dbname='.DB_DATABASE.';host='.DB_HOST.';port='.DB_PORT,
DB_USER,
DB_PASSWORD,
[
if(!static::$pool){
$pdoconfig = (new PDOConfig)
->withHost(DB_HOST)
->withPort(DB_PORT)
->withDbName(DB_DATABASE)
->withCharset('utf8mb4')
->withUsername(DB_USER)
->withPassword(DB_PASSWORD)
->withOptions([
\PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC,
\PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8mb4'",
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
]
);
}catch (\Throwable $e){
// 重新链接3次
if($tryNum < 3){
$tryNum++;
goto DBPOOLCONNECTFOR;
}
logs($e->getMessage().$e->getTraceAsString());
}
}
/**
* 查询
* @param string|array $sql
* @return false|\PDOStatement
* @author:dc
* @time 2023/2/17 10:01
*/
private function query(string|array $sql){
if(is_array($sql)){
list($sql,$params) = $sql;
}else{
$params = null;
}
if(APP_DEBUG) {
$timer = microtime(true);
}
try {
$query = $this->getClient()->prepare($sql);
$ret = $query->execute($params);
}catch (\Throwable $e){
logs([
$sql,$params,
$e->getMessage(),
$e->getTraceAsString()
],
LOG_PATH.'/'.date('Y-m-d').'-sql.error.log'
);
$ret = false;
}
if(APP_DEBUG){
$timer2 = microtime(true);
// todo:: 记录日志,生产请注释
$sql = '['.substr(($timer2-$timer)*1000,0,6).'ms] '.$sql;
logs(
$params ? [$sql,$params] : $sql,
LOG_PATH.'/'.date('Y-m-d').'.sql.log'
);
}
if($ret){
return $query;
}
return false;
}
/**
* 更新数据
* @param string $table
* @param array $data
* @param string $where
* @param bool $timeauto
* @return int
* @author:dc
* @time 2023/2/17 14:03
*/
public function update(string $table, array $data, string $where, $timeauto = true):int {
if($timeauto){
$data['updated_at'] = empty($data['updated_at']) ? date('Y-m-d H:i:s') : $data['updated_at'];
}
$sql = "update `{$table}` set ".dbUpdate($data). " where ".$where;
$data = $this->getData($data);
$query = $this->query([$sql,$data]);
if($query){
return $query->rowCount();
}
return 0;
}
/**
* 在更新/插入时处理数据
* @param $data
* @return mixed
* @author:dc
* @time 2023/2/18 14:50
*/
private function getData($data){
// 如果存储的值是数组,就json一次
foreach ($data as $k=>$datum){
if(is_array($datum)){
$data[$k] = json_encode($datum,JSON_UNESCAPED_UNICODE);
}elseif ($datum === null){
$data[$k] = '';
}
}
return $data;
}
/**
* 插入数据
* @param string $table
* @param array $data
* @param bool $timeauto
* @return int
* @author:dc
* @time 2023/2/17 14:04
*/
public function insert(string $table, array $data, $timeauto = true):int {
if($timeauto){
$data['created_at'] = empty($data['created_at']) ? date('Y-m-d H:i:s') : $data['created_at'];
}
$sql = "insert into `{$table}` set ".dbUpdate($data);
$data = $this->getData($data);
$query = $this->query([$sql,$data]);
if($query){
return $this->getClient()->lastInsertId();
}
return 0;
}
/**
* 删除语句 软删
* @param string $table
* @param array $where
* @param null $upFiled
* @return int
* @author:dc
* @time 2023/4/11 14:47
*/
public function delete(string $table, array $where,$upFiled=null){
if($upFiled){
return $this->update($table,[$upFiled === true ? 'deleted_at' : $upFiled =>time()],$where);
}
$sql = "delete from `{$table}` where ".dbUpdate($where);
$query = $this->query([$sql,$where]);
if($query){
return $query->rowCount();
}
return 0;
}
/**
* 统计数量
* @param string $sql
* @return int
* @author:dc
* @time 2023/2/14 16:19
*/
public function count(string|array $sql):int{
$query = $this->query($sql);
if($query){
return $query->fetch(\PDO::FETCH_COLUMN);
}
return 0;
}
]);
/**
* 某个值
* @param string|array $sql
* @return mixed|null
* @author:dc
* @time 2023/2/17 11:03
*/
public function value(string|array $sql){
$query = $this->query($sql);
if($query){
return $query->fetch(\PDO::FETCH_COLUMN);
static::$pool = new PDOPool($pdoconfig,1024);
}
return null;
}
/**
* 查询一条数据
* @param string|array $sql
* @return mixed|null
* @author:dc
* @time 2023/2/13 14:54
*/
public function first(string|array $sql){
$query = $this->query($sql);
if($query){
return $query->fetch();
}
// 获取链接
$this->client = static::$pool->get();
return null;
}
/**
* 查询列表
* @param string|array $sql
* @return mixed|null
* @author:dc
* @time 2023/2/13 14:54
*/
public function all(string|array $sql){
$query = $this->query($sql);
if($query){
return $query->fetchAll();
}
return null;
}
/**
* 事务开启
* @author:dc
* @time 2023/2/17 11:35
*/
public function transaction(){
$this->getClient()->beginTransaction();
}
/**
* 事务回滚
* @author:dc
* @time 2023/2/17 11:35
*/
public function rollBack(){
$this->getClient()->rollBack();
}
/**
* 事务提交
* @author:dc
* @time 2023/2/17 11:35
*/
public function commit(){
$this->getClient()->commit();
}
/**
* 验证是否正常连接
* @return bool
* @author:dc
* @time 2024/4/10 10:09
*/
public function ping(){
try {
$query = $this->getClient()->query("select 200;");
if($query->fetchColumn() == 200){
return true;
}
}catch (\Throwable $e){
return false;
}
return false;
}
/**
* @param $cid
* @return DbPool
* @author:dc
* @time 2023/2/13 9:39
*/
public static function instance($cid=0){
if(empty(static::$instance[$cid])){
static::$instance[$cid] = new DbPool($cid);
}
if(!static::$instance[$cid]->ping()){
static::$instance[$cid]->close();
static::$instance[$cid] = new DbPool($cid);
}
return static::$instance[$cid];
}
/**
... ... @@ -398,10 +60,14 @@ class DbPool {
$this->close();
}
/**
* 关闭链接
* @author:dc
* @time 2024/5/30 10:30
*/
public function close(){
self::$pool->put($this->client);
$this->client = null;
unset(static::$instance[$this->cid]);
}
... ...
<?php
namespace Lib;
/**
* db 查询
* @author:dc
* @time 2023/2/13 15:03
* Class DbPool
* @package Lib
*/
trait DbQuery {
/**
* @var \PDO|null
*/
protected $client;
public function getClient()
{
return $this->client;
}
/**
* 查询
* @param string|array $sql
* @return false|\PDOStatement
* @author:dc
* @time 2023/2/17 10:01
*/
public function query(string|array $sql){
if(is_array($sql)){
list($sql,$params) = $sql;
}else{
$params = null;
}
if(APP_DEBUG) {
$timer = microtime(true);
}
try {
$query = $this->getClient()->prepare($sql);
$ret = $query->execute($params);
}catch (\Throwable $e){
logs([
$sql,$params,
$e->getMessage(),
$e->getTraceAsString()
],
LOG_PATH.'/'.date('Y-m-d').'-sql.error.log'
);
$ret = false;
}
if(APP_DEBUG){
$timer2 = microtime(true);
// todo:: 记录日志,生产请注释
$sql = '['.substr(($timer2-$timer)*1000,0,6).'ms] '.$sql;
logs(
$params ? [$sql,$params] : $sql,
LOG_PATH.'/'.date('Y-m-d').'.sql.log'
);
}
if($ret){
return $query;
}
return false;
}
/**
* 更新数据
* @param string $table
* @param array $data
* @param string $where
* @param bool $timeauto
* @return int
* @author:dc
* @time 2023/2/17 14:03
*/
public function update(string $table, array $data, string $where, $timeauto = true):int {
if($timeauto){
$data['updated_at'] = empty($data['updated_at']) ? date('Y-m-d H:i:s') : $data['updated_at'];
}
$sql = "update `{$table}` set ".dbUpdate($data). " where ".$where;
$data = $this->getData($data);
$query = $this->query([$sql,$data]);
if($query){
return $query->rowCount();
}
return 0;
}
/**
* 在更新/插入时处理数据
* @param $data
* @return mixed
* @author:dc
* @time 2023/2/18 14:50
*/
public function getData($data){
// 如果存储的值是数组,就json一次
foreach ($data as $k=>$datum){
if(is_array($datum)){
$data[$k] = json_encode($datum,JSON_UNESCAPED_UNICODE);
}elseif ($datum === null){
$data[$k] = '';
}
}
return $data;
}
/**
* 插入数据
* @param string $table
* @param array $data
* @param bool $timeauto
* @return int
* @author:dc
* @time 2023/2/17 14:04
*/
public function insert(string $table, array $data, $timeauto = true):int {
if($timeauto){
$data['created_at'] = empty($data['created_at']) ? date('Y-m-d H:i:s') : $data['created_at'];
}
$sql = "insert into `{$table}` set ".dbUpdate($data);
$data = $this->getData($data);
$query = $this->query([$sql,$data]);
if($query){
return $this->getClient()->lastInsertId();
}
return 0;
}
/**
* 删除语句 软删
* @param string $table
* @param array $where
* @param null $upFiled
* @return int
* @author:dc
* @time 2023/4/11 14:47
*/
public function delete(string $table, array $where,$upFiled=null){
if($upFiled){
return $this->update($table,[$upFiled === true ? 'deleted_at' : $upFiled =>time()],$where);
}
$sql = "delete from `{$table}` where ".dbUpdate($where);
$query = $this->query([$sql,$where]);
if($query){
return $query->rowCount();
}
return 0;
}
/**
* 统计数量
* @param string $sql
* @return int
* @author:dc
* @time 2023/2/14 16:19
*/
public function count(string|array $sql):int{
$query = $this->query($sql);
if($query){
return $query->fetch(\PDO::FETCH_COLUMN);
}
return 0;
}
/**
* 某个值
* @param string|array $sql
* @return mixed|null
* @author:dc
* @time 2023/2/17 11:03
*/
public function value(string|array $sql){
$query = $this->query($sql);
if($query){
return $query->fetch(\PDO::FETCH_COLUMN);
}
return null;
}
/**
* 查询一条数据
* @param string|array $sql
* @return mixed|null
* @author:dc
* @time 2023/2/13 14:54
*/
public function first(string|array $sql){
$query = $this->query($sql);
if($query){
return $query->fetch();
}
return null;
}
/**
* 查询列表
* @param string|array $sql
* @return mixed|null
* @author:dc
* @time 2023/2/13 14:54
*/
public function all(string|array $sql){
$query = $this->query($sql);
if($query){
return $query->fetchAll();
}
return null;
}
/**
* 事务开启
* @author:dc
* @time 2023/2/17 11:35
*/
public function transaction(){
$this->getClient()->beginTransaction();
}
/**
* 事务回滚
* @author:dc
* @time 2023/2/17 11:35
*/
public function rollBack(){
$this->getClient()->rollBack();
}
/**
* 事务提交
* @author:dc
* @time 2023/2/17 11:35
*/
public function commit(){
$this->getClient()->commit();
}
/**
* 验证是否正常连接
* @return bool
* @author:dc
* @time 2024/4/10 10:09
*/
public function ping(){
try {
$query = $this->getClient()->query("select 200;");
if($query->fetchColumn() == 200){
return true;
}
}catch (\Throwable $e){
return false;
}
return false;
}
}
... ...
<?php
namespace Lib;
/**
* redis 链接池 swoole内置了链接池,自能在协程中使用,所以单独写出来
* @author:dc
* @time 2023/2/10 17:04
* Class Redis
*/
class Redis {
use RedisQuery;
/**
* @var \Lib\Redis
*/
static $instance;
/**
* Redis constructor.
*/
public function __construct()
{
if(!$this->conn()){
$this->conn();
}
}
/**
* @return \Redis
* @author:dc
* @time 2023/4/12 15:11
*/
public function getClient(){
try {
if(!$this->client->ping()){
$this->conn();
}
}catch (\Throwable $e){
$this->conn();
}
return $this->client;
}
/**
* 链接
* @author:dc
* @time 2023/4/12 15:10
*/
private function conn(){
$this->client = new \Redis();
if($this->client->pconnect(REDIS_HOST,REDIS_PORT,2)){
// 密码
REDIS_PASSWORD && $this->client->auth(REDIS_PASSWORD);
// 用库4
$this->client->select(REDIS_DB);
return true;
}
return false;
}
/**
*
*/
public function __destruct()
{
$this->close();
}
/**
* @return \Lib\Redis
* @author:dc
* @time 2023/2/13 9:38
*/
public static function instance(){
if(empty(static::$instance)){
static::$instance = new \Lib\Redis();
}
try {
static::$instance->client->ping();
}catch (\Throwable $e){
static::$instance->close();
static::$instance = new \Lib\Redis();
}
return static::$instance;
}
/**
* 关闭
* @author:dc
* @time 2023/3/16 13:42
*/
public function close(){
// TODO: Implement __destruct() method.
try {
$this->client->ping();
$this->client->close();
}catch (\Throwable $e){
}
$this->client = null;
}
}
... ...
... ... @@ -2,291 +2,46 @@
namespace Lib;
use Swoole\Database\RedisConfig;
/**
* redis 链接池 swoole内置了链接池,自能在协程中使用,所以单独写出来
* redis 链接池
* @author:dc
* @time 2023/2/10 17:04
* Class RedisPool
*/
class RedisPool {
/**
* @var \Lib\RedisPool[]
*/
static $instance = [];
use RedisQuery;
/**
* @var \Redis
* @var \Swoole\Database\RedisPool
*/
private $client;
static $pool = null;
/**
* @var
*/
private $cid;
/**
* 最后执行的时间
* @var int
* RedisPool constructor.
*/
public $lastTimer;
public function __construct($cid)
public function __construct()
{
$this->cid = $cid;
$this->conn();
}
/**
* 链接
* @author:dc
* @time 2023/4/12 15:10
*/
private function conn(){
$this->lastTimer = time();
$this->client = new \Redis();
$this->client->pconnect(REDIS_HOST,REDIS_PORT,2);
// 密码
REDIS_PASSWORD && $this->client->auth(REDIS_PASSWORD);
// 用库4
$this->client->select(REDIS_DB);
}
/**
* @param $key
* @return bool|int
* @author:dc
* @time 2023/2/10 18:06
*/
public function has($key)
{
return $this->getClient()->exists($key);
}
/**
* @param $key
* @param null $default
* @return mixed|null
* @author:dc
* @time 2023/2/10 18:04
*/
public function get($key, $default=null)
{
$data = $this->getClient()->get($key);
if($data === null){
return $default;
}
return $this->unserialize($data);
}
/**
* 获取原数据
* @param $key
* @return false|mixed|string
* @author:dc
* @time 2023/4/12 16:51
*/
public function getOriginData($key){
return $this->getClient()->get($key);
}
/**
* @param $key
* @param $val
* @param null $ttl
* @return bool
* @author:dc
* @time 2023/2/10 18:02
*/
public function set($key,$val,$ttl=null) {
return $this->getClient()->set($key,$this->serialize($val),$ttl);
}
/**
* 如果有key返回false,没有则新增
* @param $key
* @param $val
* @param null $ttl
* @return mixed
* @author:dc
* @time 2023/2/10 17:53
*/
public function add($key,$val,$ttl=null):mixed {
return $this->getClient()->eval(
"return redis.call('exists',KEYS[1])<1 and redis.call('setex',KEYS[1],ARGV[2],ARGV[1])",
[$key, $this->serialize($val), $ttl],
1
);
}
/**
* @param $key
* @param $value
* @return false|int
* @author:dc
* @time 2023/2/13 9:07
*/
public function lPush($key,$value){
return $this->getClient()->lPush($key,$this->serialize($value));
}
/**
* @param $key
* @param $value
* @return false|int
* @author:dc
* @time 2023/2/13 9:07
*/
public function rPush($key,$value){
return $this->getClient()->rPush($key,$this->serialize($value));
}
/**
* @param $key
* @return bool|mixed
* @author:dc
* @time 2023/2/13 9:08
*/
public function lPop($key){
return $this->unserialize($this->getClient()->lPop($key));
}
/**
* @param $key
* @return mixed|string
* @author:dc
* @time 2023/2/13 9:09
*/
public function rPop($key){
return $this->unserialize($this->getClient()->rPop($key));
}
/**
* 自增
* @param $key
* @param null $ttl
* @return int
* @author:dc
* @time 2023/2/17 15:29
*/
public function incr($key, $ttl = null){
if($ttl){
return $this->getClient()->eval(
"
if redis.call('exists',KEYS[1]) == 0 then
local x = redis.call('incr',KEYS[1])
if x then
redis.call('expire',KEYS[1],ARGV[1])
end
return x
else
return redis.call('incr',KEYS[1])
end",
[$key, $ttl],
1
if(empty(static::$pool)){
static::$pool = new \Swoole\Database\RedisPool((new RedisConfig)
->withHost(REDIS_HOST)
->withPort(REDIS_PORT)
->withAuth(REDIS_PASSWORD)
->withDbIndex(REDIS_DB)
->withTimeout(1)
,1024
);
}
return $this->getClient()->incr($key);
}
/**
* 自减
* @param $key
* @param null $ttl
* @return int
* @author:dc
* @time 2023/3/16 11:19
*/
public function decr($key,$ttl = null){
if($ttl){
return $this->getClient()->eval(
"
if redis.call('exists',KEYS[1]) == 0 then
local x = redis.call('decr',KEYS[1])
if x then
redis.call('expire',KEYS[1],ARGV[1])
end
return x
else
return redis.call('decr',KEYS[1])
end",
[$key, $ttl],
1
);
}
return $this->getClient()->decr($key);
}
/**
* 删除
* @param $key
* @return int
* @author:dc
* @time 2023/2/14 14:04
*/
public function delete(...$key):int {
return $this->getClient()->del(...$key);
// 获取一个连接,放入当前实例
$this->client = static::$pool->get();
}
/**
* 获取值并删除
* @param $key
* @return mixed
* @author:dc
* @time 2023/3/16 11:36
*/
public function getDel($key){
return $this->getClient()->eval(
"local x = redis.call('get',KEYS[1]);if x then redis.call('del',KEYS[1]) end return x",
[$key],
1
);
}
/**
* @param $val
* @return string
* @author:dc
* @time 2023/2/10 17:57
*/
private function serialize($val){
return $val ? serialize($val) : '';
}
/**
* @param $val
* @return mixed
* @author:dc
* @time 2023/2/10 17:58
*/
private function unserialize($val){
return $val ? unserialize($val) : '';
}
/**
* @return \Redis
* @author:dc
* @time 2023/4/12 15:11
*/
public function getClient(){
try {
if(!$this->client->ping()){
$this->conn();
}
}catch (\Throwable $e){
$this->conn();
}
$this->lastTimer = time();
return $this->client;
}
... ... @@ -297,43 +52,14 @@ end",
/**
* @param $cid
* @return \Lib\RedisPool
* @author:dc
* @time 2023/2/13 9:38
*/
public static function instance($cid){
if(empty(static::$instance[$cid])){
static::$instance[$cid] = new \Lib\RedisPool($cid);
}
try {
static::$instance[$cid]->client->ping();
}catch (\Throwable $e){
static::$instance[$cid]->close();
static::$instance[$cid] = new \Lib\RedisPool($cid);
}
return static::$instance[$cid];
}
/**
* 关闭
* @author:dc
* @time 2023/3/16 13:42
*/
public function close(){
// TODO: Implement __destruct() method.
try {
$this->client->ping();
$this->client->close();
}catch (\Throwable $e){
}
self::$pool->put($this->client);
unset(static::$instance[$this->cid]);
$this->client = null;
}
... ...
<?php
namespace Lib;
/**
* redis 的操作
* @author:dc
* @time 2024/5/30 10:50
* Class RedisQuery
* @package Lib
*/
trait RedisQuery {
/**
* @var \Redis
*/
protected $client;
/**
* @param $key
* @return bool|int
* @author:dc
* @time 2023/2/10 18:06
*/
public function has($key)
{
return $this->getClient()->exists($key);
}
/**
* @param $key
* @param null $default
* @return mixed|null
* @author:dc
* @time 2023/2/10 18:04
*/
public function get($key, $default=null)
{
$data = $this->getClient()->get($key);
if($data === null){
return $default;
}
return $this->unserialize($data);
}
/**
* 获取原数据
* @param $key
* @return false|mixed|string
* @author:dc
* @time 2023/4/12 16:51
*/
public function getOriginData($key){
return $this->getClient()->get($key);
}
/**
* @param $key
* @param $val
* @param null $ttl
* @return bool
* @author:dc
* @time 2023/2/10 18:02
*/
public function set($key,$val,$ttl=null) {
return $this->getClient()->set($key,$this->serialize($val),$ttl);
}
/**
* 如果有key返回false,没有则新增
* @param $key
* @param $val
* @param null $ttl
* @return mixed
* @author:dc
* @time 2023/2/10 17:53
*/
public function add($key,$val,$ttl=null):mixed {
return $this->getClient()->eval(
"return redis.call('exists',KEYS[1])<1 and redis.call('setex',KEYS[1],ARGV[2],ARGV[1])",
[$key, $this->serialize($val), $ttl],
1
);
}
/**
* @param $key
* @param $value
* @return false|int
* @author:dc
* @time 2023/2/13 9:07
*/
public function lPush($key,$value){
return $this->getClient()->lPush($key,$this->serialize($value));
}
/**
* @param $key
* @param $value
* @return false|int
* @author:dc
* @time 2023/2/13 9:07
*/
public function rPush($key,$value){
return $this->getClient()->rPush($key,$this->serialize($value));
}
/**
* @param $key
* @return bool|mixed
* @author:dc
* @time 2023/2/13 9:08
*/
public function lPop($key){
return $this->unserialize($this->getClient()->lPop($key));
}
/**
* @param $key
* @return mixed|string
* @author:dc
* @time 2023/2/13 9:09
*/
public function rPop($key){
return $this->unserialize($this->getClient()->rPop($key));
}
/**
* 自增
* @param $key
* @param null $ttl
* @return int
* @author:dc
* @time 2023/2/17 15:29
*/
public function incr($key, $ttl = null){
if($ttl){
return $this->getClient()->eval(
"
if redis.call('exists',KEYS[1]) == 0 then
local x = redis.call('incr',KEYS[1])
if x then
redis.call('expire',KEYS[1],ARGV[1])
end
return x
else
return redis.call('incr',KEYS[1])
end",
[$key, $ttl],
1
);
}
return $this->getClient()->incr($key);
}
/**
* 自减
* @param $key
* @param null $ttl
* @return int
* @author:dc
* @time 2023/3/16 11:19
*/
public function decr($key,$ttl = null){
if($ttl){
return $this->getClient()->eval(
"
if redis.call('exists',KEYS[1]) == 0 then
local x = redis.call('decr',KEYS[1])
if x then
redis.call('expire',KEYS[1],ARGV[1])
end
return x
else
return redis.call('decr',KEYS[1])
end",
[$key, $ttl],
1
);
}
return $this->getClient()->decr($key);
}
/**
* 删除
* @param $key
* @return int
* @author:dc
* @time 2023/2/14 14:04
*/
public function delete(...$key):int {
return $this->getClient()->del(...$key);
}
/**
* 获取值并删除
* @param $key
* @return mixed
* @author:dc
* @time 2023/3/16 11:36
*/
public function getDel($key){
return $this->getClient()->eval(
"local x = redis.call('get',KEYS[1]);if x then redis.call('del',KEYS[1]) end return x",
[$key],
1
);
}
/**
* @param $val
* @return string
* @author:dc
* @time 2023/2/10 17:57
*/
private function serialize($val){
return $val ? serialize($val) : '';
}
/**
* @param $val
* @return mixed
* @author:dc
* @time 2023/2/10 17:58
*/
private function unserialize($val){
return $val ? unserialize($val) : '';
}
/**
* @return \Redis
* @author:dc
* @time 2023/4/12 15:11
*/
public function getClient(){
return $this->client;
}
}
... ...
... ... @@ -74,10 +74,9 @@ class sendJobsSql {
* @author:dc
* @time 2023/4/11 16:06
*/
public static function upStatus(int $id, int $status, $db=null){
$db = $db?:db();
public static function upStatus(int $id, int $status){
// 更新状态
return $db->update(\Model\sendJobsSql::$table,[
return db()->update(\Model\sendJobsSql::$table,[
'status' => $status
],dbWhere([
'id' => $id
... ...
... ... @@ -4,11 +4,14 @@
* 邮件管理
* TODO::此项目是纯数据上的管理,不设计到界面。所以不允许返回任何非 json 类型 的数据/头部
*/
\Co\run(function (){
require_once "../vendor/autoload.php";
require_once "../vendor/autoload.php";
\Lib\App::run();
});
\Lib\App::run();
... ...