>  기사  >  백엔드 개발  >  Laravel 권한 프로젝트의 성능 최적화

Laravel 권한 프로젝트의 성능 최적화

不言
不言원래의
2018-07-06 17:22:562321검색

이 기사는 주로 참조 가치가 있는 Laravel-permission 프로젝트의 성능 최적화를 소개합니다. 이제 모든 사람과 공유합니다. 도움이 필요한 친구들은 참조할 수 있습니다.

Laravel 권한 프로젝트의 성능 최적화

최근 SWIS에서 생성된 파일을 조사하고 분석했습니다. 프로젝트 성과. 놀랍게도 성능을 가장 많이 소모하는 방법 중 하나는 우수한 spatie/laravel-permission 패키지로 인해 발생합니다. spatie/laravel-permission 包造成的。

经过查阅更多资料和研究,发现一个可能明显改善的性能问题 。既然解决方案已明确阐述,就很容易编写代码改善,提交请求。

现在这个解决方案已被合并和发布,下面是这个性能问题的分析和如何在自己的项目避免这类问题。

TL;DR: 跳转到结论部分.

性能瓶颈

如果我们抽象的看 spatie/laravel-permission 它主要做两件事:

  1. 保持一个属于某个模型的权限清单。

  2. 检查某个模型是否具有权限。

第一点说是性能瓶颈有点牵强。这里的权限数据存放在数据库中,需要的时候将会被读取出来。这个过程是有点慢但也只是执行一次。结果会被缓存下来,后续的请求可以直接使用。

第二点在性能瓶颈的观点上来看确实是一个瓶颈。 这个瓶颈取决于权限的性质和项目的大小, 因为权限会被频繁的检查。 在这个检查的过程中任何的迟钝都会成为整个项目的性能瓶颈。

过滤集合类

过滤权限集合的方法被认为是造成低性能的原因。 它做了如下事情:

$permission = $permissions
    ->where('id', $id)
    ->where('guard_name', $guardName)
    ->first();

修改后:

$permission = $permissions
    ->filter(function ($permission) use ($id, $guardName) {
        return $permission->id === $id && $permission->guard_name === $guardName;
    })
    ->first();

这两个代码段实现了同一件事情,但第二个更快。

性能测试

我正在开发的应用中大约有 150 个不同的权限。 在一个普通的请求中, 大约有 50 个权限需要用  hasPermissionTo 这个方法去检查,当然,有些页面可能需要检查大约 200 个权限。

以下是用来做性能测试的一些设置。

$users = factory(User::class, 150)->make();
$searchForTheseUsers = $users->shuffle()->take(50);

# 方法 1: where
foreach($searchForTheseUsers as $user) {
    $result = $users->where('id', '=', $user->id)->first();
}

# 方法 2: 过滤,传递一个模型作为回调
foreach($searchForTheseUsers as $searchUser) {
    $result = $users->filter(function($user) use ($searchUser) {
        return $user->id === $searchUser->id;
    })->first();
}

# 方法 3: 过滤,传递属性作为回调
foreach($searchForTheseUsers as $user) {
    $searchId = $user->id;
    $result = $users->filter(function($user) use ($searchId) {
        return $user->id === $searchId;
    })->first();
}

以上三个方法都会被用来测试过滤  1 个属性,2 个属性,3 个属性,所以,用方法 1 过滤三个属性就会是这样:

foreach($searchForTheseUsers as $user) {
    $result = $users
        ->where('id', '=', $user->id)
        ->where('firstname', '=', $user->firstname)
        ->where('lastname', '=', $user->lastname)->first();
}

结果


方法 #1 方法 #2 方法 #3
1个属性 0.190 0.139 (-27%) 0.072 (-62%)
2个属性 0.499 0.372 (-25%) 0.196 (-61%)
3个属性 0.488 0.603 (+25%) 0.198 (-59%)

结论

我们可以得出结论:对一个项目而言,重复的过滤一个大集合会引发严重性能瓶颈。

多属性的过滤明显增加计算成本。

