关于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...

就感觉这两种实现方式,都有点奇怪,有没有大佬说下?
我准备再去看看其他框架的实现,大家一起沟通下

《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
讨论数量: 8

我再去看看 协程框架的

2年前 评论

hyperf 的 与laravel 类似,但是没有上面说的直接返回 true 的问题, 关于ci 的实现,感觉是,在程序方面 采用 sleep 重试的方式,减缓 redis 的压力。

2年前 评论

1 假设没有异常的话 确实不应该

2 看样子是锁的重试。 类似Lock之类的组件代码过一遍 都有sleep

2年前 评论
zion_xayts_com (楼主) 2年前
cvoid (作者) 2年前
zion_xayts_com (楼主) 2年前

@Macken 这个是谁?咋没看到,管理员么

2年前 评论
  • 第一种方式比较简单粗暴,正常情况下是会写入成功的,如果在下面你用上面写入session数据做判断的时候可能已经被其他线程修改了
  • 第二个是做了防止session并发读写的,先获取锁,再进行写数据,while是获取锁失败后进行的多次尝试,应该类似于go协程里面并发控制的自旋锁
2年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!