
PHP dibuat untuk mati. Dan semuanya akan baik-baik saja, tetapi dia belum diberi kesempatan untuk melakukan ini baru-baru ini. Setahun yang lalu, alat roadrunner diumumkan di hub;
Prinsip kerja RoadRunner adalah menjaga proses yang berjalan dan memasukkan permintaan yang masuk ke dalamnya, yang memungkinkan, menurut pengembang, untuk meningkatkan kinerja aplikasi (kadang-kadang bahkan 40 kali).
Karena saya telah bekerja dengan Magento sejak lama, sepertinya ide bagus untuk menguji alat ini bukan pada kerangka mitos, tetapi pada aplikasi nyata, di mana Magento Open Source bekerja dengan sangat baik.
Biaya Inisialisasi Aplikasi Magento
Cara untuk mempercepat aplikasi RoadRunner melibatkan pengurangan waktu respons (setelah awal pemanasan) dengan mengurangi overhead menginisialisasi aplikasi.

Cuplikan layar dari presentasi Anton Tsitou "Merancang aplikasi Go / PHP hybrid menggunakan RoadRunner"
Dalam kasus Magento, waktu utama yang dihabiskan untuk startup jatuh pada:
- komponis otomatis
- bootstrap
Pembuatan komposer otomatis tidak menarik perhatian, karena merupakan standar untuk aplikasi PHP.

Membuat profil hasil yang terkait dengan Komposer.
Bootstraping aplikasi Magento termasuk menginisialisasi penangan kesalahan, memeriksa status aplikasi, dll.
Bagian tersulit adalah inisialisasi wadah IoC ("ObjectManager" dalam hal Magento) dan penciptaan berulang ketergantungan contoh melalui itu untuk mendapatkan objek aplikasi.

Membuat profil hasil yang terkait dengan bootstraping.
Implementasi RoadRunner
Untuk memulai RoadRunner, Anda perlu membuat pekerja yang akan mengandung siklus untuk menerima permintaan masuk dan mengirim tanggapan. Selain itu, alat ini berfungsi dengan permintaan dan jawaban yang mengimplementasikan PSR-7. Dari dokumentasi resmi, terlihat seperti ini:
while ($req = $psr7->acceptRequest()) { $resp = new \Zend\Diactoros\Response(); $resp->getBody()->write("hello world"); $psr7->respond($resp); }
Magento dan PSR-7
Magento belum mengimplementasikan PSR-7 dan di luar kotak menggunakan permintaan dan implementasi responnya, pendekatan di mana mereka sebagian besar diseret dari versi sebelumnya.
Untuk mengimplementasikan RoadRunner, Anda perlu menemukan titik masuk yang akan menerima permintaan dalam beberapa bentuk dan mengembalikan respons ( contoh Symfony ).
Ada titik seperti itu di Magento , \ Magento \ Framework \ AppInterface , hanya ada satu masalah, antarmuka ini tidak dirancang untuk menerima permintaan. Tapi tunggu, dari mana itu masuk ke dalam aplikasi? Perlu kembali ke awal dan mantra - PHP dilahirkan untuk mati . Oleh karena itu, sebagian besar perpustakaan, paket, dan kerangka kerja, ketika mendesain dan membaginya menjadi beberapa lapisan, tidak menganggap bahwa permintaan itu ternyata bukan hanya satu global.
Lapisan transport Magento dibangun pada prinsip yang sama. Meskipun dokumentasi menggambarkan perbedaan antara objek injeksi / objek yang dapat diperbarui , pada kenyataannya kami menggunakan permintaan tersebut sebagai layanan statefull global yang menginisialisasi dirinya dari variabel global ($ _GET, $ _POST). Selain semua ini, injeksi layanan ini dapat dilihat di semua tingkatan aplikasi di kernel itu sendiri, apalagi kualitas modul pihak ketiga.
Berdasarkan hal tersebut di atas, harapan mengimplementasikan RoadRunner hanya melalui konversi permintaan dari gaya PSR-7 ke gaya Magento dihabiskan.
Terapkan adaptor PSR-7
Kami merumuskan masalah, dengan mempertimbangkan informasi yang diterima.
Saya ingin memiliki antarmuka aplikasi tertentu yang menerima permintaan PSR-7 dan mengembalikan respons PSR-7. Anda juga perlu membuat implementasi antarmuka yang dibuat yang mengadaptasi format interaksi ini ke aplikasi Magento.

