摘要:大家都知道項目寫起來是挺爽,但是在生產環境性能不高,我們來抽絲剝繭分析我自己項目的運行時間消耗耗時步驟耗時觀察初步結論在調用和的方法時,消耗時間是大頭。類是用于注冊服務提供者的。但此優化在下無效。我們進一步分析。
大家都知道 laravel 項目寫起來是挺爽,但是在生產環境性能不高,我們來抽絲剝繭分析我自己項目的運行時間消耗:
Bootstrap 耗時步驟 | 耗時 |
---|---|
IlluminateFoundationBootstrapLoadEnvironmentVariables | 0.3058910369873 |
IlluminateFoundationBootstrapLoadConfiguration | 3.6571025848389 |
IlluminateFoundationBootstrapHandleExceptions | 0.78296661376953 |
IlluminateFoundationBootstrapRegisterFacades | 9.0579986572266 |
IlluminateFoundationBootstrapRegisterProviders | 101.02701187134 |
IlluminateFoundationBootstrapBootProviders | 96.982002258301 |
觀察初步結論: laravel 在調用 IlluminateFoundationBootstrapRegisterProviders 和 IlluminateFoundationBootstrapBootProviders 的 bootstrap 方法時,消耗時間是大頭。
類 IlluminateFoundationBootstrapRegisterProviders 是用于注冊服務提供者的。
類 IlluminateFoundationBootstrapBootProviders 是用于啟動服務提供者的。
laravel 的內置server php artisan serve 自帶了優化機制,上面數據僅體現首次加載的耗時。二次加載時會相比少很多。但此優化在 fpm 下無效。
我們進一步分析。
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
服務提供者 | 啟動時間 | 請求時 |
---|---|---|
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 的路由,確實是比較慢的。
[未完]
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/30879.html
摘要:模擬登錄新浪微博的核心,也是與模擬登錄最大的不同,密碼加密。已經實現模擬新浪微博登錄的功能,之后不再更新。 參考資料: http://www.csuldw.com/2016/11/10/2016-11-10-simulate-sina-login/ http://blog.csdn.net/fly_leopard/article/details/51148904 http://www....
摘要:說明本文主要學習下的模型觀察者,把一點點經驗分享出來希望對別人能有幫助。模型觀察者這個功能能做很多事情,比如模型更新時發個通知。總結本篇文章主要學了下的模型觀察者,發現這個功能也能使代碼結構更清晰,覺得挺好的。 說明:本文主要學習下Laravel的Model Observer模型觀察者,把一點點經驗分享出來希望對別人能有幫助。同時,作者會將開發過程中的一些截圖和代碼黏上去,提高閱讀效率...
摘要:全書分三大部分共章第章介紹的基礎知識安裝和基本語法第章介紹的基本編程機器學習基礎及中常用的第三方庫函數,并介紹數據預處理的基本方法第章分別介紹常用的機器學習分析算法及深度學習等。每章都采用多個經典案例圖文并茂地介紹機器學習的原理和實現方法。 最近在學習Java和全棧開發,推薦一些有用的書籍 書架主要針對Java后端和全棧開發用的 書籍介紹 《Spring Boot 2.0企業級應用開發...
摘要:全書分三大部分共章第章介紹的基礎知識安裝和基本語法第章介紹的基本編程機器學習基礎及中常用的第三方庫函數,并介紹數據預處理的基本方法第章分別介紹常用的機器學習分析算法及深度學習等。每章都采用多個經典案例圖文并茂地介紹機器學習的原理和實現方法。 最近在學習Java和全棧開發,推薦一些有用的書籍 書架主要針對Java后端和全棧開發用的 書籍介紹 《Spring Boot 2.0企業級應用開發...
閱讀 1148·2021-09-22 15:43
閱讀 2345·2021-09-22 15:32
閱讀 4455·2021-09-22 15:11
閱讀 2187·2019-08-30 15:55
閱讀 2564·2019-08-30 15:54
閱讀 984·2019-08-30 15:44
閱讀 1095·2019-08-29 13:26
閱讀 794·2019-08-29 12:54