资讯专栏INFORMATION COLUMN

一次 Laravel 性能分析全程笔记

Cruise_Chan / 2684人阅读

摘要:大家都知道项目写起来是挺爽,但是在生产环境性能不高,我们来抽丝剥茧分析我自己项目的运行时间消耗耗时步骤耗时观察初步结论在调用和的方法时,消耗时间是大头。类是用于注册服务提供者的。但此优化在下无效。我们进一步分析。

大家都知道 laravel 项目写起来是挺爽,但是在生产环境性能不高,我们来抽丝剥茧分析我自己项目的运行时间消耗:

Bootstrap 耗时
步骤 耗时
IlluminateFoundationBootstrapLoadEnvironmentVariables 0.3058910369873
IlluminateFoundationBootstrapLoadConfiguration 3.6571025848389
IlluminateFoundationBootstrapHandleExceptions 0.78296661376953
IlluminateFoundationBootstrapRegisterFacades 9.0579986572266
IlluminateFoundationBootstrapRegisterProviders 101.02701187134
IlluminateFoundationBootstrapBootProviders 96.982002258301

观察初步结论: laravel 在调用 IlluminateFoundationBootstrapRegisterProvidersIlluminateFoundationBootstrapBootProvidersbootstrap 方法时,消耗时间是大头。

IlluminateFoundationBootstrapRegisterProviders 是用于注册服务提供者的。

IlluminateFoundationBootstrapBootProviders 是用于启动服务提供者的。

laravel 的内置server php artisan serve 自带了优化机制,上面数据仅体现首次加载的耗时。二次加载时会相比少很多。但此优化在 fpm 下无效。

我们进一步分析。


RegisterProviders 耗时

IlluminateFoundationBootstrapRegisterProviders::bootstrap 方法代码如下:

    /**
     * Bootstrap the given application.
     *
     * @param  IlluminateFoundationApplication  $app
     * @return void
     */
    public function bootstrap(Application $app)
    {
        $app->registerConfiguredProviders();
    }

所以我们还是回到了 IlluminateFoundationApplication 这个文件:

    /**
     * Register all of the configured providers.
     *
     * @return void
     */
    public function registerConfiguredProviders()
    {
        $providers = Collection::make($this->config["app.providers"])
                        ->partition(function ($provider) {
                            return Str::startsWith($provider, "Illuminate");
                        });

        $providers->splice(1, 0, [$this->make(PackageManifest::class)->providers()]);

        (new ProviderRepository($this, new Filesystem, $this->getCachedServicesPath()))
                    ->load($providers->collapse()->toArray());
    }

针对上面的 (new ProviderRepository)->load 进行耗时分析发现数据为

步骤 耗时
IlluminateFoundationProviderRepository::load 61.771869659424

毋庸置疑这就是消耗时间的大头。

里面的代码为

    /**
     * Register the application service providers.
     *
     * @param  array  $providers
     * @return void
     */
    public function load(array $providers)
    {
        $manifest = $this->loadManifest();

        // First we will load the service manifest, which contains information on all
        // service providers registered with the application and which services it
        // provides. This is used to know which services are "deferred" loaders.
        if ($this->shouldRecompile($manifest, $providers)) {
            $manifest = $this->compileManifest($providers);
        }

        // Next, we will register events to load the providers for each of the events
        // that it has requested. This allows the service provider to defer itself
        // while still getting automatically loaded when a certain event occurs.
        foreach ($manifest["when"] as $provider => $events) {
            $this->registerLoadEvents($provider, $events);
        }

        // We will go ahead and register all of the eagerly loaded providers with the
        // application so their services can be registered with the application as
        // a provided service. Then we will set the deferred service list on it.
        foreach ($manifest["eager"] as $provider) {
            $this->app->register($provider);
        }

        $this->app->addDeferredServices($manifest["deferred"]);
    }

而再经过定位,发现慢在这一行

        foreach ($manifest["eager"] as $provider) {
            $this->app->register($provider);
        }

又回到 IlluminateFoundationApplication

    /**
     * Register a service provider with the application.
     *
     * @param  IlluminateSupportServiceProvider|string  $provider
     * @param  array  $options
     * @param  bool   $force
     * @return IlluminateSupportServiceProvider
     */
    public function register($provider, $options = [], $force = false)
    {
        if (($registered = $this->getProvider($provider)) && ! $force) {
            return $registered;
        }

        // If the given "provider" is a string, we will resolve it, passing in the
        // application instance automatically for the developer. This is simply
        // a more convenient way of specifying your service provider classes.
        if (is_string($provider)) {
            $provider = $this->resolveProvider($provider);
        }

        if (method_exists($provider, "register")) {
            $provider->register();
        }

        // If there are bindings / singletons set as properties on the provider we
        // will spin through them and register them with the application, which
        // serves as a convenience layer while registering a lot of bindings.
        if (property_exists($provider, "bindings")) {
            foreach ($provider->bindings as $key => $value) {
                $this->bind($key, $value);
            }
        }

        if (property_exists($provider, "singletons")) {
            foreach ($provider->singletons as $key => $value) {
                $this->singleton($key, $value);
            }
        }

        $this->markAsRegistered($provider);

        // If the application has already booted, we will call this boot method on
        // the provider class so it has an opportunity to do its boot logic and
        // will be ready for any usage by this developer"s application logic.
        if ($this->booted) {
            $this->bootProvider($provider);
        }

        return $provider;
    }

