欧美一级特黄大片做受成人-亚洲成人一区二区电影-激情熟女一区二区三区-日韩专区欧美专区国产专区

如何優(yōu)化PHP和Laravel以提高Web應(yīng)用的性能

這篇文章主要講解了“如何優(yōu)化PHP和Laravel以提高Web應(yīng)用的性能”,文中的講解內(nèi)容簡單清晰,易于學(xué)習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習“如何優(yōu)化PHP和Laravel以提高Web應(yīng)用的性能”吧!

我們提供的服務(wù)有:網(wǎng)站制作、成都網(wǎng)站設(shè)計、微信公眾號開發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認證、西陵ssl等。為1000多家企事業(yè)單位解決了網(wǎng)站和推廣的問題。提供周到的售前咨詢和貼心的售后服務(wù),是有科學(xué)管理、有技術(shù)的西陵網(wǎng)站制作公司

四種類型的優(yōu)化

在我看來,優(yōu)化可以在四個不同的層面上進行(當涉及到PHP應(yīng)用時,就是):

  • 語言層面:這意味著你使用更快的語言版本,并避免語言中特定的功能/編碼風格,使你的代碼速度變慢。

  • 框架層面:這些是我們在本文中要涉及的內(nèi)容。

  • 基礎(chǔ)設(shè)施層面:調(diào)整你的 PHP 進程管理器、Web 服務(wù)器、數(shù)據(jù)庫等。

  • 硬件層面:轉(zhuǎn)向更好、更快、更強大的硬件主機提供商。

所有這些類型的優(yōu)化都有其存在的意義(例如,php-fpm 的優(yōu)化是非常關(guān)鍵和強大的)。但本文的重點是純粹的第 2 類優(yōu)化:那些與框架相關(guān)的優(yōu)化。

要注意 n+1 數(shù)據(jù)庫查詢

n+1 查詢問題是使用 ORM 時常見的問題。Laravel 有其強大的 ORM,叫 Eloquent,它是如此的漂亮,如此的方便,以至于我們常常忘記了看是怎么回事。

考慮一個非常常見的場景:顯示指定客戶列表下的所有訂單。這在電子商務(wù)系統(tǒng)和任何需要顯示與某些實體相關(guān)的所有實體的列表中非常常見,

我們可以想象有這樣一個控制器:

class OrdersController extends Controller
{
    // ...

    public function getAllByCustomers(Request $request, array $ids) {
        $customers = Customer::findMany($ids);
        $orders = collect(); // new collection

        foreach ($customers as $customer) {
            $orders = $orders->merge($customer->orders);
        }

        return view('admin.reports.orders', ['orders' => $orders]);
    }
}

太好了!更重要的是,優(yōu)雅,美麗。??

不幸的是,用 Laravel 編寫這樣的代碼是一種災(zāi)難性的方法。

原因如下。

當我們使用 ORM 查找給定的客戶實體時,會生成這樣一個SQL查詢語句:

SELECT * FROM customers WHERE id IN (22, 45, 34, . . .);

這與預(yù)期的完全一致。結(jié)果,所有返回的行都被存儲在控制器函數(shù)中的集合 $customers 中。

現(xiàn)在我們逐一循環(huán)處理每個客戶,并獲取他們的訂單。這將執(zhí)行下面的查詢……

SELECT * FROM orders WHERE customer_id = 22;

……有多少客戶就有多少次。

換句話說,如果我們需要獲取 1000 個客戶的訂單數(shù)據(jù),那么執(zhí)行的數(shù)據(jù)庫查詢總數(shù)將是1(用于獲取所有客戶的數(shù)據(jù))+1000(用于獲取每個客戶的訂單數(shù)據(jù))=1001。這就是 n+1 這個名字的由來。

我們可以做得更好嗎? 當然可以! 通過使用預(yù)加載,我們可以強制 ORM 執(zhí)行 JOIN,并在一次查詢中返回所有需要的數(shù)據(jù)! 就像這樣:

$orders = Customer::findMany($ids)->with('orders')->get();

由此產(chǎn)生的數(shù)據(jù)結(jié)構(gòu)是一個嵌套結(jié)構(gòu),當然,但訂單數(shù)據(jù)可以很容易地提取出來。在這種情況下,產(chǎn)生的單個查詢是這樣的。

SELECT * FROM customers INNER JOIN orders ON customers.id = orders.customer_id WHERE customers.id IN (22, 45, ...);

