OpenResty: mengubah NGINX menjadi server aplikasi lengkap

OpenResty: mengubah NGINX menjadi server aplikasi lengkapKami menerbitkan kembali transkrip laporan konferensi tersebut HighLoad ++ 2016, yang diadakan di Skolkovo dekat Moskow pada 7-8 November tahun lalu. Vladimir Protasov memberitahu cara memperluas fungsionalitas NGINX dengan OpenResty dan Lua.

Halo semuanya, nama saya Vladimir Protasov, saya bekerja untuk Parallels. Saya akan bercerita sedikit tentang diri saya. Saya menghabiskan tiga perempat hidup saya untuk menulis kode. Saya benar-benar menjadi seorang programmer dalam arti sebenarnya: Saya terkadang melihat kode dalam mimpi saya. Seperempat kehidupan adalah perkembangan industri, penulisan kode yang langsung masuk ke produksi. Kode yang sebagian dari Anda gunakan tetapi tidak mengetahuinya.

Untuk memberi tahu Anda betapa buruknya itu. Ketika saya masih kecil, saya datang dan mereka memberi saya dua database terabyte ini. Sekarang ada di sini untuk semua orang yang memiliki beban tinggi. Saya pergi ke konferensi dan bertanya: β€œTeman-teman, beri tahu saya, apakah Anda memiliki data besar, apakah semuanya keren? Berapa banyak pangkalan yang Anda miliki di sana? Mereka menjawab saya: β€œKami punya 100 gigabyte!” Saya berkata: β€œKeren, 100 gigabyte!” Dan saya berpikir sendiri bagaimana cara menyimpan poker face dengan rapi. Anda berpikir, ya, orang-orang itu keren, lalu Anda kembali lagi dan mengutak-atik database multi-terabyte ini. Dan ini menjadi junior. Bisakah Anda bayangkan betapa suksesnya itu?

Saya tahu lebih dari 20 bahasa pemrograman. Inilah yang harus saya pahami selama bekerja. Mereka memberi Anda kode dalam Erlang, di C, di C++, di Lua, di Python, di Ruby, di sesuatu yang lain, dan Anda harus memotong semuanya. Secara umum, saya harus melakukannya. Jumlah pastinya tidak dapat dihitung, tetapi sekitar 20 jumlahnya hilang.

Karena semua orang di sini tahu apa itu Parallels dan apa yang kami lakukan, saya tidak akan membicarakan betapa kerennya kami dan apa yang kami lakukan. Saya hanya akan memberi tahu Anda bahwa kami memiliki 13 kantor di seluruh dunia, lebih dari 300 karyawan, pengembangan di Moskow, Tallinn, dan Malta. Jika mau, Anda dapat pindah dan pindah ke Malta jika cuaca dingin di musim dingin dan Anda perlu menghangatkan punggung.

Secara khusus, departemen kami menulis dengan Python 2. Kami sedang dalam bisnis dan kami tidak punya waktu untuk memperkenalkan teknologi yang modis, jadi kami menderita. Kita mempunyai Django, karena ia mempunyai segalanya, dan kita mengambil kelebihannya dan membuangnya. Juga MySQL, Redis dan NGINX. Kami juga punya banyak hal keren lainnya. Kami punya MongoDB, kelinci berlarian, kami tidak punya apa-apa - tapi itu bukan milik saya, dan saya tidak melakukannya.

BukaResty

aku bercerita tentang diriku sendiri. Mari kita lihat apa yang akan saya bicarakan hari ini:

  • Apa itu OpenResty dan dimakan dengan apa?
  • Mengapa menemukan kembali roda ketika kita memiliki Python, NodeJS, PHP, Go dan hal-hal keren lainnya yang disukai semua orang?
  • Dan beberapa contoh kehidupan nyata. Laporannya harus saya potong banyak, karena saya dapatnya selama 3,5 jam, jadi contohnya sedikit.

OpenResty adalah NGINX. Berkat dia, kami memiliki server web lengkap yang ditulis dengan baik dan bekerja dengan cepat. Saya rasa sebagian besar dari kita menggunakan NGINX dalam produksi. Anda semua tahu bahwa dia cepat dan keren. Mereka membuat I/O sinkron yang keren di dalamnya, jadi kita tidak perlu melakukan siklus apa pun dengan cara yang sama seperti siklus gevent dengan Python. Gevent itu keren, keren, tetapi jika Anda menulis kode-C dan ada yang tidak beres dengan gevent, Anda akan gila-gilaan men-debug-nya. Saya punya pengalaman: butuh dua hari penuh untuk mencari tahu apa yang salah di sana. Jika seseorang tidak menggali selama beberapa minggu sebelumnya, menemukan masalahnya, menulisnya di Internet, dan Google tidak menemukannya, maka kita akan menjadi gila sepenuhnya.

