RoadRunner: PHP henteu diwangun pikeun maot, atanapi Golang pikeun nyalametkeun

RoadRunner: PHP henteu diwangun pikeun maot, atanapi Golang pikeun nyalametkeun

Halo, Habr! Kami aktip di Badoo dipake dina kinerja PHP, Kusabab urang gaduh sistem anu cukup ageung dina basa ieu sareng masalah kinerja mangrupikeun masalah nyimpen artos. Langkung ti sapuluh taun ka pengker, urang nyiptakeun PHP-FPM pikeun ieu, anu mimitina mangrupikeun set patch pikeun PHP, teras janten bagian tina distribusi resmi.

Dina taun-taun ayeuna, PHP parantos ngadamel kamajuan anu saé: tukang sampah parantos ningkat, tingkat stabilitas parantos ningkat - ayeuna anjeun tiasa nyerat daemon sareng skrip umur panjang dina PHP tanpa masalah. Hal ieu ngamungkinkeun Spiral Scout langkung jauh: RoadRunner, teu sapertos PHP-FPM, henteu ngabersihan mémori antara pamundut, anu nyayogikeun kauntungan kinerja tambahan (sanaos pendekatan ieu nyusahkeun prosés pangwangunan). Kami ayeuna nuju ékspérimén sareng alat ieu, tapi kami henteu acan gaduh hasil pikeun dibagikeun. Pikeun ngajantenkeun langkung senang ngantosan aranjeunna, Kami nyebarkeun tarjamahan tina pengumuman RoadRunner ti Spiral Scout.

Pendekatan tina tulisan éta caket sareng kami: nalika ngarengsekeun masalah kami, kami ogé sering ngagunakeun kombinasi PHP sareng Go, kéngingkeun kauntungan tina dua basa sareng henteu nyerah hiji pikeun anu sanés.

Ngarasakeun!

Salila sapuluh taun katukang, kami parantos nyiptakeun aplikasi pikeun perusahaan tina daptar pakaya 500, sarta pikeun usaha kalawan panongton teu leuwih ti 500 pamaké. Sadaya waktos ieu, insinyur urang ngembangkeun backend utamina dina PHP. Tapi dua taun ka tukang, aya hiji hal nyieun dampak badag teu ukur dina kinerja produk urang, tapi ogé dina skalabilitas maranéhanana - kami ngawanohkeun Golang (Go) kana tumpukan téhnologi urang.

Ampir langsung, urang manggihan yén Go ngamungkinkeun urang pikeun ngawangun aplikasi nu leuwih gede jeung kinerja nepi ka 40x leuwih gancang. Kalayan éta, kami tiasa ngalegaan produk anu aya anu ditulis dina PHP, ningkatkeun aranjeunna ku ngagabungkeun kaunggulan dua basa.

Kami bakal nyarioskeun ka anjeun kumaha kombinasi Go sareng PHP ngabantosan ngarengsekeun masalah pangembangan nyata sareng kumaha éta parantos janten alat pikeun urang anu tiasa ngaleungitkeun sababaraha masalah anu aya hubunganana sareng. PHP dying modél.

Lingkungan Pangembangan PHP Sapopoé Anjeun

Sateuacan urang ngobrol ngeunaan kumaha anjeun tiasa nganggo Go pikeun ngahirupkeun deui modél PHP anu maot, hayu urang tingali lingkungan pangembangan PHP standar anjeun.

Dina kalolobaan kasus, anjeun ngajalankeun aplikasi nganggo kombinasi pangladén wéb nginx sareng pangladén PHP-FPM. Kahiji ngalayanan file statik sarta alihan requests husus ka PHP-FPM, sarta PHP-FPM sorangan executes kode PHP. Panginten anjeun nganggo kombinasi anu kirang populér tina Apache sareng mod_php. Tapi sanajan jalanna rada béda, prinsipna sami.

Hayu urang tingali kumaha PHP-FPM ngaéksekusi kode aplikasi. Nalika pamundut sumping, PHP-FPM ngamimitian prosés PHP anak sareng ngalangkungan detil pamundut salaku bagian tina kaayaan na (_GET, _POST, _SERVER, jsb.).

Kaayaan teu tiasa robih salami palaksanaan skrip PHP, janten ngan ukur aya hiji cara pikeun kéngingkeun set data input énggal: ku ngabersihan mémori prosés sareng ngamimitian deui.