當然,一次查詢比多查詢一千次要好。想象一下,如果有一萬個客戶要處理,會發(fā)生什么情況!或者說,如果我們還想顯示每個訂單中包含的項目,那簡直就是天方夜譚!記住,這個技術(shù)的名字叫預(yù)加載,它幾乎在任何時候都能派上用場。

緩存配置!

Laravel 的靈活性的原因之一是它有大量的配置文件, 這些文件是框架的一部分。想要改變圖片的存儲方式/位置?

好吧,只要修改 config/filesystems.php 文件就可以了(至少寫到這里)。想要使用多個隊列驅(qū)動?可以在 config/queue.php 中隨意描述。我剛剛統(tǒng)計了一下,發(fā)現(xiàn)針對框架的不同方面有 13 個配置文件,保證你無論想改什么都不會失望。鑒于 PHP 的特性,每當一個新的 Web 請求進來,Laravel 就會被喚醒, 啟動所有的東西, 并解析所有的配置文件來找出這次該如何做不同的事情。 如果這幾天什么都沒變,那就太傻了!每次請求都要重建配置文件是一種浪費,這是可以 (實際上,必須) 避免的,解決的辦法是 Laravel 提供的一個簡單的命令:

php artisan config:cache

這樣做的目的是把所有可用的配置文件合并成一個文件,并緩存在某個地方以便快速檢索。 下一次有 Web 請求的時候,Laravel 會簡單地讀取這個單一的文件并開始工作。

也就是說,配置緩存是一個極其微妙的操作,可能會在你的面前炸開。最大的陷阱是一旦你發(fā)出這個命令,除了配置文件之外,其他地方的 env() 函數(shù)調(diào)用都會返回 null!

仔細想想確實有道理。如果你使用配置緩存,你就是在告訴框架:「你知道嗎,我覺得我已經(jīng)把東西設(shè)置得很好了,我 100% 確定我不希望它們改變?!?換句話說,你希望環(huán)境保持靜態(tài),這就是 .env 文件的作用。

說到這里,這里有一些鐵定的、神圣的、不可違背的配置緩存規(guī)則:

  • 只在生產(chǎn)系統(tǒng)上做。

  • 只有在你非常非常確定要凍結(jié)配置的情況下才做。

  • 萬一出了問題,用 php artisan cache:clear 撤銷設(shè)置。

  • 祈禱對企業(yè)造成的損失不是很大!

減少自動加載的服務(wù)

為了幫助大家, Laravel在喚醒時加載了大量的服務(wù), 這些服務(wù)在 config/app.php 文件中作為 'providers' 數(shù)組鍵的一部分。讓我們來看看我的情況:

/*
    |--------------------------------------------------------------------------
    | Autoloaded Service Providers
    |--------------------------------------------------------------------------
    |
    | The service providers listed here will be automatically loaded on the
    | request to your application. Feel free to add your own services to
    | this array to grant expanded functionality to your applications.
    |
    */

    'providers' => [

        /*
         * Laravel Framework Service Providers...
         */
        Illuminate\Auth\AuthServiceProvider::class,
        Illuminate\Broadcasting\BroadcastServiceProvider::class,
        Illuminate\Bus\BusServiceProvider::class,
        Illuminate\Cache\CacheServiceProvider::class,
        Illuminate\Foundation\Providers\ConsoleSupportServiceProvider::class,
        Illuminate\Cookie\CookieServiceProvider::class,
        Illuminate\Database\DatabaseServiceProvider::class,
        Illuminate\Encryption\EncryptionServiceProvider::class,
        Illuminate\Filesystem\FilesystemServiceProvider::class,
        Illuminate\Foundation\Providers\FoundationServiceProvider::class,
        Illuminate\Hashing\HashServiceProvider::class,
        Illuminate\Mail\MailServiceProvider::class,
        Illuminate\Notifications\NotificationServiceProvider::class,
        Illuminate\Pagination\PaginationServiceProvider::class,
        Illuminate\Pipeline\PipelineServiceProvider::class,
        Illuminate\Queue\QueueServiceProvider::class,
        Illuminate\redis\RedisServiceProvider::class,
        Illuminate\Auth\Passwords\PasswordResetServiceProvider::class,
        Illuminate\Session\SessionServiceProvider::class,
        Illuminate\Translation\TranslationServiceProvider::class,
        Illuminate\Validation\ValidationServiceProvider::class,
        Illuminate\View\ViewServiceProvider::class,

        /*
         * Package Service Providers...
         */

        /*
         * Application Service Providers...
         */
        App\Providers\AppServiceProvider::class,
        App\Providers\AuthServiceProvider::class,
        // App\Providers\BroadcastServiceProvider::class,
        App\Providers\EventServiceProvider::class,
        App\Providers\RouteServiceProvider::class,

    ],

