laravel 在json文件中保存用户活动

mitkmikd  于 2023-01-27  发布在  其他
关注(0)|答案(1)|浏览(117)

我试图将用户活动保存在一个json文件中,但当文件大小变大,多个用户同时工作时,json文件会删除旧记录。
这是我的特质

trait CustomLogActivity
{
    protected static function bootCustomLogActivity()
    {
        foreach (static::getModelEvents() as $event) {
            static::$event(function ($model) use ($event) {
                $model->recordActivity($event);
            });
        }
    }
    protected static function getModelEvents()
    {
        return ['created', 'updated', 'deleted'];
    }

    protected function recordActivity($event)
    {
        $activity = [
            'user_id' => Auth::id(),
            'type' => $event,
            'subject' => (new \ReflectionClass($this))->getShortName(),
            'timestamp' => now()
        ];

        if ($event === 'updated') {
            $activity['old_properties'] = $this->getOriginal();
            $activity['new_properties'] = $this->getAttributes();
        } else {
            $activity['properties'] = $this->getAttributes();
        }
        $this->appendToLog($activity);
    }

    protected function appendToLog($activity)
    {
        $logFile = 'activity.json';
        $log = json_encode($activity);
        Storage::append($logFile, $log);
    }

    protected function getActivityType($event)
    {
        $type = strtolower((new \ReflectionClass($this))->getShortName());

        return "{$event}_{$type}";
    }
}
u3r8eeie

u3r8eeie1#

正如我在一些评论中提到的,我会把它作为一个答案发布,所以它是解释任何人有这些类型的问题:
您遇到的错误称为:concurrency.
我假设2个进程同时使用该文件,因此两者都读取当前内容,但其中一个在写入后,另一个进程在内存中已经有数据(因此该进程无法获取新数据),但没有新内容,因此它将覆盖该文件...
首先,使用一个队列(事件)发送数据,然后使用Redis,或者数据库或者其他对此超级快的东西,但不是字面上的文件,你可以瞬间丢失它,但不是数据库...
您仍然可以使用文件,但我不建议这样做,因为它在很大程度上取决于您的基础设施:

  • 如果您的负载平衡器有10台机器,您是否会有10个不同的文件(每台机器一个)?
  • 你怎么把它们结合起来?

所以我所要做的就是有一个队列(通过使用事件触发),让这个队列用一个工作者来处理这个超级特定的任务。但是你必须考虑到速度,如果你在队列中得到的事件比一个工作者所能解决的要多,你必须找到一个解决方案

相关问题