关于session 的 redis 实现问题,目前参考了ci和laravel 的实现,有些疑问?
1.laravel
看了文档,文档中使用的是 predis 这个包,实现 session redis handel 地址:
github.com/predis/predis/blob/v1.1...
/**
* {@inheritdoc}
* @return bool
*/
#[\ReturnTypeWillChange]
public function write($session_id, $session_data)
{
$this->client->setex($session_id, $this->ttl, $session_data);
return true;
}
实现起来有点简单,setnx 都不判断返回值的么?
2.ci
自带 session redis handel 地址
github.com/codeigniter4/CodeIgnite...
/**
* Acquires an emulated lock.
*
* @param string $sessionID Session ID
*/
protected function lockSession(string $sessionID): bool
{
// PHP 7 reuses the SessionHandler object on regeneration,
// so we need to check here if the lock key is for the
// correct session ID.
if ($this->lockKey === $this->keyPrefix . $sessionID . ':lock') {
return $this->redis->expire($this->lockKey, 300);
}
$lockKey = $this->keyPrefix . $sessionID . ':lock';
$attempt = 0;
do {
if (($ttl = $this->redis->ttl($lockKey)) > 0) {
sleep(1);
continue;
}
if (! $this->redis->setex($lockKey, 300, (string) time())) {
$this->logger->error('Session: Error while trying to obtain lock for ' . $this->keyPrefix . $sessionID);
return false;
}
$this->lockKey = $lockKey;
break;
} while (++$attempt < 30);
if ($attempt === 30) {
log_message('error', 'Session: Unable to obtain lock for ' . $this->keyPrefix . $sessionID . ' after 30 attempts, aborting.');
return false;
}
if ($ttl === -1) {
log_message('debug', 'Session: Lock for ' . $this->keyPrefix . $sessionID . ' had no TTL, overriding.');
}
$this->lock = true;
return true;
}
注意,lockSession 方法里的 sleep?
这是啥,这里有个问题,相同 session 的并发请求,会造成 1s 上的延迟,这是啥?(这里 sleep 我们团队直接改成 100ms 了)
争议连接:github.com/bcit-ci/CodeIgniter/pul...
就感觉这两种实现方式,都有点奇怪,有没有大佬说下?
我准备再去看看其他框架的实现,大家一起沟通下
推荐文章: