使用silber / bouncer-rc5从laravel 5.7更新到laravel 5.8后检查权限时,显着增加时间

问题描述 投票:2回答:2

我正在使用bouncer来满足我的ACL需求,自从我的项目从laravel 5.7升级到5.8后,我注意到我的请求处理所需的时间显着增加。

我正在处理两个模型(让我们称之为ParentChild),以及经过身份验证的用户对它们的权限。

// Takes about 110ms. Eager loads various nested relationships and counters with specific constraints
$parents = Parent::myScope(...)->get();

// Bottleneck. Takes 5 minutes (!). Used to take about 40 seconds on laravel 5.7
$parents->each(function ($parent) {
    $parent->permissions = [
        'edit' => auth()->user()->can('edit', $parent),
        'delete' => auth()->user()->can('delete', $parent),
        'restore' => auth()->user()->can('restore', $parent)
    ];
    $parent->children()->each(function ($child) {
        $child->permissions = [
            'edit' => auth()->user()->can('edit', $child),
            'delete' => auth()->user()->can('delete', $child),
            'restore' => auth()->user()->can('restore', $child)
        ];
    }
}

我正在附加这样的权限,因为$parents变量将作为json发送到前端。我很确定这个实现是错误的,并且必须有一个更好的选择,但真正的问题是加载时间的这个莫名的五倍增加。

时间是使用Debugbar措施获得的。

monitor中使用redis-cli命令(我使用Redis来缓存权限),我注意到GET请求比以前更慢。事实上,即使我停止加载页面(ESC),对Redis的GET请求也不会立即停止。我不确定这是否是正常行为。

我试图检查保镖回购中的问题,但我没有找到任何东西。

laravel acl laravel-5.7 laravel-5.8
2个回答
1
投票

你正在呼叫auth()->user()数百次。你可以尝试只调用一次吗?

$user = auth()->user();

$parents->each(function ($parent) use ($user) {
    $parent->permissions = [
        'edit' => $user->can('edit', $parent),
        'delete' => $user->can('delete', $parent),
        'restore' => $user->can('restore', $parent)
    ];

    $parent->children()->each(function ($child) {
        $child->permissions = [
            'edit' => $user->can('edit', $child),
            'delete' => $user->can('delete', $child),
            'restore' => $user->can('restore', $child)
        ];
    }
}

此外,由于你急于加载children,你不应该在每次循环迭代中再次获取它们:

$parent->children()->each(function ($child) {
//               ^^ remove these parentheses
    $child->permissions = [
        'edit' => $user->can('edit', $child),
        'delete' => $user->can('delete', $child),
        'restore' => $user->can('restore', $child)
    ];
}

0
投票

经过一些测试后,找到了解决方案。事实证明,代码完全没有问题。

服务器出了点问题。我们不知道究竟是什么,但尝试在新安装的机器上运行项目摆脱了那些可怕的处理时间。 (现在第一次请求时间是15秒)

从laravel 5.7迁移到5.8之后,服务器的问题变得更加巧妙,这让我陷入了疯狂的追逐。

附录

罪魁祸首是Xdebug。我们使用它来获得代码覆盖率分析,但性能非常差,我们最终切换到phpdbg。

© www.soinside.com 2019 - 2024. All rights reserved.