Hampir serentak, kami mendapati bahawa Go bukan sahaja membenarkan kami mencipta aplikasi yang lebih besar, tetapi juga meningkatkan prestasi sehingga 40x. Dengan itu, kami dapat memanjangkan produk sedia ada yang ditulis dalam PHP dan menambah baiknya dengan menggabungkan yang terbaik daripada kedua-dua bahasa.
Kami akan memberitahu anda melalui pengalaman luas dengan Go dan PHP, cara menggunakannya untuk menyelesaikan masalah pembangunan sebenar, dan cara kami boleh mengubahnya menjadi alat untuk menghapuskan beberapa masalah yang berkaitan dengan model kematian PHP.
Pembelajaran yang disyorkan: "
Tutorial Video PHPPersekitaran pembangunan PHP biasamemberitahu bagaimana Go boleh dipertingkatkan Sebelum model kematian PHP, fahami dahulu persekitaran pembangunan PHP biasa.
Biasanya, aplikasi dijalankan pada nginx dan PHP-FPM. nginx mengendalikan permintaan statik, manakala permintaan dinamik dialihkan ke PHP-FPM, yang melaksanakan kod PHP. Mungkin anda menggunakan Apache dan mod_php, tetapi mereka mempunyai prinsip yang sama dan hanya sedikit perbezaan dalam cara ia berfungsi.
Lihat cara PHP-FPM melaksanakan kod. Apabila permintaan diterima, PHP-FPM memulakan subproses PHP dan memajukan butiran permintaan kepadanya sebagai sebahagian daripada statusnya (_GET, _POST, _SERVER, dll.).
Semasa pelaksanaan skrip PHP, keadaan tidak boleh diubah, jadi hanya ada satu cara untuk mendapatkan set data input baharu: kosongkan memori proses dan mulakan semula.
Model prestasi ini mempunyai banyak kelebihan. Anda tidak perlu terlalu risau tentang penggunaan memori, semua proses diasingkan sepenuhnya, jika salah satu proses "mati", ia akan dicipta semula secara automatik dan tidak akan menjejaskan proses lain. Walau bagaimanapun, pendekatan ini mempunyai kelemahan apabila anda cuba menskalakan aplikasi anda.
Kelemahan dan Ketidakcekapan Persekitaran PHP BiasaJika anda terlibat dalam pembangunan profesional PHP, maka anda tahu di mana hendak bermula apabila mencipta projek baharu - memilih rangka kerja . Ia adalah perpustakaan untuk suntikan pergantungan, ORM, transformasi dan kaedah templat. Sudah tentu, semua data yang dimasukkan pengguna boleh diletakkan dengan mudah dalam satu objek (Symfony / HttpFoundation atau PSR-7). Bingkai ini hebat!
Tetapi semuanya ada harganya. Dalam mana-mana rangka kerja perusahaan, untuk mengendalikan permintaan pengguna yang mudah atau mengakses pangkalan data, anda perlu memuatkan sekurang-kurangnya beberapa dozen fail, mencipta banyak kelas dan menghuraikan berbilang konfigurasi. Tetapi perkara yang paling teruk ialah selepas setiap tugas selesai, anda perlu menetapkan semula semuanya dan mulakan semula: semua kod yang baru anda mulakan akan menjadi tidak berguna, dan dengan bantuannya anda tidak akan dapat memproses permintaan lain. Beritahu perkara ini kepada mana-mana pengaturcara yang menulis dalam bahasa lain - dan anda akan melihat kekeliruan di wajahnya.
Selama bertahun-tahun, jurutera PHP telah mencari cara untuk menyelesaikan masalah ini, menggunakan teknologi pemuatan malas, bingkai mikro, perpustakaan pengoptimuman, caching, dll. Tetapi akhirnya, anda masih perlu meninggalkan keseluruhan aplikasi dan memulakan semula* (Nota Penterjemah: Dengan kemunculan pramuat dalam PHP7.4, masalah ini akan diselesaikan sebahagiannya) Kendalikan berbilang permintaan?
Anda boleh menulis skrip PHP yang bertahan lebih lama daripada beberapa minit (sehingga jam atau hari): mis. Semua kerja ini mengikut corak: mereka mendapat tugas, memprosesnya, dan kemudian mendapat tugasan seterusnya. Kod tersebut berada dalam ingatan, jadi operasi tambahan untuk memuatkan rangka kerja dan aplikasi dielakkan, menjimatkan masa yang berharga.Tetapi membangunkan skrip jangka panjang bukanlah semudah itu. Sebarang ralat akan mematikan proses, limpahan memori akan menyebabkan ranap, dan F5 tidak boleh digunakan untuk nyahpepijat atur cara.
Perkara telah bertambah baik sejak PHP 7: pengumpul sampah yang boleh dipercayai telah muncul, ia menjadi lebih mudah untuk mengendalikan ralat, dan sambungan pada kernel boleh mengelakkan kebocoran memori. Ya, jurutera masih perlu berhati-hati menangani isu memori dan mengingati keadaan dalam kod (bahasa apa yang membolehkan anda tidak memberi perhatian kepada perkara ini?) Sudah tentu, dalam PHP 7, tidak banyak kejutan. Adakah mungkin untuk menggunakan model skrip PHP pemastautin untuk tugas yang lebih remeh seperti mengendalikan permintaan HTTP, dengan itu menghapuskan keperluan untuk memuat turun segala-galanya dari awal untuk setiap permintaan?Untuk menyelesaikan masalah ini, anda perlu terlebih dahulu melaksanakan aplikasi pelayan yang boleh menerima permintaan HTTP dan mengubah halanya kepada pekerja PHP satu demi satu dan bukannya mematikannya setiap kali.
Kami tahu bahawa kami boleh menulis pelayan web dalam PHP tulen (PHP-PM) atau sambungan C (Swoole). Walaupun setiap pendekatan mempunyai kelebihannya, tiada pilihan yang berkesan untuk kami - saya mahukan sesuatu yang lebih. Kami memerlukan lebih daripada sekadar pelayan web - kami mahukan penyelesaian yang membolehkan kami mengelakkan masalah yang berkaitan dengan "mula semula" dalam PHP, sambil mudah disesuaikan dan boleh dilanjutkan untuk aplikasi tertentu. Iaitu, kita memerlukan pelayan aplikasi.
Bolehkah Go membantu menyelesaikan masalah ini? Kami tahu ia boleh kerana bahasa itu menyusun aplikasi ke dalam satu binari; ia adalah platform merentas (concurrency) dan perpustakaannya sendiri untuk mengendalikan HTTP dan akhirnya, kami boleh meletakkan lebih banyak perpustakaan sumber terbuka ke dalam kami; program.
Kesukaran yang dihadapi dalam menggabungkan dua bahasa pengaturcaraan
Pertama, adalah perlu untuk menentukan bagaimana dua atau lebih aplikasi boleh berkomunikasi antara satu sama lain.
Sebagai contoh, menggunakan perpustakaan go-php Alex Palaestras, perkongsian memori antara proses PHP dan Go (seperti mod_php dalam Apache) boleh dicapai. Tetapi kefungsian perpustakaan ini mengehadkan penggunaan kami untuk menyelesaikan masalah.
Kami memutuskan untuk menggunakan satu lagi pendekatan yang lebih biasa: menstrukturkan interaksi antara proses dengan menggunakan soket / saluran paip. Pendekatan ini telah membuktikan kebolehpercayaannya sepanjang dekad yang lalu dan dioptimumkan dengan baik pada peringkat sistem pengendalian.
Mula-mula, kami mencipta protokol binari mudah untuk bertukar-tukar data antara proses dan mengendalikan ralat penghantaran. Dalam bentuk yang paling mudah, jenis protokol ini menyerupai rentetan jaring dengan pengepala paket bersaiz tetap (17 bait dalam contoh kami) yang mengandungi maklumat tentang jenis paket, saiznya dan maklumat Topeng binari yang digunakan untuk menyemak integriti data.
Di sebelah PHP, kami menggunakan fungsi pek, dan di sebelah Go, kami menggunakan pengekodan/pustaka binari.
Terdapat protokol yang agak ketinggalan zaman untuk kami dan kami telah menambah keupayaan untuk memanggil perkhidmatan net/rpc Go terus daripada PHP. Ciri ini banyak membantu kami dalam pembangunan kemudian kerana kami boleh dengan mudah menyepadukan perpustakaan Go ke dalam aplikasi PHP. Hasil kerja ini boleh dilihat dalam satu lagi produk sumber terbuka kami, Goridge.
Agihkan tugas di kalangan berbilang Pekerja PHP
Selepas mekanisme interaksi dilaksanakan, kami mula memikirkan cara untuk memindahkan tugas dengan lebih baik kepada proses PHP. Apabila tugas tiba, pelayan aplikasi mesti memilih pekerja terbiar untuk melaksanakannya. Jika proses pekerja ditamatkan dengan ralat atau "mati", kami mengosongkannya dan mencipta yang baharu. Jika proses pekerja berjaya dilaksanakan, kami mengembalikannya ke kumpulan pekerja di mana ia boleh digunakan untuk melaksanakan tugas.
Untuk menyimpan kumpulan proses pekerja aktif, kami menggunakan saluran penimbal Untuk mengosongkan proses pekerja "mati" yang tidak dijangka daripada kumpulan, kami menambah ralat penjejakan dan status proses pekerja mekanisme.
Akhir sekali, kami mempunyai pelayan PHP yang berfungsi yang mampu mengendalikan sebarang permintaan yang diberikan dalam bentuk binari.
Untuk membolehkan aplikasi kami mula berfungsi sebagai pelayan web, kami mesti memilih standard PHP yang boleh dipercayai untuk mengendalikan sebarang permintaan HTTP yang masuk. Dalam kes kami, kami hanya menukar permintaan net/http mudah daripada Pergi ke format PSR-7 supaya ia serasi dengan kebanyakan rangka kerja PHP yang tersedia hari ini.
Memandangkan PSR-7 dianggap tidak berubah (ada yang mengatakan secara teknikalnya tidak), pembangun mesti menulis aplikasi yang pada dasarnya tidak menganggap permintaan sebagai entiti global. Ini selaras sepenuhnya dengan konsep proses pemastautin PHP. Pelaksanaan akhir kami (belum ada nama diterima) kelihatan seperti ini:
RoadRunner - Pelayan Aplikasi PHP Berprestasi Tinggi
Us My tugas ujian pertama ialah bahagian belakang API yang secara berkala mengalami letusan permintaan yang tidak dapat diramalkan (lebih kerap daripada biasa). Walaupun keupayaan nginx mencukupi dalam kebanyakan kes, kami sering menghadapi ralat 502 disebabkan oleh ketidakupayaan untuk mengimbangi sistem dengan cepat di bawah peningkatan beban yang dijangkakan.
Untuk menyelesaikan masalah ini, kami menggunakan pelayan aplikasi PHP/Go pertama kami pada awal 2018. Dan mencapai hasil yang menakjubkan serta-merta! Kami bukan sahaja menghapuskan ralat 502 sepenuhnya, kami juga mengurangkan bilangan pelayan sebanyak dua pertiga, menjimatkan banyak wang dan menyelesaikan masalah pening untuk jurutera dan pengurus produk.
Pada pertengahan tahun, kami menambah baik penyelesaian kami dan mengeluarkannya di GitHub di bawah lesen MIT di bawah nama RoadRunner, sekali gus menekankan kelajuan dan kecekapannya yang menakjubkan.
Bagaimana RoadRunner menambah baik timbunan pembangunan anda
Penggunaan RoadRunner membolehkan kami menggunakan middleware net/http di sebelah Go dan juga melakukan JWT sebelum permintaan pergi ke PHP Pengesahan, dan pengendalian WebSocket dan keadaan agregat global dalam Prometheus.
Terima kasih kepada RPC terbina dalam, anda boleh membuka API mana-mana pustaka Go dalam PHP tanpa menulis pakej sambungan. Lebih-lebih lagi, dengan RoadRunner, anda boleh menggunakan pelayan baharu yang berbeza daripada HTTP. Contohnya termasuk menjalankan pemproses AWS Lambda dalam PHP, mencipta pemilih baris gilir yang berkuasa dan juga menambahkan gRPC pada aplikasi kami.
Menggunakan kedua-dua PHP dan Go, penyelesaiannya telah dipertingkatkan secara berterusan, meningkatkan prestasi aplikasi sebanyak 40x dalam beberapa ujian, menambah baik alatan penyahpepijatan, membolehkan penyepaduan dengan rangka kerja Symfony dan menambah Sokongan untuk HTTPS, HTTP/2, pemalam dan PSR-17.
Kesimpulan
Sesetengah orang masih terikat dengan konsep PHP yang lapuk, menganggap PHP adalah bahasa yang perlahan dan menyusahkan hanya sesuai untuk menulis pemalam di bawah WordPress. Orang-orang ini bahkan mengatakan bahawa PHP mempunyai had: apabila aplikasi menjadi cukup besar, anda perlu memilih bahasa yang lebih "matang" dan menulis semula pangkalan kod yang terkumpul selama ini.
Jawapan saya kepada soalan ini ialah: fikir semula. Kami percaya anda sahaja yang telah menetapkan beberapa had pada PHP. Anda boleh menghabiskan hidup anda berpindah dari satu bahasa ke bahasa lain, cuba mencari yang sesuai untuk keperluan anda, atau anda boleh menganggap bahasa sebagai alat. Dengan bahasa seperti PHP, kelemahan yang sepatutnya mungkin menjadi sebab sebenar kejayaannya. Jika anda menggabungkannya dengan bahasa lain seperti Go, anda mencipta produk yang lebih berkuasa daripada hanya menggunakan satu bahasa.
Selepas menggunakan Go dan PHP secara bergantian, kita boleh mengatakan bahawa kita menyukainya. Kami tidak akan mengorbankan satu untuk yang lain, tetapi sebaliknya kami akan mencari cara untuk mendapatkan lebih banyak daripada seni bina dwi ini.
Alamat asal: https://sudonull.com/post/6470-RoadRunne...
Alamat terjemahan: https://learnku.com/php/t/61733
Atas ialah kandungan terperinci Nikmati gabungan hebat PHP dan Go [RoadRunner]!. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!