NGINX sudah melakukan caching dan konten statis. Anda tidak perlu khawatir tentang bagaimana melakukannya secara manusiawi, sehingga Anda tidak melambat di suatu tempat, sehingga Anda tidak kehilangan deskriptor di suatu tempat. Nginx sangat mudah digunakan, Anda tidak perlu memikirkan apa yang harus diambil - WSGI, PHP-FPM, Gunicorn, Unicorn. Nginx telah diinstal, diberikan kepada admin, mereka tahu cara bekerja dengannya. Nginx memproses permintaan secara terstruktur. Saya akan membicarakan ini nanti. Singkatnya, dia memiliki fase ketika dia baru saja menerima permintaan, saat dia memproses, dan saat dia memberikan konten kepada pengguna.

Nginx itu keren, tapi ada satu masalah: Nginx tidak cukup fleksibel bahkan dengan semua fitur keren yang dimasukkan ke dalam konfigurasi, meskipun faktanya bisa dikustomisasi. Kekuatan ini tidak cukup. Oleh karena itu, orang-orang dari Taobao pada suatu waktu, saya pikir sekitar delapan tahun yang lalu, membangun Lua ke dalamnya. Apa yang dia berikan?

  • Ukuran. Itu kecil. LuaJIT memberikan overhead memori sekitar 100-200 kilobyte dan overhead kinerja minimal.
  • Mempercepat. Penerjemah LuaJIT dekat dengan C dalam banyak situasi, dalam beberapa situasi ia kalah dari Java, dalam beberapa situasi ia menyusulnya. Untuk sementara, ini dianggap canggih, kompiler JIT paling keren. Sekarang ada yang lebih keren, tapi berat sekali, misalnya V8 sama. Beberapa penerjemah JS dan Java HotSpot lebih cepat di beberapa titik, namun masih kalah di beberapa titik.
  • Mudah untuk dipelajari. Jika Anda memiliki, katakanlah, basis kode Perl dan Anda tidak melakukan Pemesanan, Anda tidak akan menemukan pemrogram Perl. Karena mereka tidak ada, mereka semua dibawa pergi, dan mengajar mereka lama dan sulit. Jika Anda menginginkan programmer untuk hal lain, mereka mungkin juga harus dilatih ulang atau ditemukan. Dalam kasus Lua, semuanya sederhana. Lua dapat dipelajari oleh junior mana pun dalam tiga hari. Butuh waktu sekitar dua jam bagi saya untuk mengetahuinya. Dua jam kemudian, saya sudah menulis kode dalam produksi. Sekitar seminggu kemudian, dia langsung menuju produksi dan keluar.

Hasilnya, tampilannya seperti ini:

OpenResty: mengubah NGINX menjadi server aplikasi lengkap

Ada banyak hal di sini. OpenResty telah merakit banyak modul, baik luash maupun mesin. Dan Anda telah menyiapkan segalanya - diterapkan dan berfungsi.

contoh

Cukup liriknya, mari kita beralih ke kodenya. Ini sedikit Hello World:

OpenResty: mengubah NGINX menjadi server aplikasi lengkap

Apa yang ada disana? ini adalah lokasi mesinnya. Kami tidak khawatir, kami tidak menulis perutean kami sendiri, kami tidak mengambil yang sudah jadi - kami sudah memilikinya di NGINX, kami hidup dengan baik dan malas.

content_by_lua_block adalah blok yang mengatakan bahwa kami menyajikan konten menggunakan skrip Lua. Kami mengambil variabel mesin remote_addr dan masukkan ke dalamnya string.format. Ini sama dengan sprintf, hanya di Lua, hanya benar. Dan kami memberikannya kepada klien.

Hasilnya akan terlihat seperti ini:

OpenResty: mengubah NGINX menjadi server aplikasi lengkap

Tapi kembali ke dunia nyata. Dalam produksi, tidak ada yang menerapkan Hello World. Aplikasi kita biasanya masuk ke database atau di tempat lain dan sering kali menunggu respons.

OpenResty: mengubah NGINX menjadi server aplikasi lengkap

