OpenResty: menukar NGINX menjadi pelayan aplikasi sepenuhnya

OpenResty: menukar NGINX menjadi pelayan aplikasi sepenuhnyaKami sekali lagi menerbitkan transkrip laporan persidangan itu HighLoad ++ 2016, yang berlangsung di Skolkovo dekat Moscow pada 7-8 November tahun lepas. Vladimir Protasov menerangkan cara memanjangkan fungsi NGINX dengan OpenResty dan Lua.

Halo semua, nama saya Vladimir Protasov, saya bekerja di Parallels. Saya akan memberitahu anda sedikit tentang diri saya. Saya menghabiskan tiga perempat daripada hidup saya menulis kod. Saya menjadi pengaturcara kepada teras dalam erti kata literal: kadangkala saya melihat kod dalam mimpi saya. Satu perempat daripada kehidupan ialah pembangunan perindustrian, menulis kod yang terus ke dalam pengeluaran. Kod yang sesetengah daripada anda gunakan tetapi tidak menyedarinya.

Jadi anda faham betapa teruknya ia. Semasa saya masih kecil, saya datang dan diberikan pangkalan data dua terabait ini. Ia adalah beban yang tinggi untuk semua orang di sini sekarang. Saya pergi ke persidangan dan bertanya: "Kawan-kawan, beritahu saya, anda mempunyai data besar, adakah semuanya bagus? Berapa banyak pangkalan yang anda ada di sana? Mereka menjawab saya: "Kami mempunyai 100 gigabait!" Saya berkata: "Sejuk, 100 gigabait!" Dan saya berfikir sendiri bagaimana untuk menjaga muka poker saya dengan berhati-hati. Anda fikir, ya, lelaki itu hebat, dan kemudian anda kembali dan bermain-main dengan pangkalan data berbilang terabait ini. Dan ini adalah menjadi junior. Bolehkah anda bayangkan betapa hebatnya ini?

Saya tahu lebih daripada 20 bahasa pengaturcaraan. Ini adalah sesuatu yang saya perlu fikirkan semasa saya bekerja. Mereka memberi anda kod dalam Erlang, C, C++, Lua, Python, Ruby, sesuatu yang lain, dan anda perlu memotong semuanya. Secara umum, saya terpaksa. Tidak dapat mengira nombor yang tepat, tetapi di suatu tempat sekitar 20hb nombor itu telah hilang.

Memandangkan semua orang yang hadir tahu apa itu Parallels dan apa yang kami lakukan, saya tidak akan bercakap tentang betapa hebatnya kami dan apa yang kami lakukan. Saya hanya akan memberitahu anda bahawa kami mempunyai 13 pejabat di seluruh dunia, lebih daripada 300 pekerja, pembangunan di Moscow, Tallinn dan Malta. Jika anda mahu, anda boleh mengambilnya dan berpindah ke Malta jika ia sejuk pada musim sejuk dan anda perlu memanaskan punggung anda.

Secara khusus, jabatan kami menulis dalam Python 2. Kami menjalankan perniagaan dan tidak mempunyai masa untuk melaksanakan teknologi yang bergaya, jadi kami menderita. Kami menggunakan Django kerana ia mempunyai segala-galanya, dan kami mengambil apa yang tidak perlu dan membuangnya. Juga MySQL, Redis dan NGINX. Kami juga mempunyai banyak perkara menarik yang lain. Kami mempunyai MongoDB, kami mempunyai arnab yang berkeliaran, kami mempunyai segala-galanya - tetapi ia bukan milik saya, dan saya tidak melakukannya.

OpenResty

Saya memberitahu tentang diri saya. Mari kita fikirkan apa yang akan saya bincangkan hari ini:

  • Apakah OpenResty dan dengan apa ia dimakan?
  • Mengapa mencipta semula roda lain apabila kita mempunyai Python, NodeJS, PHP, Go dan perkara menarik lain yang semua orang berpuas hati?
  • Dan beberapa contoh dari kehidupan. Saya terpaksa memotong laporan banyak kerana saya mengambil masa 3,5 jam, jadi akan ada beberapa contoh.