Modél palaksanaan ieu ngagaduhan seueur kaunggulan. Anjeun teu kedah hariwang pisan ngeunaan konsumsi mémori, sadaya prosés terasingkeun lengkep, sareng upami salah sahijina maot, éta bakal didamel deui sacara otomatis tanpa mangaruhan sésa prosés. Tapi pendekatan ieu ogé ngagaduhan kalemahan anu muncul nalika nyobian skala aplikasi.

Kalemahan sareng inefficiencies lingkungan PHP biasa

Upami anjeun kalibet dina pamekaran profésional dina PHP, maka anjeun terang dimana ngamimitian proyék énggal - ku milih kerangka. Éta diwangun ku perpustakaan pikeun suntikan dependensi, ORM, tarjamahan sareng témplat. Sarta tangtu, sadaya input pamaké bisa merenah nempatkeun kana hiji obyék (Symfony / HttpFoundation atanapi PSR-7). Frameworks anu keren!

Tapi sagalana boga harga na. Dina kerangka tingkat perusahaan mana waé, pikeun ngolah pamundut pangguna anu saderhana atanapi ngaksés pangkalan data, anjeun kedah ngamuat sahenteuna puluhan file, nyiptakeun seueur kelas sareng nga-parse sababaraha konfigurasi. Tapi anu paling parah nyaéta saatos ngabéréskeun unggal tugas anjeun kedah ngareset sadayana sareng ngamimitian deui: sadaya kode anu anjeun nembé ngamimitian janten henteu aya gunana, kalayan bantosan anjeun moal deui ngolah pamundut anu sanés. Nyaritakeun ieu ka programer anu nyerat dina basa anu sanés, sareng anjeun bakal ningali bewilderment dina rarayna.

Insinyur PHP parantos mangtaun-taun milarian cara pikeun ngabéréskeun masalah ieu, ngagunakeun téknik ngamuat kedul pinter, microframeworks, perpustakaan anu dioptimalkeun, cache, jsb. (Catetan Panarjamah: masalah ieu sawaréh bakal direngsekeun ku mecenghulna pramuat dina PHP 7.4)

Naha PHP sareng Go tiasa salamet langkung ti hiji pamundut?

Kasebut nyaéta dimungkinkeun pikeun nulis Aksara PHP anu bakal lepas leuwih ti sababaraha menit (nepi ka jam atawa poé): contona, tugas cron, CSV parsers, antrian busters. Éta sadayana dianggo dumasar kana skenario anu sami: aranjeunna nyandak tugas, ngalaksanakeunana, sareng ngantosan anu salajengna. Kodeu aya dina mémori, ngahémat millidetik anu berharga sabab seueur léngkah tambahan anu diperyogikeun pikeun ngamuat kerangka sareng aplikasi.

Tapi ngamekarkeun naskah lila-cicing teu jadi gampang. Kasalahan naon waé maéhan prosésna, diagnosis bocor mémori nyababkeun anjeun gélo, sareng anjeun henteu tiasa deui nganggo debugging F5.

Kaayaan parantos ningkat sareng sékrési PHP 7: pangumpulan sampah anu dipercaya parantos muncul, janten langkung gampang pikeun nanganan kasalahan, sareng ekstensi kernel ayeuna ditangtayungan tina bocor. Leres, insinyur masih kedah ati-ati dina mémori sareng sadar kana masalah kaayaan dina kode (naha aya basa dimana urang henteu kedah hariwang ngeunaan hal-hal ieu?). Tapi, dina PHP 7, langkung seueur kejutan anu ngantosan urang.

Naha mungkin nyandak modél damel sareng skrip PHP anu umurna panjang, adaptasi kana tugas anu langkung sepele sapertos ngolah pamundut HTTP, sareng ku kituna ngaleungitkeun kabutuhan pikeun ngamuat sadayana ti mimiti pikeun unggal pamundut?

Pikeun ngajawab masalah ieu, urang mimitina diperlukeun pikeun nerapkeun hiji aplikasi server nu bisa nampa requests HTTP tur teruskeun aranjeunna hiji-hiji ka worker PHP tanpa maéhan eta unggal waktu.