Hanya duduk dan menunggu. Itu tidak terlalu bagus. Ketika 100.000 pengguna datang, itu sangat sulit bagi kami. Oleh karena itu, mari kita gunakan aplikasi sederhana sebagai contoh. Kita akan mencari gambar, misalnya kucing. Hanya saja kami tidak hanya mencari, kami akan memperluas kata kunci dan, jika pengguna mencari "anak kucing", kami akan menemukan kucing, bulu halus, dan sebagainya. Pertama kita perlu mendapatkan data permintaan di backend. Ini terlihat seperti ini:

OpenResty: mengubah NGINX menjadi server aplikasi lengkap

Dua baris memungkinkan Anda mengambil parameter GET, tanpa komplikasi. Kemudian kita, misalnya, mendapatkan informasi ini dari database dengan tabel berdasarkan kata kunci dan ekstensi menggunakan query SQL biasa. Semuanya sederhana. Ini terlihat seperti ini:

OpenResty: mengubah NGINX menjadi server aplikasi lengkap

Kami menghubungkan perpustakaan resty.mysql, yang sudah kami miliki di kit. Kita tidak perlu menginstal apapun, semuanya sudah siap. Tentukan cara menyambungkan dan membuat kueri SQL:

OpenResty: mengubah NGINX menjadi server aplikasi lengkap

Agak menakutkan, tapi berhasil. Di sini 10 adalah batasnya. Kami mengeluarkan 10 rekaman, kami malas, kami tidak ingin menampilkan lebih banyak. Di SQL, saya lupa tentang batasannya.

Kemudian kami menemukan gambar untuk semua pertanyaan. Kami mengumpulkan banyak permintaan dan mengisi tabel Lua yang disebut reqs, dan lakukan ngx.location.capture_multi.

OpenResty: mengubah NGINX menjadi server aplikasi lengkap

Semua permintaan ini berjalan secara paralel, dan jawabannya dikembalikan kepada kami. Waktu berjalan sama dengan waktu respons yang paling lambat. Jika kita semua membalas dalam 50 milidetik, dan kita mengirimkan seratus permintaan, maka kita akan menerima respons dalam 50 milidetik.

Karena kami malas dan tidak ingin menulis penanganan HTTP dan caching, kami akan membuat NGINX melakukan segalanya untuk kami. Seperti yang Anda lihat, ada permintaan url/fetch, ini dia:

OpenResty: mengubah NGINX menjadi server aplikasi lengkap

Kami membuatnya sederhana proxy_pass, tentukan tempat untuk melakukan cache, bagaimana melakukannya, dan semuanya berfungsi untuk kami.

Namun ini belum cukup, kami tetap perlu memberikan datanya kepada pengguna. Ide paling sederhana adalah membuat serial semuanya ke JSON, dengan mudah, dalam dua baris. Kami memberikan Content-Type, kami memberikan JSON.

Namun ada satu kesulitan: pengguna tidak ingin membaca JSON. Kita perlu menarik pengembang front-end. Terkadang kita merasa tidak ingin melakukannya pada awalnya. Ya, dan pakar SEO akan mengatakan bahwa jika kita mencari gambar, maka mereka tidak peduli. Dan jika kami memberi mereka beberapa konten, mereka akan mengatakan bahwa mesin pencari kami tidak mengindeks apa pun.

Apa yang harus dilakukan dengan itu? Tentu saja, kami akan memberikan HTML kepada pengguna. Menghasilkan dengan pegangan bukanlah hal yang salah, jadi kami ingin menggunakan templat. Ada perpustakaan untuk ini lua-resty-template.

OpenResty: mengubah NGINX menjadi server aplikasi lengkap

Anda pasti pernah melihat tiga huruf OPM yang ditakuti. OpenResty hadir dengan manajer paketnya sendiri, yang melaluinya Anda dapat menginstal banyak modul berbeda, khususnya, lua-resty-template. Ini adalah mesin templat sederhana yang mirip dengan templat Django. Di sana Anda dapat menulis kode dan melakukan substitusi variabel.

Hasilnya, semuanya akan terlihat seperti ini:

OpenResty: mengubah NGINX menjadi server aplikasi lengkap

Kami mengambil data dan merender template lagi dalam dua baris. Pengguna senang, mendapat kucing. Sejak kami memperluas permintaannya, dia juga menerima anjing laut berbulu untuk anak kucing. Anda tidak pernah tahu, mungkin dia sedang mencarinya, tetapi dia tidak bisa merumuskan permintaannya dengan benar.