OpenResty ialah NGINX. Terima kasih kepadanya, kami mempunyai pelayan web lengkap yang ditulis dengan baik dan berfungsi dengan cepat. Saya rasa kebanyakan kita menggunakan NGINX dalam pengeluaran. Anda semua tahu dia cepat dan keren. Mereka membuat I/O segerak yang hebat di dalamnya, jadi kita tidak perlu mengitar apa-apa, sama seperti mereka melakukan gevent dalam Python. Gevent hebat, hebat, tetapi jika anda menulis kod C dan ada masalah, maka dengan Gevent anda akan menjadi gila menyahpepijatnya. Saya mempunyai pengalaman: mengambil masa dua hari penuh untuk mengetahui apa yang salah di sana. Jika seseorang tidak menggali selama beberapa minggu, menemui masalah itu, menulis di Internet, dan Google tidak menemuinya, maka kami akan menjadi gila sepenuhnya.

NGINX sudah melakukan caching dan kandungan statik. Anda tidak perlu risau tentang cara melakukan perkara ini secara manusiawi, supaya anda tidak perlahan di suatu tempat, supaya anda tidak kehilangan deskriptor di suatu tempat. Nginx sangat mudah untuk digunakan, anda tidak perlu memikirkan apa yang perlu diambil - WSGI, PHP-FPM, Gunicorn, Unicorn. Nginx telah dipasang, diberikan kepada pentadbir, mereka tahu bagaimana untuk bekerja dengannya. Nginx memproses permintaan secara berstruktur. Saya akan bercakap tentang ini sedikit kemudian. Ringkasnya, ia mempunyai fasa apabila ia hanya menerima permintaan, apabila ia memprosesnya dan apabila ia menyampaikan kandungan kepada pengguna.

Nginx adalah keren, tetapi ada satu masalah: ia tidak cukup fleksibel, walaupun dengan semua ciri hebat yang telah dijejalkan oleh lelaki itu ke dalam konfigurasi, walaupun apa yang boleh dikonfigurasikan. Kuasa ini tidak mencukupi. Itulah sebabnya lelaki dari Taobao, suatu masa dahulu, nampaknya seperti lapan tahun yang lalu, membina Lua ke dalamnya. Apa yang ia berikan?

  • saiz. Ia adalah kecil. LuaJIT memberikan kira-kira 100-200 kilobait overhed memori dan overhed prestasi minimum.
  • Kelajuan. Jurubahasa LuaJIT hampir dengan C dalam banyak situasi, dalam beberapa situasi ia kalah kepada Java, dalam keadaan lain ia mengatasinya. Untuk beberapa lama ia dianggap sebagai keadaan seni, pengkompil JIT yang paling hebat. Kini terdapat yang lebih sejuk, tetapi ia sangat berat, contohnya, V8 yang sama. Sesetengah jurubahasa JS dan Java HotSpot lebih pantas pada beberapa titik, tetapi di beberapa tempat mereka masih kalah.
  • Mudah dipelajari. Jika anda mempunyai, katakan, asas kod Perl, dan anda tidak Tempahan, anda tidak akan menemui pengaturcara Perl. Kerana mereka tidak wujud, mereka semua telah dibawa pergi, dan mengajar mereka adalah panjang dan sukar. Jika anda mahukan pengaturcara untuk sesuatu yang lain, anda juga mungkin perlu melatih mereka semula atau mencari mereka. Dalam kes Lua, semuanya mudah. Mana-mana junior boleh belajar Lua dalam tiga hari. Saya mengambil masa kira-kira dua jam untuk memikirkannya. Dua jam kemudian saya sudah menulis kod dalam pengeluaran. Kira-kira seminggu kemudian dia terus ke produksi dan pergi.

Akibatnya, ia kelihatan seperti ini:

OpenResty: menukar NGINX menjadi pelayan aplikasi sepenuhnya

Terdapat banyak di sini. OpenResty telah mengumpul sekumpulan modul, kedua-dua luash dan enjin. Dan anda mempunyai segala-galanya sedia - digunakan dan berfungsi.

contoh

Cukup lirik, mari kita beralih kepada kod. Inilah sedikit Hello World:

OpenResty: menukar NGINX menjadi pelayan aplikasi sepenuhnya

Apa yang ada di sana? Ini ialah lokasi Engins. Kami tidak bimbang, kami tidak menulis laluan kami sendiri, kami tidak mengambil laluan yang sudah siap - kami sudah mempunyainya di NGINX, kami menjalani kehidupan yang baik dan malas.

content_by_lua_block ialah blok yang mengatakan bahawa kami menyediakan kandungan menggunakan skrip Lua. Kami mengambil pembolehubah Engins remote_addr dan masukkan ke dalam string.format. Ini sama dengan sprintf, hanya di Lua, hanya betul. Dan kami memberikannya kepada pelanggan.

Akibatnya, ia akan kelihatan seperti ini:

OpenResty: menukar NGINX menjadi pelayan aplikasi sepenuhnya

Tetapi mari kita kembali ke dunia nyata. Tiada siapa yang menggunakan Hello World untuk pengeluaran. Aplikasi kami biasanya pergi ke pangkalan data atau tempat lain dan kebanyakan masa menunggu jawapan.

OpenResty: menukar NGINX menjadi pelayan aplikasi sepenuhnya

Dia hanya duduk dan menunggu. Ia tidak begitu baik. Apabila 100.000 pengguna datang, ia sangat sukar untuk kami. Jadi mari kita gunakan aplikasi mudah sebagai contoh. Kami akan mencari gambar, sebagai contoh, kucing. Tetapi kami tidak hanya akan mencari, kami akan mengembangkan kata kunci dan, jika pengguna mencari "anak kucing," kami akan menemui kucing, kucing berbulu dan sebagainya. Pertama, kita perlu mendapatkan data permintaan pada bahagian belakang. Ia kelihatan seperti ini:

OpenResty: menukar NGINX menjadi pelayan aplikasi sepenuhnya

Dua baris membolehkan anda mengambil parameter GET, tiada komplikasi. Seterusnya, katakan, daripada pangkalan data dengan tanda untuk kata kunci dan sambungan, kami memperoleh maklumat ini menggunakan pertanyaan SQL biasa. Mudah sahaja. Ia kelihatan seperti ini:

OpenResty: menukar NGINX menjadi pelayan aplikasi sepenuhnya

Menghubungkan perpustakaan resty.mysql, yang sudah ada dalam kit. Kami tidak perlu memasang apa-apa, semuanya sudah siap. Kami menunjukkan cara menyambung dan membuat pertanyaan SQL:

OpenResty: menukar NGINX menjadi pelayan aplikasi sepenuhnya

Ia agak menakutkan di sini, tetapi semuanya berfungsi. Di sini 10 adalah had. Kami cabut 10 penyertaan, kami malas, kami tidak mahu tunjuk lebih. Saya terlupa tentang had dalam SQL.

Seterusnya kami mencari gambar untuk semua pertanyaan. Kami mengumpulkan sekumpulan permintaan dan mengisi jadual Lua yang dipanggil reqs, dan kami lakukan ngx.location.capture_multi.

OpenResty: menukar NGINX menjadi pelayan aplikasi sepenuhnya

Semua permintaan ini dihantar secara selari, dan jawapan dikembalikan kepada kami. Masa operasi adalah sama dengan masa tindak balas yang paling perlahan. Jika kami semua merakam dalam 50 milisaat, dan kami menghantar seratus permintaan, maka kami akan menerima jawapan dalam 50 milisaat.

