class RedisManager
{
private static ?\Redis $instance = null;
// 单例 + 自动重连
public static function conn(): \Redis
{
if (self::$instance === null) {
self::$instance = new \Redis();
self::$instance-connect('127.0.0.1', 6379, 0.5);
self::$instance-setOption(\Redis::OPT_SERIALIZER, \Redis::SERIALIZER_JSON);
self::$instance-setOption(\Redis::OPT_PREFIX, 'app:');
}
// 心跳检测,断线自动重连
if (!self::$instance-ping()) {
self::$instance-connect('127.0.0.1', 6379, 0.5);
}
return self::$instance;
}
// 业务封装示例:缓存 + 防雪崩
public static function remember(string $key, int $ttl, callable $loader)
{
$redis = self::conn();
$data = $redis-get($key);
if ($data === false) {
$data = $loader();
$redis-setex($key, $ttl, $data);
}
return $data;
}
// Lua 脚本原子扣库存(秒杀)
public static function decrStock(string $sku, int $num): bool
{
$lua = <<<LUA
local key = KEYS[1]
local num = tonumber(ARGV[1])
local stock = tonumber(redis.call('GET', key) or 0)
if stock = num then
redis.call('DECRBY', key, num)
return 1
else
return 0
end
LUA;
return (bool) self::conn()-eval($lua, [$sku, $num], 1);
}
}
使用示例
php
require 'vendor/autoload';
use App\RedisManager;