Semuanya keren, tapi kami sedang dalam pengembangan, dan kami belum ingin menampilkannya kepada pengguna. Ayo lakukan otorisasi. Untuk melakukannya, mari kita lihat bagaimana NGINX menangani permintaan dalam kaitannya dengan OpenResty:

  • Fase pertama - mengakses, ketika pengguna baru saja datang, dan kami melihatnya berdasarkan header, berdasarkan alamat IP, berdasarkan data lainnya. Anda bisa langsung memotongnya jika kami tidak menyukainya. Ini dapat digunakan untuk otorisasi, atau jika kami menerima banyak permintaan, kami dapat dengan mudah memotongnya pada tahap ini.
  • menulis kembali. Menulis ulang beberapa data permintaan.
  • Konten. Kami memberikan konten kepada pengguna.
  • penyaring tajuk. Ubah header respons. Jika kita menggunakan proxy_pass, kita dapat menulis ulang beberapa header sebelum memberikannya kepada pengguna.
  • penyaring tubuh. Kita bisa mengubah tubuh.
  • mencatat - masuk. Dimungkinkan untuk menulis log di elasticsearch tanpa lapisan tambahan.

Otorisasi kami akan terlihat seperti ini:

OpenResty: mengubah NGINX menjadi server aplikasi lengkap

Kami akan menambahkannya ke dalamnya location, yang telah kami jelaskan sebelumnya, dan letakkan kode berikut di sana:

OpenResty: mengubah NGINX menjadi server aplikasi lengkap

Kami melihat apakah kami memiliki token cookie. Jika tidak, maka kami akan melakukan otorisasi. Pengguna licik dan mungkin menebak bahwa token cookie perlu disetel. Oleh karena itu, kami juga akan memasukkannya ke dalam Redis:

OpenResty: mengubah NGINX menjadi server aplikasi lengkap

Kode untuk bekerja dengan Redis sangat sederhana dan tidak berbeda dengan bahasa lain. Pada saat yang sama, semua input/output, apa yang ada, apa yang ada di sini, tidak diblokir. Jika Anda menulis kode sinkron, maka kode tersebut berfungsi secara asinkron. Seperti halnya Gevent, hanya dilakukan dengan baik.

OpenResty: mengubah NGINX menjadi server aplikasi lengkap

Mari kita lakukan otorisasi sendiri:

OpenResty: mengubah NGINX menjadi server aplikasi lengkap

Kami mengatakan bahwa kami perlu membaca isi permintaan. Kami menerima argumen POST, periksa apakah login dan kata sandi sudah benar. Jika salah, maka kami melakukan otorisasi. Dan jika benar, maka kita menulis tokennya ke Redis:

OpenResty: mengubah NGINX menjadi server aplikasi lengkap

Jangan lupa untuk mengatur cookie, ini juga dilakukan dalam dua baris:

OpenResty: mengubah NGINX menjadi server aplikasi lengkap

