如果session用redis的话在swoole环境中,只要并发上来就报错。
我用的ab -n10000 -c100 测试的

但是默认的是文件保存,就没一点问题。
感觉是连接池的问题,但是没找到关于session方面对于redis的文档和文章
有没有大佬讲解一下这是为啥🤔🤔🤔🤔🤔🤔
➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖
<?php
declare(strict_types=1);
namespace app\support\Session;
use Illuminate\Redis\Connections\PhpRedisConnection;
use RuntimeException;
use Throwable;
use support\Redis as UseRedis;
use Workerman\Protocols\Http\Session;
class RedisSessionHandler implements \Workerman\Protocols\Http\Session\SessionHandlerInterface
{
protected array $config;
protected string $sessionPrefix;
public function __construct(array $config)
{
// 检查 Redis 扩展
if (false === extension_loaded('redis')) {
throw new RuntimeException('Please install redis extension.');
}
//初始化配置:指定用 Session 专属连接池
$this->config = $config + [
'connection' => 'session',
'prefix' => 'webman_session:',
];
$this->sessionPrefix = $this->config['prefix'];
}
/**
* 每次操作都重新获取 Redis 连接
* 避免协程间连接竞争
*/
protected function getRedis(): PhpRedisConnection
{
return UseRedis::connection($this->config['connection']);
}
// ------------------- 修改所有方法,使用 getRedis() 获取连接 -------------------
public function open(string $savePath, string $name): bool
{
return true;
}
public function read(string $sessionId): string|false
{
try {
$redis = $this->getRedis(); // 每次操作获取新连接
$key = $this->sessionPrefix . $sessionId;
$data = $redis->get($key);
return $data ?: '';
} catch (Throwable $e) {
throw $e;
}
}
public function write(string $sessionId, string $sessionData): bool
{
$redis = $this->getRedis(); // 每次操作获取新连接
$key = $this->sessionPrefix . $sessionId;
return true === $redis->setex($key, Session::$lifetime, $sessionData);
}
public function updateTimestamp(string $sessionId, string $data = ""): bool
{
$redis = $this->getRedis(); // 每次操作获取新连接
$key = $this->sessionPrefix . $sessionId;
return true === $redis->expire($key, Session::$lifetime);
}
public function destroy(string $sessionId): bool
{
$redis = $this->getRedis(); // 每次操作获取新连接
$key = $this->sessionPrefix . $sessionId;
$redis->del($key);
return true;
}
public function close(): bool
{
return true;
}
public function gc(int $maxLifetime): bool
{
return true;
}
}
➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖
➖➖➖➖➖➖➖➖➖以上代码已没啥用,仅供学习➖➖➖➖➖➖➖➖➖➖➖➖➖➖
➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖
昨天更新了workerman5.1.4
这个问题解决了。再也不用自己单独写一个处理了🎉🎉🎉🎉🎉🎉
workermanV5.1.4添加了redis连接池功能 升级下即可 composer require -W workerman/workerman:~5.1
知道啦,谢谢大佬