我再一次數(shù)了數(shù),一共列出了 27 項服務(wù)! 現(xiàn)在,你可能需要所有的服務(wù),但不太可能。

例如,我現(xiàn)在正好在構(gòu)建一個 REST API,這意味著我不需要 Session Service Provider、View Service Provider 等。而且由于我是按照自己的方式來做一些事情,而不是按照框架的默認值來做,所以我也可以禁用 Auth Service Provider、Pagination Service Provider、Translation Service Provider 等??偠灾?,對于我的用例來說,這些幾乎有一半是不必要的。

仔細審視一下你的應(yīng)用吧。它是否需要所有這些服務(wù)提供者?但是看在上帝的份上,請不要盲目地注釋掉這些服務(wù),然后推送到生產(chǎn)中去! 運行所有的測試,在開發(fā)機和暫存機上手動檢查,并且在扣動扳機之前要非常非常偏執(zhí)。

明智地使用中間件堆棧。

當你需要對傳入的 Web 請求進行一些自定義處理時,創(chuàng)建一個新的中間件就是答案?,F(xiàn)在,打開 app/Http/Kernel.php 并將中間件粘在 webapi 堆棧中是很有誘惑力的;這樣一來,它就會在整個應(yīng)用程序中變得可用,而且如果它沒有做一些侵入性的事情(例如,像日志或通知)。

然而,隨著應(yīng)用程序的增長,如果所有(或大多數(shù))這些全局中間件都存在于每個請求中,那么這個全局中間件的集合可能會成為應(yīng)用程序的一個無聲負擔,即使沒有業(yè)務(wù)原因。

換句話說,要小心你在哪里添加/應(yīng)用新的中間件。在全局范圍內(nèi)添加一些東西可能會更方便,但從長遠來看,性能懲罰是非常高的。我知道如果每次有新的變化都要有選擇地應(yīng)用中間件,你要承受的痛苦,但這是我心甘情愿承受的痛苦,也是我所推薦的!

避免使用 ORM (有時)

雖然 Eloquent 讓 DB 交互的很多方面變得愉悅,但它是以速度為代價的。作為一個映射器,ORM 不僅要從數(shù)據(jù)庫中獲取記錄,還要實例化模型對象,并用列數(shù)據(jù)對其進行填充。

所以,如果你做一個簡單的 $users = User::all(),比如有10000個用戶,框架會從數(shù)據(jù)庫中獲取 10000 行記錄,并在內(nèi)部做 10000 個 new User(),并用相關(guān)數(shù)據(jù)填充他們的屬性。這是大量的工作在幕后進行,如果數(shù)據(jù)庫是你的應(yīng)用成為瓶頸的地方,繞過 ORM 有時是個好主意。

這對于復(fù)雜的 SQL 查詢來說尤其如此,在這種情況下,你必須跳很多的圈子,寫一個又一個的閉包,但最終還是能得到一個高效的查詢。在這種情況下,最好做一個 DB::raw(),然后手工寫查詢。

根據(jù) 這個 的性能研究, 即使是簡單的插入, Eloquent 也會隨著記錄數(shù)量的增加而變慢

盡量使用緩存

Web 應(yīng)用優(yōu)化中最保守的秘密之一就是緩存。

對于新手來說,緩存的意思是預(yù)先計算和存儲昂貴的結(jié)果(昂貴的 CPU 和內(nèi)存使用量),并在重復(fù)相同的查詢時簡單地返回。

例如,在一個電商商店里,可能會遇到,在 200 萬種產(chǎn)品中,大多數(shù)時候人們都會對那些新鮮出爐的、在一定價格范圍內(nèi)的、針對特定年齡段的產(chǎn)品感興趣。在數(shù)據(jù)庫中查詢這些信息是很浪費的——因為查詢的內(nèi)容不會經(jīng)常變化,所以最好把這些結(jié)果存儲在我們可以快速訪問的地方。

Laravel 內(nèi)置支持多種類型的緩存。除了使用緩存驅(qū)動和從底層構(gòu)建緩存系統(tǒng)外,你可能還想使用一些Laravel 包,方便模型緩存、查詢緩存等。

