Mergebot Şimdi %1,200 Daha Hızlı: Blackfire ile Laravel Uygulamasını Ayarlama
Dağıtım başına 1.000 sorgu sınırını kaldırarak Mergebot beta sürümümüzde büyük bir dönüm noktasına ulaştık 🎉. WordPress veritabanlarını birleştirmeyi kolaylaştırmak için Mergebot'u oluşturduk. Mergebot'u oluştururken, çözmeye odaklandığımız problemler o kadar karmaşıktı ki, optimizasyon hakkında düşünmek veya kodumuzu hızlı bir şekilde çalıştırmak için gerçekten fazla zaman harcamadık. Bununla birlikte, dağıtım sınırlaması başına 1.000 sorguyu kaldırabilmek için uygulamanın performansı, özellikle dağıtım oluşturma işlerimizin performansı hakkında bir şeyler yapmamız gerektiği ortaya çıktı.
Sınırı kaldırmaya yönelik çalışmamın bir parçası olarak, dağıtımların yalnızca zaman aşımları veya bellek sınırlarına çarpma nedeniyle başarısız olmayacağından emin olmam gerekiyordu. Gir, Laravel.
Muhtemelen şimdiye kadar bildiğiniz gibi, Mergebot uygulaması Laravel kullanılarak oluşturulmuştur. İş yükünün web sunucusundan boşaltılabilmesi ve ayrı olarak ölçeklenebilmesi için uzun süren herhangi bir işlemi (örneğin bir dağıtım oluşturma) işlemek için Laravel'in Kuyruk İşlerini kullanıyoruz.
PHP uygulamalarının profillenmesi söz konusu olduğunda ilk bağlantı noktam Blackfire. Blackfire'ın premium planları, kesinlikle göz atmaya değer her türlü fantezi performans izleme özelliği sunar, ancak ücretsiz planları, web sayfalarını, CLI komut dosyalarını ve duvar süresini ve bellek kullanımını ölçmenize olanak tanıyan API Çağrıları oluşturmanıza olanak tanır. Bu, PHP kodunda performans darboğazları aramanız gerektiğinde sizi harekete geçirmek için fazlasıyla yeterli.
Bu makalede, bir Laravel uygulamasının profilinin nasıl oluşturulacağına ve özellikle Blackfire kullanarak bir kuyruk işinin profilinin nasıl oluşturulacağına bakacağız. Sonuçları nasıl yorumlamamız gerektiğine bir göz atacağız ve Mergebot'un performansını nasıl %1200 oranında iyileştirmeyi başardığımı göreceğiz.
Laravel ve Blackfire
Yapmamız gereken ilk şey, Blackfire'ı Laravel uygulamamızı çalıştıran sunucuda çalıştırmak ve çalıştırmak. Bu öğreticinin amaçları doğrultusunda, bir Laravel Homestead VM kullanacağız, ancak bu talimatlar, Laravel uygulamanızı çalıştırdığınız herhangi bir sunucu için geçerli olacaktır.
Henüz yapmadıysanız, gidin ve bir Blackfire hesabı için kaydolun. Giriş yaptıktan sonra, müşteri kimlik bilgilerinizi görmeniz gereken hesap sayfasına gidin. Bu bilgilere kısa süre içinde ihtiyacınız olacak.
Laravel uygulamanızın Homestead'de (veya sunucunuzda) kurulu olduğunu varsayacağım. Homestead, Blackfire önceden yüklenmiş olarak gelerek bize biraz zaman kazandırıyor, ancak henüz Blackfire yüklemediyseniz, Blackfire belgelerindeki talimatları izleyin (aracıya, CLI aracına ve PHP araştırmasına ihtiyacımız var). kurulmalıdır).
Yerleşik bir Artisan komutunun profilini çıkararak Blackfire kurulumumuzu test edebiliriz. SSH'den Homestead'e, ardından uygulamanızın kökünden aşağıdakileri çalıştırın:
blackfire run php artisan route:list
Blackfire'ı ilk kez çalıştırıyorsanız, muhtemelen “Blackfire doğru şekilde yapılandırılmamış” ile ilgili bir hata göreceksiniz. Bu durumda, talimatları izleyerek ve Blackfire panosundaki hesap sayfasından sağlanan bilgileri kullanarak blackfire config çalıştırın. Bu yapıldıktan sonra, yukarıdaki komutu tekrar çalıştırın. Umarım, böyle bir şey görmelisiniz:

Grafik URL'sini ziyaret edersek (veya sadece Blackfire Dashboard'a gidersek), sonuçları profil listesinde görmelisiniz.
Komutları Kullanarak İşlerin Profilini Oluşturma
Ardından, meslek sınıfımızı test etmek için bir Artisan komutu oluşturacağız. Zaten test etmek istediğiniz bir iş sınıfınız varsa, kullanmaktan çekinmeyin. Aksi takdirde, test amaçlı kullanmak için kukla bir iş oluşturabiliriz. Bunu yapmak için aşağıdakileri çalıştırın:
php artisan make:job DummyJob
Şimdi Laravel app/Jobs dizininde bir DummyJob sınıfı görmelisiniz. Normalde bu işi çalıştırmak için bir kuyruk çalışanı kurmanız, işi göndermeniz ve ardından kuyruk dinleyicisi tarafından alınıp yürütülene kadar beklemeniz gerekir. Ancak, iş yürütülürken çalıştırılan kodun profilini çıkarmaya gelince bu işlem bize pek yardımcı olmayacak. Bunun yerine, özellikle işi yürütmek için bir Artisan Command oluşturmayı seviyorum, böylece onu CLI kullanarak çalıştırabiliriz. Devam edelim ve şu komutu oluşturalım:
php artisan make:command ExecuteDummyJob
Bu, app/Console/Commands dizininde bir ExecuteDummyJob sınıfı oluşturacaktır. Bu sınıfta yapmamız gereken iki değişiklik var. İlk önce, komuta uygun bir imza verin:
protected $signature = 'app:execute-dummy-job';
İkinci olarak, DummyJob sınıfımızın handle yöntemini çalıştırmamız gerekiyor (sıradaki çalışanın normalde yapacağı şey budur):
use App\Jobs\DummyJob; /** * Execute the console command. * * @return mixed */ public function handle() { $job = new DummyJob(); $job->handle(); }
Son olarak, çalıştırabilmemiz için yeni komutumuzu Kernel.php sınıfına eklemeyi unutmayın:
/** * The Artisan commands provided by your application. * * @var array */ protected $commands = [ \App\Console\Commands\ExecuteDummyJob::class, ];
Şimdi php artisan app:execute-dummy-job , temelde kuyruk dinleyicisi tarafından yürütülecek olanı kopyalarız, ancak şimdi Blackfire CLI kullanarak profilini çıkarabiliriz:
blackfire run php artisan app:execute-dummy-job
Blackfire Sonuçlarını Yorumlama
Bu bölüm için, aslında Mergebot'tan gerçek bir dünya örneğine bakacağım, ancak kendi işiniz varsa veya DummyJob yeni kurduysanız ve profile bir kod eklediyseniz, bunu şu şekilde kullanabilirsiniz: sonuçlarınızı araştırmak için temel. Eski Mergebot kodunda 60 sorgu dağıtımı çalıştırmanın sonuçları:

Bu sonuçlara atlamadan önce yapmanızı tavsiye edeceğim ilk şey, Blackfire'ın Profilleri Analiz Etme konusundaki kendi belgelerini okumaktır. Bu size Blackfire sonuç sayfasının nasıl çalıştığına dair iyi bir fikir verecektir.
Ardından, bu profil için ana sonuç ölçütlerine dikkat etmelisiniz: 22,1 MB bellek kullanılarak çalıştırılması 2 dakika 10 saniye sürdü. Bunlar azaltmaya çalıştığımız ana performans göstergeleri olacak.

Ana çağrı grafiğinde, her bir yöntemin kaç kez çağrıldığını ve “sıcak yolun” nereye gittiğini (yürütme süresinin çoğunun harcandığı yer) dahil olmak üzere kod yürütme akışını görebiliriz. Blackfire belgeleri, açık bir darboğazdan kaynaklanıp kaynaklanmadığını görmek için her zaman önce etkin yolu analiz etmenizi önerir, ancak bazen sıcak yolun tamamen haklı olduğunu ve aslında bir sorun olmadığını unutmayın.
Bu durumda, iki etkin yol fgets (önbellekten okuma) ve PDOStatement::execute (veritabanı sorgularını yürütme) yol açar.

Bu bize tek başına pek bir şey söylemiyor. Ancak, bu yöntemlerin her birinin ne sıklıkla çağrıldığına dikkat edin. Önbellekten okuma ( fgets ) 58.000'den fazla kez çağrılıyor ve tümü 60 sorgu dağıtımı için yürütülen 8.500'den fazla veritabanı sorgusu var! Performans sorunları yaşamamıza şaşmamalı. Çağrı grafiğine geri dönelim ve sorunun nereden kaynaklandığını belirleyip belirleyemeyeceğimize bakalım.