Memandangkan kami malas dan tidak mahu menulis HTTP dan pengendalian caching, kami akan membuatkan NGINX melakukan segala-galanya untuk kami. Seperti yang anda lihat, terdapat permintaan untuk url/fetch, ini dia:

OpenResty: menukar NGINX menjadi pelayan aplikasi sepenuhnya

Kami membuatnya mudah proxy_pass, kami menunjukkan tempat untuk cache, cara melakukannya dan semuanya berfungsi untuk kami.

Tetapi ini tidak mencukupi, kami masih perlu memberikan data kepada pengguna. Idea paling mudah adalah untuk mensiri semua dalam JSON, dengan mudah, dalam dua baris. Kami memberikan Jenis Kandungan, kami memberikan JSON.

Tetapi terdapat satu kesukaran: pengguna tidak mahu membaca JSON. Kita perlu menarik pemaju hadapan. Kadang-kadang kita tidak mahu melakukan ini pada mulanya. Dan pakar SEO akan mengatakan bahawa jika kita mencari gambar, maka itu tidak penting bagi mereka. Dan jika kami memberi mereka beberapa kandungan, mereka akan mengatakan bahawa enjin carian kami tidak mengindeks apa-apa.

Apa yang perlu dilakukan mengenainya? Sudah tentu, kami akan memberikan pengguna HTML. Menjana dengan tangan bukan comme il faut, jadi kami mahu menggunakan templat. Terdapat perpustakaan untuk ini lua-resty-template.

OpenResty: menukar NGINX menjadi pelayan aplikasi sepenuhnya

Anda mungkin pernah melihat tiga huruf OPM yang menakutkan. OpenResty datang dengan pengurus pakejnya sendiri, di mana anda boleh memasang sekumpulan modul yang berbeza, khususnya, lua-resty-template. Ini ialah enjin templat mudah, serupa dengan templat Django. Di sana anda boleh menulis kod dan melakukan penggantian pembolehubah.

Akibatnya, semuanya akan kelihatan seperti ini:

OpenResty: menukar NGINX menjadi pelayan aplikasi sepenuhnya

Kami mengambil data dan memberikan templat, sekali lagi dalam dua baris. Pengguna gembira, dia menerima kucing. Oleh kerana kami memperluaskan permintaan itu, dia juga menerima anjing laut bulu untuk anak kucing. Anda tidak pernah tahu, mungkin dia sedang mencari perkara ini, tetapi tidak dapat merumuskan permintaannya dengan betul.

Semuanya bagus, tetapi kami dalam pembangunan dan tidak mahu menunjukkannya kepada pengguna lagi. Mari kita lakukan kebenaran. Untuk melakukan ini, mari lihat bagaimana NGINX mengendalikan permintaan dalam istilah OpenResty:

  • Fasa pertama - mengakses, apabila pengguna baru tiba, dan kami melihatnya dengan pengepala, alamat IP dan data lain. Kita boleh segera memotongnya jika kita tidak menyukainya. Ini boleh digunakan untuk kebenaran, atau jika kami menerima banyak permintaan, kami boleh memotongnya dengan mudah pada fasa ini.
  • menulis semula. Kami menulis semula beberapa data permintaan.
  • kandungan. Kami menghantar kandungan kepada pengguna.
  • penapis pengepala. Kami menggantikan pengepala respons. Jika kita menggunakan proxy_pass, kita boleh menulis semula beberapa tajuk sebelum memberikannya kepada pengguna.
  • penapis badan. Kita boleh mengubah badan.
  • log - pembalakan. Anda boleh menulis log dalam elasticsearch tanpa lapisan tambahan.

Keizinan kami akan kelihatan seperti ini:

OpenResty: menukar NGINX menjadi pelayan aplikasi sepenuhnya

Kami akan menambah ini kepada yang itu location, yang kami terangkan sebelum ini, dan letakkan kod berikut di sana:

OpenResty: menukar NGINX menjadi pelayan aplikasi sepenuhnya