Contohnya sederhana, spekulatif. Tentu saja kami tidak akan membuat layanan yang menunjukkan kucing kepada orang-orang. Tapi siapa yang mengenal kita. Jadi mari kita membahas apa yang bisa dilakukan dalam produksi.

  • Bagian belakang minimalis. Terkadang kita perlu memberikan sedikit data ke backend: di suatu tempat kita perlu mengganti tanggal, di suatu tempat kita perlu menampilkan semacam daftar, katakanlah berapa banyak pengguna di situs sekarang, pasang penghitung atau statistik. Sesuatu yang sangat kecil. Beberapa potongan minimal dapat dibuat dengan sangat mudah. Ini akan cepat, mudah dan hebat.
  • Pemrosesan awal data. Terkadang kami ingin menyematkan iklan di halaman kami, dan kami menerima iklan tersebut dengan permintaan API. Ini sangat mudah dilakukan di sini. Kami tidak memuat backend kami, yang sudah bekerja keras. Anda dapat mengambil dan mengumpulkan di sini. Kita dapat mencetak beberapa JS atau, sebaliknya, melepaskan, memproses sesuatu terlebih dahulu sebelum memberikannya kepada pengguna.
  • Fasad untuk layanan mikro. Ini juga merupakan kasus yang sangat bagus, saya menerapkannya. Sebelumnya, saya bekerja di Tenzor, sebuah perusahaan pelaporan elektronik yang menyediakan pelaporan untuk sekitar setengah badan hukum di negara tersebut. Kami telah membuat layanan, banyak hal dilakukan di sana menggunakan mekanisme yang sama: perutean, otorisasi, dan banyak lagi.
    OpenResty dapat digunakan sebagai perekat layanan mikro Anda untuk menyediakan akses tunggal ke semuanya dan satu antarmuka. Karena layanan mikro dapat ditulis sedemikian rupa sehingga Anda memiliki Node.js di sini, Anda memiliki PHP di sini, Anda memiliki Python di sini, ada beberapa hal Erlang di sini, kami memahami bahwa kami tidak ingin menulis ulang kode yang sama di mana pun. Oleh karena itu, OpenResty bisa dicolokkan ke depan.

  • Statistik dan analitik. Biasanya NGINX ada di pintu masuk, dan semua permintaan melewatinya. Di tempat inilah sangat nyaman untuk dikumpulkan. Anda dapat langsung menghitung sesuatu dan membuangnya ke suatu tempat, misalnya Elasticsearch, Logstash yang sama, atau cukup menulisnya ke log lalu mengirimkannya ke suatu tempat.
  • Sistem Multi-Pengguna. Misalnya saja game online juga sangat baik untuk dilakukan. Hari ini di Cape Town Alexander Gladysh akan memberi tahu Anda cara membuat prototipe game multipemain dengan cepat menggunakan OpenResty.
  • Pemfilteran Permintaan (WAF). Sekarang menjadi mode untuk membuat segala macam firewall aplikasi web, ada banyak layanan yang menyediakannya. Dengan bantuan OpenResty, Anda dapat menjadikan diri Anda firewall aplikasi web, yang akan dengan mudah dan sederhana memfilter permintaan sesuai kebutuhan Anda. Jika Anda memiliki Python, maka Anda memahami bahwa PHP pasti tidak akan disuntikkan kepada Anda, kecuali, tentu saja, Anda menelurkannya di mana saja dari konsol. Anda tahu Anda memiliki MySQL dan Python. Mungkin, di sini mereka dapat mencoba melakukan semacam penelusuran direktori dan memasukkan sesuatu ke dalam database. Oleh karena itu, Anda dapat memfilter permintaan bodoh dengan cepat dan murah langsung dari depan.
  • Masyarakat. Karena OpenResty didasarkan pada NGINX, ia memiliki bonus - ini dia Komunitas NGINX. Jumlahnya sangat besar, dan banyak pertanyaan yang Anda miliki pada awalnya telah dijawab oleh komunitas NGINX.

    Pengembang Lua. Kemarin saya berbicara dengan orang-orang yang datang ke hari pelatihan HighLoad++ dan mendengar bahwa hanya Tarantool yang ditulis dalam Lua. Ini tidak benar, banyak hal yang ditulis dalam Lua. Contoh: OpenResty, server Prosody XMPP, mesin permainan Love2D, Lua ditulis dalam Warcraft dan di tempat lain. Ada banyak sekali pengembang Lua, mereka memiliki komunitas yang besar dan responsif. Semua pertanyaan Lua saya terjawab dalam beberapa jam. Saat Anda menulis ke milis, dalam beberapa menit sudah ada banyak jawaban, mereka menjelaskan apa dan bagaimana, apa apa. Itu bagus. Sayangnya, komunitas tulus yang baik hati tidak ada di mana-mana.
    OpenResty memiliki GitHub, tempat Anda dapat membuka masalah jika terjadi kerusakan. Ada milis di Google Grup tempat Anda dapat mendiskusikan masalah umum, ada milis dalam bahasa Mandarin - Anda tidak pernah tahu, mungkin Anda tidak bisa berbahasa Inggris, tetapi Anda memiliki pengetahuan bahasa Mandarin.

Hasil

  • Saya harap saya dapat menyampaikan bahwa OpenResty adalah kerangka web yang sangat nyaman.
  • Batas masuknya rendah, karena kodenya mirip dengan yang kita tulis, bahasanya cukup sederhana dan minimalis.
  • Ini menyediakan I/O asinkron tanpa panggilan balik, kita tidak akan mengalami mie seperti yang terkadang kita tulis di NodeJS.
  • Penerapannya mudah, karena kita hanya memerlukan NGINX dengan modul yang tepat dan kode kita, dan semuanya langsung berfungsi.
  • Komunitas besar dan responsif.

Saya tidak menceritakan secara detail cara routingnya, ternyata ceritanya panjang sekali.

Terima kasih!


Vladimir Protasov - OpenResty: mengubah NGINX menjadi server aplikasi lengkap

Sumber: www.habr.com

Tambah komentar