Redis 脏数据

Guest

1、ThinkPHP 6
2、Workerman version:3.5.31
3、GatewayWorker
4、PHP version:7.4.9

private function start()
{
    $this->startRegister();
    $this->startGateWay();
    $this->startBusinessWorker();
    $this->startTimerWorker();
    Worker::runAll();
}

private function startTimerWorker()
{
    $Task = new Worker();

    $Task->count = 1;

    $Task->onWorkerStart = function($task)
    {
        Timer::add(10, function()
    {
    (new TimerModel)->scanTimeout();
    });

    Timer::add(10, function()
    {
        (new TimerModel)->ExportHistory();
    });
};
}

Register 与 GateWay 与 BusinessWorker REDIS工作正常,但是我单独创建 TimerWorker 用来轮询处理一些任务的进程,REDIS会获取到脏数据。

有时候还会出现连接REDIS的异常:
RedisException: read error on connection to 127.0.0.1:6379 in /ThinkPHP6/vendor/topthink/framework/src/think/cache/Driver.php:345

2791 2 0
2个回答

walkor 打赏

不要在Worker::runAll();运行前连redis,Worker::runAll();运行前执行的代码都是运行在主进程,主进程初始化redis后会被子进程共享,导致数据错乱。连接redis的操作放到onWorkerStart里,这样可以让每个子进程都有属于自己的redis连接,互相不影响。

  • Guest 2020-09-09

    大佬,是否还存在其他可能?因为我的REDIS都是在onWorkerStart之后创建的。

  • Guest 2020-09-10

    已经解决了,谢谢大佬。问题出在ThinkPHP6 初始化的时候会实例化Think/Log对象,Think/Log对象实例化的时候会根据缓存是Redis,而去实例化Redis,执行完这些底层初始化代码,才跑去走应用代码。

Guest

我使用的ThinkPHP6 console commands创建的应用

我确信在

$this->startRegister();
$this->startGateWay();
$this->startBusinessWorker();

里,REDIS 都是在onWorkerStart里或者之后创建的。

我单独创建的 TimerWorker Worker 业务代码里的REDIS也是在 onWorkerStart 里执行的。

我搜索了好久,答案都是描述不能在onWorkerStart前创建连接资源,可是我检查过并没有这样的代码。

是否THINKPHP6的底层,在console 应用 初始化前就连接了缓存了呢?

年代过于久远,无法发表回答
×
🔝