Kami melihat untuk melihat sama ada kami mempunyai token kuki. Jika tidak, maka kami meminta kebenaran. Pengguna licik dan boleh meneka bahawa mereka perlu menetapkan token kuki. Oleh itu, kami juga akan meletakkannya di Redis:

OpenResty: menukar NGINX menjadi pelayan aplikasi sepenuhnya

Kod untuk bekerja dengan Redis adalah sangat mudah dan tidak berbeza daripada bahasa lain. Pada masa yang sama, semua input/output, di sana sini, tidak menyekat. Jika anda menulis kod segerak, ia berfungsi secara tak segerak. Hampir seperti gevent, tetapi dilakukan dengan baik.

OpenResty: menukar NGINX menjadi pelayan aplikasi sepenuhnya

Mari kita lakukan kebenaran itu sendiri:

OpenResty: menukar NGINX menjadi pelayan aplikasi sepenuhnya

Kami mengatakan bahawa kami perlu membaca kandungan permintaan itu. Kami menerima argumen POST dan menyemak sama ada log masuk dan kata laluan adalah betul. Jika ia tidak betul, maka kami mencabar anda untuk mendapatkan kebenaran. Dan jika betul, kemudian tulis token dalam Redis:

OpenResty: menukar NGINX menjadi pelayan aplikasi sepenuhnya

Jangan lupa untuk menetapkan kuki, ini juga dilakukan dalam dua baris:

OpenResty: menukar NGINX menjadi pelayan aplikasi sepenuhnya