Urang terang yén urang tiasa nyerat wéb dina PHP murni (PHP-PM) atanapi nganggo ekstensi C (Swoole). Sareng sanaos unggal metodeu gaduh kaunggulan sorangan, duanana pilihan henteu cocog sareng kami - kami hoyong anu langkung. Kami peryogi langkung ti ngan ukur pangladén wéb - kami ngarep-arep kéngingkeun solusi anu tiasa nyalametkeun urang tina masalah anu aya hubunganana sareng "mimiti sesah" dina PHP, anu dina waktos anu sami tiasa gampang diadaptasi sareng dilegakeun pikeun aplikasi khusus. Nyaéta, urang peryogi server aplikasi.

Dupi Go ngabantosan ieu? Urang terang éta tiasa sabab basa nyusun aplikasi kana binari tunggal; éta cross-platform; ngagunakeun sorangan, pisan elegan, model processing paralel (concurrency) jeung perpustakaan pikeun gawé bareng HTTP; sarta pamustunganana, rébuan perpustakaan open-source sarta integrasi bakal sadia pikeun urang.

Kasesahan ngagabungkeun dua basa program

Léngkah munggaran nyaéta pikeun nangtukeun kumaha dua atanapi langkung aplikasi bakal saling komunikasi.

Contona, ngagunakeun perpustakaan éndah Alex Palaestras bisa nerapkeun babagi memori antara prosés PHP jeung Go (sarupa mod_php di Apache). Tapi perpustakaan ieu ngagaduhan fitur anu ngabatesan panggunaanana pikeun ngarengsekeun masalah urang.

Urang mutuskeun pikeun ngagunakeun pendekatan sejen, leuwih umum: ngawangun interaksi antara prosés ngaliwatan sockets / pipelines. Pendekatan ieu parantos ngabuktikeun réliabilitasna salami dasawarsa katukang sareng parantos dioptimalkeun dina tingkat sistem operasi.

Pikeun mimitian, kami nyiptakeun protokol binér saderhana pikeun tukeur data antara prosés sareng nanganan kasalahan pangiriman. Dina bentuk pangbasajanna, jinis protokol ieu sami sareng netstring с lulugu pakét ukuran tetep (dina hal urang 17 bait), nu ngandung émbaran ngeunaan jenis pakét, ukuranana sarta masker binér pikeun pariksa integritas data.

Dina sisi PHP kami dipaké fungsi pakét, sareng di sisi Go - perpustakaan encoding / binér.

Sigana urang yén hiji protokol henteu cekap - janten kami nambihan kamampuan pikeun nelepon Go jasa net / rpc langsung tina PHP. Ieu engké mantuan kami pisan dina ngembangkeun, sabab urang bisa kalayan gampang ngahijikeun perpustakaan Go kana aplikasi PHP. Hasil tina karya ieu tiasa ditingali, contona, dina produk open-source kami anu sanés Goridge.

Ngadistribusikaeun tugas sakuliah sababaraha pagawe PHP

Saatos ngalaksanakeun mékanisme interaksi, urang mimiti mikir ngeunaan cara paling éfisién nransfer tugas kana prosés PHP. Nalika aya tugas, pangladén aplikasi kedah milih pagawé gratis pikeun ngarengsekeunana. Lamun pagawe / prosés terminates kalawan kasalahan atawa "maot," urang meunang leupas tina éta sarta nyieun nu anyar pikeun ngaganti eta. Tur upami worker / prosés geus réngsé junun, urang balikkeun ka kolam renang pagawe sadia pikeun ngalakukeun tugas.

RoadRunner: PHP henteu diwangun pikeun maot, atanapi Golang pikeun nyalametkeun

Pikeun nyimpen hiji kolam renang pagawe aktip kami dipaké saluran buffered, Pikeun miceun disangka "maot" pagawe ti kolam renang, urang ditambahkeun mékanisme pikeun kasalahan tracking jeung worker nagara bagian.

Hasilna, kami nampi server PHP anu tiasa dianggo pikeun ngolah sagala pamundut anu dipidangkeun dina bentuk binér.

Supados aplikasi urang tiasa fungsina salaku pangladén wéb, urang kedah milih standar PHP anu tiasa dipercaya pikeun ngagambarkeun pamundut HTTP anu datang. Dina hal urang ngan transformasi net / http pamundut ti Pindah ka format PSR-7supados cocog sareng kalolobaan kerangka PHP anu sayogi ayeuna.