在 register 方法中,根据 get_class($provider) 和 执行耗时,得出以下数据

步骤 耗时
IlluminateEventsEventServiceProvider 0.02197265625
IlluminateLogLogServiceProvider 0.005859375
IlluminateRoutingRoutingServiceProvider 0.011962890625
IlluminateAuthAuthServiceProvider 0.024169921875
IlluminateCookieCookieServiceProvider 0.0048828125
IlluminateDatabaseDatabaseServiceProvider 9.678955078125
IlluminateEncryptionEncryptionServiceProvider 0.00732421875
IlluminateFilesystemFilesystemServiceProvider 0.014892578125
IlluminateFoundationProvidersFormRequestServiceProvider 0.0009765625
IlluminateFoundationProvidersFoundationServiceProvider 0.416015625
IlluminateNotificationsNotificationServiceProvider 0.011962890625
IlluminatePaginationPaginationServiceProvider 5.04296875
IlluminateSessionSessionServiceProvider 0.072021484375
IlluminateViewViewServiceProvider 0.01318359375
CogLaravelLoveProvidersLoveServiceProvider 0.01708984375
DingoApiProviderRoutingServiceProvider 0.0146484375
DingoApiProviderHttpServiceProvider 0.03271484375
DingoApiProviderLaravelServiceProvider 20.23583984375
FideloperProxyTrustedProxyServiceProvider 0.001953125
InfyOmAdminLTETemplatesAdminLTETemplatesServiceProvider 0.001953125
InfyOmGeneratorInfyOmGeneratorServiceProvider 0.045166015625
JeroenNotenLaravelAdminLteServiceProvider 0.013671875
LaracastsFlashFlashServiceProvider 0.013916015625
LaravelfyValidatorServiceProvider 0.001953125
LshorzLuocaptchaLCaptchaServiceProvider 0.01171875
MaatwebsiteExcelExcelServiceProvider 6.778076171875
OvertrueLaravelWeChatServiceProvider 9.040771484375
PrettusRepositoryProvidersEventServiceProvider 0.00390625
PrettusRepositoryProvidersRepositoryServiceProvider 1.244140625
SpatiePermissionPermissionServiceProvider 0.3759765625
TymonJWTAuthProvidersLaravelServiceProvider 0.03515625
CollectiveHtmlHtmlServiceProvider 0.025146484375
YajraDataTablesHtmlServiceProvider 2.22314453125
YajraDataTablesButtonsServiceProvider 4.593017578125
YajraDataTablesDataTablesServiceProvider 0.333984375
AppProvidersAppServiceProvider 0.001953125
AppProvidersAuthServiceProvider 0.001953125
AppProvidersEventServiceProvider 0.001953125
AppProvidersRouteServiceProvider 0.001708984375
AppProvidersResponseMacroServicePrivoder 37.69677734375
OvertrueLaravelLangTranslationServiceProvider 0.01220703125
IlluminateValidationValidationServiceProvider 0.029052734375
IlluminateCacheCacheServiceProvider 0.01318359375
IlluminateHashingHashServiceProvider 0.031005859375

得出 RegisterProviders 瓶颈的结论

AppProvidersResponseMacroServicePrivoder 占用 37ms

DingoApiProviderLaravelServiceProvider 占用 20ms

IlluminateDatabaseDatabaseServiceProvider 占用 9ms

OvertrueLaravelWeChatServiceProvider 占用 9ms