Contohnya mudah dan spekulatif. Sudah tentu, kami tidak akan membuat perkhidmatan yang menunjukkan orang kucing. Tetapi siapa yang mengenali kita. Jadi mari kita pergi ke atas apa yang boleh dilakukan dalam pengeluaran.

  • Bahagian belakang minimalis. Kadangkala kita perlu mengeluarkan hanya sedikit data ke bahagian belakang: di suatu tempat kita perlu memasukkan tarikh, di suatu tempat kita perlu memaparkan senarai, katakan bilangan pengguna yang berada di tapak sekarang, lampirkan pembilang atau statistik. Sesuatu yang sangat kecil. Beberapa kepingan minimum boleh dibuat dengan sangat mudah. Ini akan menjadikannya cepat, mudah dan hebat.
  • Prapemprosesan data. Kadangkala kami ingin membenamkan pengiklanan ke dalam halaman kami dan kami menerima pengiklanan ini menggunakan permintaan API. Ini sangat mudah dilakukan di sini. Kami tidak memuatkan bahagian belakang kami, yang sudah duduk dan bekerja keras. Anda boleh mengambil dan mengumpulnya di sini. Kita boleh menggabungkan beberapa JS atau, sebaliknya, mencabutnya dan memproses sesuatu sebelum memberikannya kepada pengguna.
  • Fasad untuk perkhidmatan mikro. Ini juga kes yang sangat baik, saya melaksanakannya. Sebelum itu, saya bekerja di Tenzor, sebuah syarikat yang berurusan dengan pelaporan elektronik dan menyediakan pelaporan kepada kira-kira separuh daripada entiti undang-undang di negara ini. Kami mencipta perkhidmatan, banyak perkara telah dilakukan di sana menggunakan mekanisme yang sama: penghalaan, kebenaran dan banyak lagi.
    OpenResty boleh digunakan sebagai gam untuk perkhidmatan mikro anda, menyediakan akses tunggal kepada segala-galanya dan antara muka tunggal. Memandangkan perkhidmatan mikro boleh ditulis sedemikian rupa sehingga anda mempunyai Node.js di sini, PHP di sini, Python di sini, beberapa perkara Erlang di sini, kami faham bahawa kami tidak mahu menulis semula kod yang sama di mana-mana sahaja. Oleh itu, OpenResty boleh dipasang pada bahagian hadapan.

  • Statistik dan analitik. Biasanya NGINX berada di pintu masuk, dan semua permintaan melaluinya. Di tempat inilah ia sangat mudah untuk dikumpulkan. Anda boleh mengira sesuatu dengan serta-merta dan memuat naiknya ke suatu tempat, contohnya, Elasticsearch, Logstash, atau hanya menulisnya pada log dan kemudian menghantarnya ke suatu tempat.
  • Sistem berbilang pengguna. Sebagai contoh, permainan dalam talian juga sangat bagus untuk dibuat. Hari ini di Cape Town, Alexander Gladysh akan bercakap tentang cara membuat prototaip permainan berbilang pemain dengan cepat menggunakan OpenResty.
  • Permintaan Penapisan (WAF). Pada masa kini adalah bergaya untuk membuat semua jenis firewall aplikasi web; terdapat banyak perkhidmatan yang menyediakannya. Menggunakan OpenResty, anda boleh menjadikan diri anda sebagai tembok api aplikasi web yang akan menapis permintaan dengan mudah dan mudah mengikut keperluan anda. Jika anda mempunyai Python, maka anda faham bahawa PHP pasti tidak akan disuntik ke dalam anda, melainkan, sudah tentu, anda melahirkannya di mana-mana dari konsol. Anda tahu anda mempunyai MySQL dan Python. Mungkin, mereka mungkin cuba melakukan beberapa jenis traversal direktori dan menyuntik sesuatu ke dalam pangkalan data. Oleh itu, anda boleh menapis pertanyaan pelik dengan cepat dan murah di bahagian hadapan.
  • Komuniti. Memandangkan OpenResty dibina pada NGINX, ia mempunyai bonus - ini komuniti NGINX. Ia sangat besar, dan sebahagian besar soalan yang anda akan ada pada mulanya telah diselesaikan oleh komuniti NGINX.

    pemaju Lua. Semalam saya bercakap dengan lelaki yang datang ke hari latihan HighLoad++ dan mendengar bahawa hanya Tarantool ditulis dalam Lua. Ini tidak benar, banyak perkara yang ditulis dalam Lua. Contoh: OpenResty, pelayan Prosody XMPP, enjin permainan Love2D, skrip Lua dalam Warcraft dan tempat lain. Terdapat banyak pembangun Lua, mereka mempunyai komuniti yang besar dan responsif. Semua soalan Lua saya telah diselesaikan dalam masa beberapa jam. Apabila anda menulis ke senarai mel, secara literal dalam masa beberapa minit sudah ada banyak jawapan, menerangkan apa dan bagaimana, apa apa. Ia hebat. Malangnya, komuniti rohani seperti itu tidak ada di mana-mana.
    Terdapat GitHub untuk OpenResty, di mana anda boleh membuka isu jika ada yang rosak. Terdapat senarai mel di Google Kumpulan, di mana anda boleh membincangkan isu umum, terdapat senarai mel dalam bahasa Cina - anda tidak pernah tahu, mungkin anda tidak berbahasa Inggeris, tetapi anda tahu bahasa Cina.

Keputusan

  • Saya harap saya dapat menyampaikan bahawa OpenResty ialah rangka kerja yang sangat mudah disesuaikan untuk web.
  • Ia mempunyai halangan yang rendah untuk masuk, kerana kodnya serupa dengan apa yang kami tulis, bahasanya agak mudah dan minimalis.
  • Ia menyediakan I/O tak segerak tanpa panggil balik, kami tidak akan mempunyai sebarang mi seperti yang kadangkala boleh kami tulis dalam NodeJS.
  • Ia mempunyai penggunaan yang mudah, kerana kami hanya memerlukan NGINX dengan modul yang diperlukan dan kod kami, dan semuanya berfungsi serta-merta.
  • Komuniti yang besar dan responsif.

Saya tidak memberitahu secara terperinci bagaimana routing dilakukan, ternyata ia adalah cerita yang sangat panjang.

Thank you!


Vladimir Protasov - OpenResty: menukar NGINX menjadi pelayan aplikasi sepenuhnya

Sumber: www.habr.com

Tambah komen