Kusabab PSR-7 dianggap immutable (sababaraha bakal nyebutkeun téhnisna éta henteu), pamekar kudu nulis aplikasi nu teu fundamentally ngubaran pamundut teh salaku éntitas global. Ieu fits nicely jeung konsép prosés PHP lila-cicing. Palaksanaan ahir kami, anu henteu acan namina, katingali sapertos kieu:

RoadRunner: PHP henteu diwangun pikeun maot, atanapi Golang pikeun nyalametkeun

Ngenalkeun RoadRunner - server aplikasi PHP-kinerja tinggi

Tugas tés munggaran urang nyaéta backend API, anu périodik ngalaman panyumputan anu teu kaduga (langkung sering ti biasana). Sanaos nginx cekap dina kalolobaan kasus, kami sering mendakan kasalahan 502 sabab kami henteu tiasa nyaimbangkeun sistem gancang-gancang pikeun paningkatan beban anu dipiharep.

Pikeun ngagentos solusi ieu, kami nyebarkeun server aplikasi PHP/Go munggaran kami di awal 2018. Sareng langsung urang ngagaduhan pangaruh anu luar biasa! Henteu ngan urang sagemblengna meunang leupas tina kasalahan 502, tapi urang ogé bisa ngurangan jumlah server ku dua per tilu, nyimpen loba duit jeung headaches pikeun insinyur sarta manajer produk.

Dina pertengahan taun, kami parantos nyampurnakeun solusi kami, diterbitkeun dina GitHub handapeun lisénsi MIT, sareng nyebatna RoadRunner, kukituna emphasizing speed luar biasa tur efisiensi.

Kumaha RoadRunner Bisa Ngaronjatkeun Tumpukan Pangembangan Anjeun

aplikasi RoadRunner diwenangkeun urang ngagunakeun Middleware net / http di sisi Go pikeun ngalakukeun verifikasi JWT saméméh pamundut malah hits PHP, kitu ogé pikeun nanganan WebSockets na aggregation kaayaan global di Prometheus.

Hatur nuhun kana RPC anu diwangun, anjeun tiasa muka API tina perpustakaan Go pikeun PHP tanpa nyerat bungkus ekstensi. Anu langkung penting, RoadRunner tiasa dianggo pikeun nyebarkeun server non-HTTP énggal. Conto kalebet peluncuran pawang dina PHP AWS Lambda, nyieun busters antrian dipercaya komo nambahkeun gRPC kana aplikasi urang.

Kalayan bantosan komunitas PHP sareng Go, kami parantos ningkatkeun stabilitas solusi, ningkatkeun kinerja aplikasi dugi ka 40 kali dina sababaraha tés, ningkatkeun alat debugging, ngalaksanakeun integrasi sareng kerangka Symfony, sareng nambihan dukungan pikeun HTTPS, HTTP/ 2, plugins, sarta PSR-17.

kacindekan

Sababaraha urang masih bray dina tempoan luntur PHP salaku slow, basa pajeujeut ngan alus keur nulis plugins WordPress. Jalma ieu malah bisa disebutkeun yen PHP boga watesan: lamun aplikasi meunang cukup badag, Anjeun kudu milih basa nu leuwih "dewasa" jeung nulis ulang dasar kode nu geus akumulasi leuwih sababaraha taun.

Pikeun sakabéh ieu abdi hoyong ngajawab: pikir deui. Kami yakin yén anjeun ngan ukur tiasa nyetél larangan pikeun PHP. Anjeun tiasa nyéépkeun saumur hirup anjeun ngaluncat tina hiji basa ka basa anu sanés, nyobian milari patandingan anu cocog pikeun kabutuhan anjeun, atanapi anjeun tiasa mimiti mikirkeun basa salaku alat. The shortcomings ditanggap tina basa kawas PHP sabenerna bisa jadi alesan sukses na. Sareng upami anjeun ngagabungkeun sareng basa sanés sapertos Go, anjeun tiasa nyiptakeun produk anu langkung kuat tibatan upami anjeun dugi ka ngan ukur hiji basa.

Saatos damel sareng kombinasi Go sareng PHP, urang tiasa nyarios yén urang bogoh ka aranjeunna. Kami henteu ngarencanakeun pikeun ngorbankeun hiji pikeun anu sanés, tapi milarian cara pikeun kéngingkeun nilai langkung tina tumpukan ganda ieu.

UPD: Kami ngabagéakeun panyipta RoadRunner sareng panulis panulis artikel asli - Lachesis

sumber: www.habr.com

Tambahkeun komentar