Adaptor PSR-7
Seperti yang disebutkan di atas, aplikasi magento sudah mengembalikan respons, jadi kita hanya perlu mengubahnya ke format PSR-7.
Untuk permintaan, Anda memerlukan kelas yang mem-proksi semua panggilan ke objek permintaan saat ini, yang kami masukkan ke register khusus (ya, para dewa arsitektur akan memaafkan penyimpangan ini). Selain itu, ditemukan bahwa kelas permintaan tidak digunakan satu, tetapi 3, sehingga mengharuskan mereka untuk didaftarkan ulang melalui konfigurasi IoC wadah.

Himpunan kelas yang digunakan untuk bekerja dengan kueri di Magento
Masalah aplikasi PHP yang tidak pernah mati
Aplikasi yang diluncurkan melalui RoadRunner memiliki masalah yang sama dengan proses php yang berumur panjang, dijelaskan dalam dokumentasi ( https://roadrunner.dev/docs/usage-production )
Masalah utama tingkat aplikasi yang harus dipantau oleh pengembang adalah:
Perhatian khusus dalam konteks Magento harus diberikan kepada manajemen negara, karena baik dalam kernel dan dalam modul pihak ketiga, caching pengguna / produk / kategori saat ini di dalam layanan adalah pendekatan yang sangat umum.
protected function getCustomer(): ?CustomerInterface { if (!$this->customer) { if ($this->customerSession->isLoggedIn()) { $this->customer = $this->customerRepository->getById($this->customerSession->getCustomerId()); } else { return null; } } return $this->customer; }
Contoh metode dari kernel menggunakan status objek.
Menjalankan Magento Rest API Server melalui RoadRunner
Mengingat potensi masalah dengan negara global, berdasarkan pada pengalaman mengembangkan bagian ujung depan Magento, bagian WebApi yang paling cocok dan tidak menyakitkan dipilih untuk diluncurkan.
Hal pertama yang harus dilakukan adalah menciptakan pekerja kami, yang akan berjalan melalui RoadRunner dan hidup tanpa henti (hampir). Untuk melakukan ini, ambil sepotong kode dari panduan RoadRunner dan tambahkan aplikasi kami di sana, dibungkus dengan adaptor PSR-7.
$relay = new StreamRelay(STDIN, STDOUT); $psr7 = new PSR7Client(new Worker($relay)); $bootstrap = \Magento\Framework\App\Bootstrap::create(BP, []); $app = $bootstrap->createApplication(\Magento\Framework\App\Http::class); $psr7Application = $bootstrap->getObjectManager()->create( \Isxam\M2RoadRunner\Application\MagentoAppWrapper::class, [ 'magentoApp' => $app ] ); while ($request = $psr7->acceptRequest()) { try { $response = $psr7Application->handle($request); $psr7->respond($response); } catch (\Throwable $e) { $psr7->getWorker()->error((string)$e); } }
Kode sebelum loop sementara akan dieksekusi pada awal pekerja, semua yang ada di dalam loop - dengan setiap permintaan baru.
Ketika pekerja kami siap, kami melanjutkan untuk mengonfigurasi server RoadRunner yang ditulis dalam Go. Semuanya bagus dan cepat di sini, hanya paket komposer yang mengunduh file yang dapat dieksekusi tidak perlu diinstal, yang tidak menyenangkan. Kami membuat konfigurasi server kami - yang paling sederhana terlihat seperti ini.
http: address: 0.0.0.0:8086 workers: command: "php worker.php" pool: numWorkers: 1
Konfigurasi RoadRunner.
Dokumentasi berisi banyak pengaturan yang memungkinkan Anda untuk mengkonfigurasi server secara fleksibel sehingga keinginan untuk mengkompilasi biner Anda tidak terjadi dengan tepat.
./rr serve -v -d
Server mulai
Pengujian solusi
Alat-alatnya
Untuk pengujian yang mudah, kami mengambil sesuatu yang sederhana, misalnya artillery.io.
Kami akan menguji kinerja dengan bantuan satu pengguna yang mengeksekusi kueri secara berurutan (RoadRunner juga mendukung eksekusi kueri di beberapa utas, kami akan menyerahkan pertanyaan ini kepada peneliti lain)
Pada input, kami memiliki file konfigurasi artileri dengan dua lingkungan - Apache dan RoadRunner. Mereka berdua bekerja dengan instance Magento yang sama, jadi di sini mereka memiliki kedudukan yang sama.
Skenario pengujian
Skenario berikut digunakan untuk mengukur kinerja kedua solusi.
Skenario 1. Membuat kategori - name: "S1. Create category" flow: - loop: - post: url: "/rest/V1/categories" json: category: name: "name-{{prefix}}-{{ $loopCount }}" parent_id: 2 is_active: true count: 100
Skenario 2. Mendapatkan daftar negara - name: "S2. Countries list" flow: - loop: - get: url: "/rest/V1/directory/countries" count: 100
Skenario 3: Daftar Jenis Produk - name: "S3. Product types list" flow: - loop: - get: url: "/rest/V1/products/types" count: 100
Skenario 4. Mendapatkan daftar set atribut - name: "S4. Product attribute sets list" flow: - loop: - get: url: "/rest/V1/products/attribute-sets/sets/list?searchCriteria" count: 100
Skenario 5. Mendapatkan kategori - name: "S5. Category get" flow: - loop: - get: url: "/rest/V1/categories/2" count: 100
Skenario 6. Penciptaan Produk - name: "S6. Create product" flow: - loop: - post: url: '/rest/V1/products' json: product: sku: "sku-{{prefix}}-{{ $loopCount }}" name: "name-{{prefix}}-{{ $loopCount }}" attribute_set_id: 4 price: 100 type_id: "simple" count: 100
Skenario 7. Mengambil Daftar Produk - name: "S7. Get product list" flow: - loop: - get: url: "/rest/V1/products?searchCriteria[pageSize]=20" count: 100
Hasil
Setelah menjalankan semua skrip secara bergantian melalui RoadRunner dan Apache, median dari durasi kueri diperoleh. Menurut median, kecepatan semua skenario berbeda dengan kira-kira nilai yang sama ~ 50ms.

Hasil Uji Kinerja.
Ringkasan
Eksperimen langsung mengonfirmasi asumsi tentang kesegaran perolehan kinerja RoadRunner pada aplikasi tertentu. Dengan menggunakan alat ini, Anda dapat mempercepat pemrosesan permintaan aplikasi dengan konstan yang sama dengan waktu inisialisasi lingkungan dan dependensi.
Pada penangan ringan, ini memungkinkan Anda untuk mempercepat aplikasi di kali, pada berat itu hampir tidak memberikan efek nyata. Jika kode Anda lambat, maka kemungkinan pisang raja tidak akan membantunya.
Jika aplikasi Anda ditulis dengan baik, maka kemungkinan besar tidak akan ada masalah dengan operasinya melalui RoadRunner, tetapi jika aplikasi tersebut membutuhkan adaptasi untuk digunakan dengan RoadRunner, maka kemungkinan besar itu akan memerlukan hal yang sama tanpa RoadRunner untuk lebih jelas mengamati lapisan arsitektur. dan mengikuti standar pengembangan di lapangan.
Magento Open Source umumnya cocok untuk diluncurkan di lingkungan yang diberikan, namun, itu membutuhkan peningkatan pada lapisan transportasi dan memperbaiki logika bisnis untuk mencegah perilaku yang salah selama permintaan berulang dalam proses yang sama. Selain itu, penggunaan RoadRunner memberlakukan batasan tertentu pada pendekatan pembangunan, namun, mereka tidak bertentangan dengan praktik yang sudah mapan.
Akhirnya tangkapan layar yang bagus. Kapan Anda masih melihat permintaan Magento dengan waktu respons ini? Referensi
- Contoh dari artikel
- Situs Resmi RoadRunner