BootProviders 耗时
服务提供者 启动时间 请求时
IlluminateDatabaseDatabaseServiceProvider::boot 0.851074875 3.6809083125
IlluminateFoundationProvidersFormRequestServiceProvider::boot 0.022949875 0.0290524375
IlluminateNotificationsNotificationServiceProvider::boot 2.113769125 9.91894525
IlluminatePaginationPaginationServiceProvider::boot 0.062988125 0.089843
EasyWeChatComposerLaravelServiceProvider::boot 6.5910643125 22.644042875
CogLaravelLoveProvidersLoveServiceProvider::boot 0.6311035625 2.3010250625
DingoApiProviderLaravelServiceProvider::boot 9.228027375 53.9980465
FideloperProxyTrustedProxyServiceProvider::boot 0.1589356875 0.6091309375
InfyOmAdminLTETemplatesAdminLTETemplatesServiceProvider::boot 0.033691625 0.0410155
PrettusRepositoryProvidersEventServiceProvider::boot 0.020996375 0.0432120625
PrettusRepositoryProvidersRepositoryServiceProvider::boot 1.7600095625 8.361816625
LaracastsFlashFlashServiceProvider::boot 0.191894125 0.066894125
InfyOmGeneratorInfyOmGeneratorServiceProvider::boot 0.0832513125 0.019042875
JeroenNotenLaravelAdminLteServiceProvider::boot 3.2441405 17.807128625
LaravelfyValidatorServiceProvider::boot 2.940917875 10.8391118125
LshorzLuocaptchaLCaptchaServiceProvider::boot 0.0832513125 0.075683375
OvertrueLaravelWeChatServiceProvider::boot 0.074707125 0.0139165625
SpatiePermissionPermissionServiceProvider::boot 9.5026856875 15.3239749375
TymonJWTAuthProvidersLaravelServiceProvider::boot 1.070800125 11.508300125
YajraDataTablesDataTablesServiceProvider::boot 0.2839356875 1.0837404375
YajraDataTablesHtmlServiceProvider::boot 0.0827631875 0.0651856875
MaatwebsiteExcelExcelServiceProvider::boot 0.0461428125 0.0097655
YajraDataTablesButtonsServiceProvider::boot 0.0529785625 0.046875
AppProvidersAppServiceProvider::boot 0.1179191875 0.0979000625
AppProvidersAuthServiceProvider::boot 0.1901856875 0.437988125
AppProvidersEventServiceProvider::boot 0.196777375 0.8210441875
AppProvidersRouteServiceProvider::boot 4.6032714375 12.817871375
AppProvidersResponseMacroServicePrivoder::boot 5.6691893125 16.917968
LaravelTinkerTinkerServiceProvider::boot 0.3859868125 null
BarryvdhLaravelIdeHelperIdeHelperServiceProvider::boot 0.1750488125 null
原因分析

EasyWeChatComposerLaravelServiceProvider::boot 的启动速度,略慢,分析原因: 代码 Github boot 方法中,加载了路由。而 Laravel 的路由,确实是比较慢的。

[未完]

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/30879.html

相关文章

  • PHP基于laravel框架获取微博数据之一 模拟新浪微博登录

    摘要:模拟登录新浪微博的核心,也是与模拟登录最大的不同,密码加密。已经实现模拟新浪微博登录的功能,之后不再更新。 参考资料: http://www.csuldw.com/2016/11/10/2016-11-10-simulate-sina-login/ http://blog.csdn.net/fly_leopard/article/details/51148904 http://www....

    galois 评论0 收藏0
  • Laravel学习笔记之Model Observer模型观察者

    摘要:说明本文主要学习下的模型观察者,把一点点经验分享出来希望对别人能有帮助。模型观察者这个功能能做很多事情,比如模型更新时发个通知。总结本篇文章主要学了下的模型观察者,发现这个功能也能使代码结构更清晰,觉得挺好的。 说明:本文主要学习下Laravel的Model Observer模型观察者,把一点点经验分享出来希望对别人能有帮助。同时,作者会将开发过程中的一些截图和代码黏上去,提高阅读效率...

    Crazy_Coder 评论0 收藏0
  • Java后端学习,你应该看那些书籍?

    摘要:全书分三大部分共章第章介绍的基础知识安装和基本语法第章介绍的基本编程机器学习基础及中常用的第三方库函数,并介绍数据预处理的基本方法第章分别介绍常用的机器学习分析算法及深度学习等。每章都采用多个经典案例图文并茂地介绍机器学习的原理和实现方法。 最近在学习Java和全栈开发,推荐一些有用的书籍 书架主要针对Java后端和全栈开发用的 书籍介绍 《Spring Boot 2.0企业级应用开发...

    QiuyueZhong 评论0 收藏0
  • Java后端学习,你应该看那些书籍?

    摘要:全书分三大部分共章第章介绍的基础知识安装和基本语法第章介绍的基本编程机器学习基础及中常用的第三方库函数,并介绍数据预处理的基本方法第章分别介绍常用的机器学习分析算法及深度学习等。每章都采用多个经典案例图文并茂地介绍机器学习的原理和实现方法。 最近在学习Java和全栈开发,推荐一些有用的书籍 书架主要针对Java后端和全栈开发用的 书籍介绍 《Spring Boot 2.0企业级应用开发...

    FreeZinG 评论0 收藏0

发表评论

0条评论

Cruise_Chan

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<