但是請注意, 在一定的簡化用例之外, 預(yù)制的緩存包可能會帶來更多的問題, 而不是解決這些問題.

優(yōu)先選擇內(nèi)存緩存

當你在 Laravel 中緩存一些東西時, 你有幾個選項可以選擇將需要緩存的計算結(jié)果存儲在哪里。這些選項也被稱為 緩存驅(qū)動。所以, 雖然使用文件系統(tǒng)來存儲緩存結(jié)果是可能的,也是完全合理的,但這并不是緩存的真正目的。

理想情況下,你希望使用內(nèi)存中(完全活在 RAM 中)的緩存,比如 Redis、Memcached、MongoDB 等,這樣在較高的負載下,緩存就能起到至關(guān)重要的作用,而不是自己成為瓶頸。

現(xiàn)在,你可能會認為擁有 SSD 磁盤和使用 RAM 棒幾乎是一樣的,但還差得遠。即使是非正式的 基準測試也顯示,在速度方面,RAM優(yōu)于SSD的10-20倍。

在緩存方面,我最喜歡的系統(tǒng)是 Redis。它的速度 快得離譜(每秒 10 萬次讀取操作是很常見的),對于非常大的緩存系統(tǒng),可以很容易地演變成一個 集群。

緩存路由

就像應(yīng)用程序的配置一樣,路由不會隨著時間的推移而改變,是緩存的理想選擇。如果你像我一樣無法忍受大文件,并且最終把你的 web.phpapi.php 分割成幾個文件的話,這一點尤其適用。 一個簡單的Laravel命令就可以把所有可用的路由打包并保存起來, 方便以后的訪問:

php artisan route:cache

而當你最終要增加或改變路由時,只需這樣做即可。

php artisan route:clear

圖像優(yōu)化和 cdn

圖片是大多數(shù)網(wǎng)絡(luò)應(yīng)用的核心和靈魂。巧合的是,它們也是最大的帶寬消耗者,也是導(dǎo)致應(yīng)用程序/網(wǎng)站速度慢的最大原因之一。如果你只是簡單地將上傳的圖片天真地存儲在服務(wù)器上,然后以 HTTP 響應(yīng)的方式發(fā)送回來,你就會讓一個巨大的優(yōu)化機會溜走。

我的第一個建議是不要在本地存儲圖片——有數(shù)據(jù)丟失的問題要處理,而且取決于你的客戶在哪個地理區(qū)域,數(shù)據(jù)傳輸可能會非常緩慢。

相反,選擇像 Cloudinary 這樣的解決方案,它可以自動動態(tài)調(diào)整和優(yōu)化圖像的大小。

如果這不可能,使用類似 Cloudflare 的東西來緩存和服務(wù)圖像,同時它們存儲在你的服務(wù)器上。

如果連這一點都做不到,調(diào)整一下你的網(wǎng)絡(luò)服務(wù)器軟件,壓縮資產(chǎn)并引導(dǎo)訪問者的瀏覽器去緩存東西,就會有很大的不同。下面是一個 Nginx 配置的片段。

server {

   # file truncated

    # gzip compression settings
    gzip on;
    gzip_comp_level 5;
    gzip_min_length 256;
    gzip_proxied any;
    gzip_vary on;

   # browser cache control
   location ~* \.(ico|css|js|gif|jpeg|jpg|png|woff|ttf|otf|svg|woff2|eot)$ {
         expires 1d;
         access_log off;
         add_header Pragma public;
         add_header Cache-Control "public, max-age=86400";
    }
}

我知道圖片優(yōu)化與 Laravel 無關(guān), 但這是一個如此簡單而強大的技巧 (而且經(jīng)常被忽視), 所以我忍不住了。

自動加載器優(yōu)化

自動加載是 PHP 中一個整潔的、并不古老的功能,它可以說是拯救了這門語言的末日。盡管如此,通過破譯給定的命名空間字符串來尋找和加載相關(guān)類的過程是需要時間的,在生產(chǎn)部署中,如果需要高性能,可以避免這個過程。 再一次,Laravel 有一個單一命令的解決方案來解決這個問題:

composer install --optimize-autoloader --no-dev

與隊列交朋友

隊列 是指當有很多事情時,你如何處理這些事情,而且每件事情都需要幾毫秒才能完成。一個很好的例子是發(fā)送電子郵件——在網(wǎng)絡(luò)應(yīng)用中,一個廣泛的用例是當用戶執(zhí)行一些操作時,發(fā)出幾封通知郵件。