使用 Collection::filter() 代替 Collection::where()

더 많은 정보와 연구를 검토한 결과 크게 개선될 수 있는 성능 문제를 발견했습니다. 이제 솔루션이 명확하게 명시되었으므로 코드 개선 사항을 쉽게 작성하고 풀 요청을 제출할 수 있습니다.

이제 이 솔루션이 병합되어 출시되었으므로 여기에 이 ​​성능 문제에 대한 분석과 자신의 프로젝트에서 이러한 문제를 피하는 방법이 있습니다.

TL;DR: 결론 부분으로 이동하세요.

성능 병목 현상

추상적으로 보면 spatie/laravel-permission은 주로 두 가지 작업을 수행합니다.

  1. 특정 모델에 속하는 권한 목록을 유지합니다.

  2. 모델에 권한이 있는지 확인하세요.

첫 번째 요점은 성능 병목 현상이라는 점인데, 이는 다소 무리가 있습니다. 여기에 있는 권한 데이터는 데이터베이스에 저장되며 필요할 때 읽혀집니다. 이 프로세스는 약간 느리지만 한 번만 수행됩니다. 결과는 캐시되어 후속 요청에서 직접 사용될 수 있습니다. 두 번째 요점은 실제로 성능 병목 현상의 관점에서 볼 때 병목 현상입니다. 권한은 자주 확인되므로 이 병목 현상은 권한의 성격과 프로젝트 크기에 따라 달라집니다. 이 검사 중 느린 속도는 전체 프로젝트의 성능 병목 현상이 됩니다.

컬렉션 클래스 필터링

권한 컬렉션을 필터링하는 방식이 성능 저하의 원인으로 간주됩니다. 다음 작업을 수행합니다.

성능 테스트

🎜 제가 개발 중인 앱에는 약 150가지의 다양한 권한이 있습니다. 일반적인 요청에는 hasPermissionTo 메서드를 사용하여 확인해야 하는 권한이 약 50개 있습니다. 물론 일부 페이지에서는 약 200개의 권한을 확인해야 할 수도 있습니다. 🎜🎜다음은 성능 테스트에 사용되는 몇 가지 설정입니다. 🎜rrreee🎜위의 세 가지 방법은 1개 속성, 2개 속성, 3개 속성 필터링을 테스트하는 데 사용됩니다. 따라서 세 가지 속성을 필터링하기 위해 방법 1을 사용하면 다음과 같습니다. 🎜rrreee

결과

🎜 방법 #1 방법 #2 방법 #3 속성 1개 0.190 0.139(-27%) 0.072(-62%) 속성 2개 0.499 0.372(- 25%) 0.196(-61%) 속성 3개 0.488 0.603(+25%) 0.198(-59%)

결론 h2>🎜우리는 할 수 있습니다 프로젝트의 경우 대규모 컬렉션을 반복적으로 필터링하면 심각한 성능 병목 현상이 발생할 수 있다는 결론을 내립니다. 🎜🎜다중 속성 필터링은 계산 비용을 크게 증가시킵니다. 🎜🎜Collection::where() 대신 Collection::filter()를 사용하면 성능을 60% 향상시킬 수 있습니다. 🎜🎜경고: 전체 모델을 필터 콜백에 전달하는 것은 성능 집약적이므로 개별 속성을 전달하는 것이 더 좋습니다. 🎜🎜위 내용은 이 글의 전체 내용입니다. 모든 분들의 학습에 도움이 되었으면 좋겠습니다. 더 많은 관련 내용은 PHP 중국어 홈페이지를 주목해주세요! 🎜🎜관련 권장 사항: 🎜🎜🎜Laravel 5.6에서 Swoole의 코루틴 데이터베이스 쿼리 사용🎜🎜🎜🎜🎜Laravel의 Facade 표시 시스템 분석🎜🎜🎜🎜🎜laravel+Redis는 스트레스 테스트를 통해 대기열의 높은 동시 처리를 구현합니다🎜 🎜🎜

위 내용은 Laravel 권한 프로젝트의 성능 최적화의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.