• 一次 Laravel 性能分析全程笔记


    大家都知道 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://segmentfault.com/a/1190000016411386

  • 相关阅读:
    个人理财小助手 —— 简介
    我的分页控件(未完,待续)——控件件介绍及思路
    静态变量 静态对象 静态函数和非静态函数的区别。(我的理解,大家看看对不对)
    通过“访问多种数据库”的代码来学习多态!(.net2.0版)
    Step By Step 一步一步写网站[1] —— 填加数据
    个人理财小助手 —— 数据库(一)
    几个鸟叫的声音
    Step By Step 一步一步写网站[1] —— 帧间压缩,表单控件
    面向对象相关
    论程序的成长—— 你写的代码有生命力吗?
  • 原文地址:https://www.cnblogs.com/lalalagq/p/9971337.html
Copyright © 2020-2023  润新知