例如,在一個新推出的產(chǎn)品中,你可能希望每當有人下單超過一定值時,公司領(lǐng)導(dǎo)層(大約6-7個電子郵件地址)就會收到通知。假設(shè)你的郵件網(wǎng)關(guān)能在500ms內(nèi)響應(yīng)你的SMTP請求,那么在訂單確認啟動之前,用戶需要等待3-4秒。一個非常糟糕的用戶體驗,我相信你會同意。

補救的辦法是在任務(wù)進來的時候就把它們存儲起來,告訴用戶一切都很順利,然后再處理它們(幾秒鐘)。如果出現(xiàn)錯誤,在宣布失敗之前,排隊的任務(wù)可以重試幾次。

雖然隊列系統(tǒng)使設(shè)置復(fù)雜化了一些 (并增加了一些監(jiān)控開銷), 但它在現(xiàn)代Web應(yīng)用中是不可缺少的。

資源優(yōu)化 (Laravel Mix)

對于你的 Laravel 應(yīng)用中的任何前端資源,請確保有一個管道可以編譯和最小化所有的資源文件。 那些對 Webpack,Gulp,Parcel 等打包器系統(tǒng)很熟悉的人不需要費心,但如果你還沒有這樣做,Laravel Mix是一個可靠的推薦。

Mix 是一個輕量級的 (老實說,很討人喜歡!) 圍繞Webpack的打包器,它可以處理你所有的 CSS,SASS,JS 等文件。 一個典型的 .mix.js 文件可以像這樣小,但仍然可以發(fā)揮出巨大的作用。

const mix = require('laravel-mix').mix.js('resources/js/app.js', 'public/js');

mix.js('resources/js/app.js', 'public/js')
    .sass('resources/sass/app.scss', 'public/css');

當您準備部署生產(chǎn)環(huán)境并運行 npm run production 時,它將自動處理導(dǎo)入,最小化,優(yōu)化以及整個工作流程。 Mix 不僅關(guān)心傳統(tǒng)的 JS和 CSS 文件,而且還關(guān)心您在應(yīng)用程序工作流程中可能使用的 Vue 和 React 組件。

感謝各位的閱讀,以上就是“如何優(yōu)化PHP和Laravel以提高Web應(yīng)用的性能”的內(nèi)容了,經(jīng)過本文的學(xué)習后,相信大家對如何優(yōu)化PHP和Laravel以提高Web應(yīng)用的性能這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識點的文章,歡迎關(guān)注!

文章名稱:如何優(yōu)化PHP和Laravel以提高Web應(yīng)用的性能
本文網(wǎng)址:http://aaarwkj.com/article4/pccioe.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供ChatGPT、網(wǎng)站策劃網(wǎng)站維護、Google、網(wǎng)頁設(shè)計公司、微信公眾號

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

商城網(wǎng)站建設(shè)
人妻少妇被猛烈进入中出视频| 粉嫩一区二区三区在线| 日韩精品欧美视频久久| 女人的天堂亚洲的天堂欧美 | 日本午夜福利免费在线播放| 欧美一区二区三区精美| 五月婷婷亚洲激情综合网| 欧美另类亚洲综合久青草| 国产成人免费视频一区| 一区二区日韩视频九一蜜桃| 亚洲av优选在线观看精品| 精品国产一区二区三区卡| 色哟哟网站在线精品视频| 三级av电影中文字幕| 日本亚洲精品一区二区三| 成人性生交免大片免费| 中国女人内射91熟女| 久久亚洲综合色一区二区三区| 亚洲国产中日韩精品综合| 四虎永久播放地址免费| 亚洲av毛片一区二区三区网| av中文字幕一区二区三区| 日韩二区三区精品视频| 国产黄色免费精品网站| 国产一区二区三区区别| 欧美午夜视频一区二区福利| 日日添夜夜躁欧美一区二区| 亚洲精品在线观看av| 国产成人精品亚洲av无人区| 欧美日韩精品视频在线| 丝袜美腿一区二区三区| 一区二区三区乱码国产在线| 日韩欧美国产精品一区二区| 婷婷中文字幕在线不卡视频| 超碰欧美性欧美最猛性| 高清欧美一区二区三区日本| 午夜日韩综合激情视频在线观看 | 日韩精品在线观看你懂的| 精品日韩av一区二区三区| 熟妇高潮一区二区三区| 国产91九色蝌蚪在线观看|