Ah, şimdi net bir performans darboğazının nerede olduğunu görebiliyoruz. idRelatesToDifferentObject yöntemi, esas olarak getFirstUpdateData ve updateValueWithPlaceholder yöntemlerinden 2790 kez çağrıldı. Bu, bu yöntemlerin muhtemelen beklenenden çok daha sık gerçekleşen bir döngü içinde idRelatesToDifferentObject çağırdığı anlamına gelir. Yeniden düzenlemeye başlayabileceğimiz bir performans darboğazının yerini bulduk.
Bu aynı işlem, kodunuzun performansından memnun kalana kadar ihtiyaç duyduğunuz sıklıkta tekrarlanabilir. Blackfire, performans iyileştirmesini görmek için profilleri karşılaştırmanıza izin veren başka bir güzel özelliğe sahiptir. Bu profili Mergebot için yazdığım yeni, yeniden yazılmış dağıtım süreci koduyla karşılaştıralım.

Dikkat edilmesi gereken ilk şey, ana zaman ve bellek ölçümlerinin performans iyileştirmesidir:

Harika Scott! Bu kod, zamanın %8'inde çalışır (bu, öncekinden %1200 daha hızlıdır) ve belleğin yarısından daha azını kullanır. Aynı 60 sorgu dağıtımı artık yalnızca 10 saniye sürüyor. Fena değil. Yeni kodun sıcak yoluna bakalım.

Sıcak yol hala aynı tür olaylara yol açar (önbellekten okuma ve veritabanı sorgularını yürütme). Ancak, bu yöntemleri eskisinden çok daha az çağırdığımıza dikkat edin. PDOStatement::execute 8700 kez çağrılmaktan 674 kez çağrıldı. Veritabanı sorgularını sınırlamak, performansı artırmanın etkili bir yoludur.
Çağrı grafiğine geri dönersek, yöntem çağrılarımıza ne olduğunu görelim.

idRelatesToDifferentObject yöntemi 2790 kez çağrılmaktan 940 kez çağrıldı. Bu kendi başına iyi bir gelişmedir, ancak aynı zamanda idRelatesToDifferentObject yöntemi içinde herhangi bir yöntemin çağrılma sayısı üzerinde zincirleme bir etkiye sahiptir. Buna karşılaştırma grafiğinde bakarsak, bunun yürütme süresi üzerindeki etkisini görebiliriz.

Uygulamanızın Performansını Geliştirme
Umarım bu noktada, Laravel kurulumunuzda Blackfire kurmayı başardınız ve kodunuzu kıyaslamak için profiller oluşturabilirsiniz. CLI'deki kuyruk işlerini test etmek için bir Artisan komutu oluşturmak için kullandığımız süreç, teorik olarak, kodunuzun profilini çıkarmak isteyebileceğiniz herhangi bir bölümünü test etmek için kullanılabilir.
Mergebot örneğinde, performans darboğazının ana nedeni, döngüler içinde kodu beklenenden çok daha fazla çağırıyor olmamızdı. Bu aslında büyük dağıtımların tamamen bozulmasına neden olan üstel bir performans sorununa neden oldu. Bu tür performans sorununun basit çözümü, yöntemleri daha az sıklıkta çağırmak için kodunuzu yeniden düzenlemektir. Ancak, kodunuzun yavaş çalışmasına neden olabilecek birçok farklı türde sorun vardır ve her proje kendi benzersiz performans zorluklarıyla karşı karşıya kalacaktır.
Mergebot için sırada ne var? Önümüzdeki haftalarda, sıklıkla istenen başka bir özelliği kullanıma sunmayı umuyoruz: çoklu site desteği.
Daha önce kodunuzun profilini çıkarmak için Blackfire kullandınız mı? Laravel/PHP kodunu optimize etme konusunda herhangi bir ipucunuz var mı? Geçmişte hangi performans sorunlarıyla karşılaştınız? Yorumlarda bize bildirin.
Mergebot için bir sonraki koltuk turunda ilk puana sahip olmak istiyorsanız, buradan kaydolduğunuzdan emin olun.
Güncelleme: Kuyruk işlerini biraz daha test etmek istiyorsanız, henüz yayınladığım yeni bir proje ilginizi çekebilir. Sqsd, uygulamanızın sıradaki işleri “AWS yolu” ile nasıl ele aldığını test etmek için AWS Elastic Beanstalk çalışan SQS arka plan programının (sqsd) bir kopyasıdır.
ev borcu WordPress sitesi