OpenResty: NGINX'i tam teşekküllü bir uygulama sunucusuna dönüştürmek

OpenResty: NGINX'i tam teşekküllü bir uygulama sunucusuna dönüştürmekKonferansın raporunun transkriptini yeniden yayınlıyoruz Yüksek Yük++ Geçen yıl 2016-7 Kasım tarihlerinde Moskova yakınlarındaki Skolkovo'da düzenlenen 8. Vladimir Protasov NGINX işlevselliğinin OpenResty ve Lua ile nasıl genişletileceğini anlatır.

Herkese merhaba, benim adım Vladimir Protasov, Parallels için çalışıyorum. Size biraz kendimden bahsedeceğim. Hayatımın dörtte üçünü kod yazarak geçiriyorum. Kelimenin tam anlamıyla çekirdek bir programcı oldum: Bazen rüyalarımda kod görüyorum. Yaşamın dörtte biri, doğrudan üretime giden kod yazmak olan endüstriyel gelişmedir. Bazılarınızın kullandığı ama bilmediği kod.

Ne kadar kötü olduğunu bilmen için. Küçükken içeri girdim ve bana bu iki terabayt veri tabanını verdiler. Artık herkes için yüksek yük burada. Konferanslara gittim ve sordum: “Beyler, söyleyin bana, büyük verileriniz var mı, her şey yolunda mı? Orada kaç üssünüz var? Bana cevap verdiler: "100 gigabaytımız var!" "Harika, 100 gigabayt!" dedim. Ve kendi kendime poker suratını düzgün bir şekilde nasıl kurtaracağımı düşündüm. Evet, adamların harika olduğunu düşünüyorsunuz ve sonra geri dönüp bu çok terabaytlık veritabanlarıyla uğraşıyorsunuz. Ve bu genç olmak. Nasıl bir vuruş olduğunu hayal edebiliyor musunuz?

20'den fazla programlama dili biliyorum. Çalışma sırasında çözmem gereken şey buydu. Size Erlang'da, C'de, C++'da, Lua'da, Python'da, Ruby'de, başka bir şeyde kod veriyorlar ve hepsini kesmeniz gerekiyor. Genel olarak yapmak zorundaydım. Kesin sayıyı hesaplamak mümkün değildi, ancak 20 civarında bir yerde sayı kayboldu.

Buradaki herkes Parallels'in ne olduğunu ve ne yaptığımızı bildiği için ne kadar havalı olduğumuzdan ve ne yaptığımızdan bahsetmeyeceğim. Size sadece dünya çapında 13 ofisimiz, 300'den fazla çalışanımız, Moskova, Tallinn ve Malta'da gelişimimiz olduğunu söyleyeceğim. Dilerseniz, kışın soğuksa ve sırtınızı ısıtmanız gerekiyorsa, Malta'ya alıp hareket edebilirsiniz.

Bölümümüz özellikle Python 2'de yazıyor. İş içindeyiz ve modaya uygun teknolojileri tanıtacak vaktimiz yok, bu yüzden acı çekiyoruz. Django'ya sahibiz çünkü her şeye sahip ve fazlalığı alıp çöpe attık. Ayrıca MySQL, Redis ve NGINX. Ayrıca başka birçok harika şeyimiz var. MongoDB'miz var, etrafta koşturan tavşanlarımız var, hiçbir şeyimiz yok - ama bu benim değil ve ben yapmıyorum.

AçıkResty

kendimden bahsettim Bakalım bugün nelerden bahsedeceğim:

  • OpenResty nedir ve ne ile yenir?
  • Python, NodeJS, PHP, Go ve herkesin memnun olduğu diğer harika şeyler varken neden tekerleği yeniden icat edelim?
  • Ve birkaç gerçek hayat örneği. Raporu çok kısa kesmek zorunda kaldım, çünkü 3,5 saate aldım, bu yüzden birkaç örnek olacak.

OpenResty, NGINX'tir. Onun sayesinde, iyi yazılmış, hızlı çalışan tam teşekküllü bir web sunucumuz var. Sanırım çoğumuz üretimde NGINX kullanıyoruz. Hepiniz onun hızlı ve havalı olduğunu biliyorsunuz. İçinde harika senkronize G / Ç yaptılar, bu nedenle Python'da gevent'in çevrildiği şekilde hiçbir şeyi döngülememize gerek yok. Gevent harika, harika ama C-kodu yazarsanız ve gevent ile ilgili bir şeyler ters giderse, hata ayıklamak için çıldırırsınız. Deneyimim vardı: Orada neyin yanlış gittiğini anlamak iki koca günümü aldı. Birisi birkaç hafta önce kazmasaydı, sorunu bulup internette yazmasaydı ve Google da bulmasaydı, o zaman tamamen çıldırırdık.

NGINX zaten önbelleğe alma ve statik içerik yapıyor. Bir yerde yavaşlamamak, bir yerde tanımlayıcıları kaybetmemek için bunu insanca nasıl yapacağınız konusunda endişelenmenize gerek yok. Nginx'in konuşlandırılması çok uygundur, ne alacağınızı düşünmenize gerek yoktur - WSGI, PHP-FPM, Gunicorn, Unicorn. Nginx kuruldu, yöneticilere verildi, onunla nasıl çalışacaklarını biliyorlar. Nginx, istekleri yapılandırılmış bir şekilde işler. Bundan biraz sonra bahsedeceğim. Kısaca isteği henüz kabul ettiği, işleme aldığı ve içeriği kullanıcıya verdiği bir evresi var.

Nginx harika, ancak bir sorun var: Özelleştirilebilir olmasına rağmen, adamların yapılandırmaya ittiği tüm bu harika özelliklerle bile yeterince esnek değil. Bu güç yeterli değil. Bu nedenle, Taobao'daki adamlar bir zamanlar, sanırım yaklaşık sekiz yıl önce, Lua'yı buraya yerleştirdiler. Ne veriyor?

  • boyut. Bu küçük. LuaJIT, yaklaşık 100-200 kilobayt bellek ek yükü ve minimum performans ek yükü sağlar.
  • hız. LuaJIT tercümanı birçok durumda C'ye yakındır, bazı durumlarda Java'ya kaybeder, bazılarında onu geçer. Bir süre, son teknoloji, en havalı JIT derleyicisi olarak kabul edildi. Şimdi daha havalı olanlar var ama çok ağırlar, örneğin aynı V8. Bazı JS tercümanları ve Java HotSpot bazı noktalarda daha hızlıdır, ancak yine de bazı noktalarda kaybederler.
  • Öğrenmesi kolay. Diyelim ki bir Perl kod tabanınız varsa ve Booking değilseniz, Perl programcılarını bulamazsınız. Orada olmadıkları için hepsi götürüldü ve onlara öğretmek uzun ve zor. Programcıları başka bir şey için istiyorsanız, yeniden eğitilmeleri veya bulunmaları gerekebilir. Lua söz konusu olduğunda her şey basit. Lua, herhangi bir genç tarafından üç günde öğrenilebilir. Bunu anlamam yaklaşık iki saatimi aldı. İki saat sonra, zaten üretimde kod yazıyordum. Yaklaşık bir hafta sonra doğrudan üretime geçti ve ayrıldı.

Sonuç olarak, şöyle görünür:

OpenResty: NGINX'i tam teşekküllü bir uygulama sunucusuna dönüştürmek

Burada çok şey var. OpenResty, hem luash hem de engin olmak üzere bir grup modül bir araya getirdi. Ve her şey hazır - dağıtılmış ve çalışıyor.

Örnekler

Sözler bu kadar yeter, koda geçelim. İşte küçük bir Merhaba Dünya:

OpenResty: NGINX'i tam teşekküllü bir uygulama sunucusuna dönüştürmek

Oradaki ne? burası motorların yeri. Endişelenmiyoruz, kendi yönlendirmemizi yazmıyoruz, hazır bir tane almıyoruz - zaten NGINX'te var, iyi ve tembel yaşıyoruz.

content_by_lua_block Lua komut dosyası kullanarak içerik sunduğumuzu söyleyen bir bloktur. Bir motor değişkeni alıyoruz remote_addr ve içine kaydır string.format. Bu aynı sprintf, yalnızca Lua'da, yalnızca doğru. Ve müşteriye veriyoruz.

Sonuç olarak, şöyle görünecektir:

OpenResty: NGINX'i tam teşekküllü bir uygulama sunucusuna dönüştürmek

Ama gerçek dünyaya geri dönelim. Üretimde hiç kimse Hello World konuşlandırmıyor. Uygulamamız genellikle veri tabanına veya başka bir yere gider ve çoğu zaman yanıt bekler.

OpenResty: NGINX'i tam teşekküllü bir uygulama sunucusuna dönüştürmek

Sadece oturur ve bekler. Bu hiç iyi değil. 100.000 kullanıcı geldiğinde işimiz çok zor. Bu nedenle örnek olarak basit bir uygulama kullanalım. Resimler arayacağız, örneğin kediler. Sadece arama yapmayacağız, anahtar kelimeleri genişleteceğiz ve kullanıcı "yavru kedi" için arama yaparsa kediler, tüyler vb. Öncelikle arka uçtaki istek verilerini almamız gerekiyor. Şuna benziyor:

OpenResty: NGINX'i tam teşekküllü bir uygulama sunucusuna dönüştürmek

İki satır, GET parametrelerini almanızı sağlar, herhangi bir komplikasyon yoktur. Daha sonra, örneğin, bu bilgiyi, normal bir SQL sorgusu kullanarak anahtar kelimeye ve uzantıya göre bir tablo içeren bir veritabanından alırız. Her şey basit. Şuna benziyor:

OpenResty: NGINX'i tam teşekküllü bir uygulama sunucusuna dönüştürmek

Kütüphaneyi bağlarız resty.mysql, kitte zaten var. Hiçbir şey yüklememize gerek yok, her şey hazır. Nasıl bağlanılacağını ve bir SQL sorgusu oluşturulacağını belirtin:

OpenResty: NGINX'i tam teşekküllü bir uygulama sunucusuna dönüştürmek

Biraz korkutucu ama işe yarıyor. Burada 10 sınırdır. 10 plak çıkardık, tembeliz, daha fazlasını göstermek istemiyoruz. SQL'de limiti unuttum.

Ardından tüm sorgular için görseller buluyoruz. Bir sürü istek topluyoruz ve adlı bir Lua tablosu dolduruyoruz. reqs, ve yap ngx.location.capture_multi.

OpenResty: NGINX'i tam teşekküllü bir uygulama sunucusuna dönüştürmek

Tüm bu talepler paralel gidiyor ve cevaplar bize geri dönüyor. Çalışma süresi, en yavaş olanın tepki süresine eşittir. Hepimiz 50 milisaniyede geri ateş edersek ve yüz istek gönderirsek, o zaman 50 milisaniyede yanıt alırız.

Tembel olduğumuz ve HTTP işleme ve önbelleğe alma yazmak istemediğimiz için, NGINX'in bizim için her şeyi yapmasını sağlayacağız. Gördüğünüz gibi, bir istek vardı. url/fetchişte burada:

OpenResty: NGINX'i tam teşekküllü bir uygulama sunucusuna dönüştürmek

basitleştiriyoruz proxy_pass, nerede önbelleğe alınacağını, nasıl yapılacağını belirtin ve her şey bizim için çalışıyor.

Ancak bu yeterli değil, yine de kullanıcıya verileri vermemiz gerekiyor. En basit fikir, her şeyi iki satırda kolayca JSON'a seri hale getirmektir. Content-Type veriyoruz, JSON veriyoruz.

Ancak bir zorluk var: kullanıcı JSON'u okumak istemiyor. Ön uç geliştiricileri çekmemiz gerekiyor. Bazen ilk başta yapmak istemiyoruz. Evet ve SEO uzmanları, resimler arıyorsak umursamadıklarını söyleyecekler. Ve onlara biraz içerik verirsek, arama motorlarımızın hiçbir şeyi indekslemediğini söyleyecekler.

Bununla ne yapmalı? Elbette kullanıcıya HTML vereceğiz. Tanıtıcılarla oluşturmak kolay değildir, bu nedenle şablonlar kullanmak istiyoruz. Bunun için bir kütüphane var lua-resty-template.

OpenResty: NGINX'i tam teşekküllü bir uygulama sunucusuna dönüştürmek

Üç korkunç harf OPM'yi görmüş olmalısınız. OpenResty, özellikle bir dizi farklı modül kurabileceğiniz kendi paket yöneticisi ile birlikte gelir. lua-resty-template. Django şablonlarına benzeyen basit bir şablon motorudur. Orada kod yazabilir ve değişken değiştirme yapabilirsiniz.

Sonuç olarak, her şey şöyle görünecek:

OpenResty: NGINX'i tam teşekküllü bir uygulama sunucusuna dönüştürmek

Verileri aldık ve şablonu iki satırda yeniden oluşturduk. Kullanıcı mutlu, kedileri var. Talebi genişlettiğimiz için kedi yavruları için bir kürklü fok da aldı. Bilemezsin, belki arıyordu ama isteğini doğru formüle edemiyordu.

Her şey harika, ancak geliştirme aşamasındayız ve henüz kullanıcılara göstermek istemiyoruz. Bir yetkilendirme yapalım. Bunu yapmak için, NGINX'in isteği OpenResty açısından nasıl ele aldığını görelim:

  • İlk etap - erişim, kullanıcı yeni geldiğinde ve ona başlıklara, IP adresine, diğer verilere göre baktık. Beğenmezsek hemen kesebilirsiniz. Bu, yetkilendirme için kullanılabilir veya çok fazla istek alırsak, bu aşamada onları kolayca kesebiliriz.
  • yeniden yazmak. Bazı istek verilerinin yeniden yazılması.
  • içerik. Kullanıcıya içerik veriyoruz.
  • başlık filtresi. Yanıt başlıklarını değiştirin. eğer kullandıysak proxy_pass, kullanıcıya vermeden önce bazı başlıkları yeniden yazabiliriz.
  • vücut filtresi. Bedeni değiştirebiliriz.
  • log - Kerestecilik. Elasticsearch'te günlükleri ek bir katman olmadan yazmak mümkündür.

Yetkilendirmemiz şuna benzer:

OpenResty: NGINX'i tam teşekküllü bir uygulama sunucusuna dönüştürmek

onuda ekleyeceğiz location, daha önce tanımladığımız ve oraya aşağıdaki kodu koyun:

OpenResty: NGINX'i tam teşekküllü bir uygulama sunucusuna dönüştürmek

Çerez jetonumuz olup olmadığına bakarız. Olmazsa, yetkilendirme yaparız. Kullanıcılar kurnazdır ve bir çerez belirtecinin ayarlanması gerektiğini tahmin edebilir. Bu nedenle Redis'e de koyacağız:

OpenResty: NGINX'i tam teşekküllü bir uygulama sunucusuna dönüştürmek

Redis ile çalışma kodu çok basittir ve diğer dillerden hiçbir farkı yoktur. Aynı zamanda tüm giriş/çıkışlar, ne var, ne burada, bloke etmiyor. Eşzamanlı kod yazarsanız, eşzamansız çalışır. Gevent'te olduğu gibi, sadece iyi yapılmış.

OpenResty: NGINX'i tam teşekküllü bir uygulama sunucusuna dönüştürmek

Yetkilendirmeyi kendisi yapalım:

OpenResty: NGINX'i tam teşekküllü bir uygulama sunucusuna dönüştürmek

İstek gövdesini okumamız gerektiğini söylüyoruz. POST bağımsız değişkenleri alıyoruz, kullanıcı adı ve parolanın doğru olup olmadığını kontrol edin. Yanlışsa, yetkilendirme yaparız. Ve eğer doğruysa, belirteci Redis'e yazarız:

OpenResty: NGINX'i tam teşekküllü bir uygulama sunucusuna dönüştürmek

Çerezi ayarlamayı unutmayın, bu da iki satırda yapılır:

OpenResty: NGINX'i tam teşekküllü bir uygulama sunucusuna dönüştürmek

Örnek basit, spekülatif. Tabii ki insanlara kedi gösteren bir servis yapmayacağız. Ama bizi kim bilir. O halde üretimde neler yapılabileceğine bir göz atalım.

  • Minimalist arka uç. Bazen arka uca oldukça fazla veri vermemiz gerekir: bir yerde tarihi değiştirmemiz gerekir, bir yerde bir tür liste görüntülememiz gerekir, örneğin şu anda sitede kaç kullanıcı var, bir sayacı veya istatistikleri vidalayın. Çok küçük bir şey. Bazı minimal parçalar çok kolay yapılabilir. Bu hızlı, kolay ve harika olacak.
  • Veri ön işleme. Bazen sayfamıza reklam yerleştirmek istiyoruz ve bu reklamları API istekleri ile alıyoruz. Bunu burada yapmak çok kolay. Zaten çok çalışan arka ucumuzu yüklemiyoruz. Buradan alabilir ve toplayabilirsiniz. Bazı JS'leri şekillendirebiliriz veya tam tersine, bir şeyi kullanıcıya vermeden önce önceden işleyebiliriz.
  • Mikro hizmet için cephe. Bu da çok güzel bir durum, uyguladım. Ondan önce, ülkedeki tüzel kişilerin yaklaşık yarısına raporlama sağlayan bir elektronik raporlama şirketi olan Tenzor'da çalıştım. Bir hizmet yaptık, orada aynı mekanizma kullanılarak birçok şey yapılıyor: yönlendirme, yetkilendirme ve daha fazlası.
    OpenResty, her şeye tek bir erişim ve tek bir arabirim sağlamak için mikro hizmetleriniz için yapıştırıcı olarak kullanılabilir. Mikro hizmetler öyle bir şekilde yazılabilir ki burada Node.js var, burada PHP var, burada Python var, burada biraz Erlang olayı var, anlıyoruz ki aynı kodu her yere yeniden yazmak istemiyoruz. Bu nedenle, OpenResty öne takılabilir.
  • İstatistik ve analitik. Genellikle NGINX giriştedir ve tüm istekler buradan geçer. Bu yerde toplamak çok uygun. Hemen bir şeyi hesaplayabilir ve bir yere, örneğin aynı Elasticsearch, Logstash'a atabilir veya sadece günlüğe yazıp bir yere gönderebilirsiniz.
  • Çok Kullanıcılı Sistemler. Örneğin, çevrimiçi oyunlar yapmak da çok iyidir. Bugün Cape Town'da Alexander Gladysh size OpenResty kullanarak çok oyunculu bir oyunun prototipini nasıl hızlı bir şekilde yapabileceğinizi anlatacak.
  • Talep Filtreleme (WAF). Artık her türlü web uygulaması güvenlik duvarı yapmak moda oldu, bunları sağlayan birçok hizmet var. OpenResty'nin yardımıyla kendinize, gereksinimlerinize göre istekleri basit ve kolay bir şekilde filtreleyen bir web uygulaması güvenlik duvarı oluşturabilirsiniz. Python'a sahipseniz, konsoldan herhangi bir yerde oluşturmadığınız sürece PHP'nin size kesinlikle enjekte edilmeyeceğini anlarsınız. MySQL ve Python'a sahip olduğunuzu biliyorsunuz. Muhtemelen, burada bir tür dizin geçişi yapmayı deneyebilir ve veritabanına bir şey enjekte edebilirler. Bu nedenle, aptal istekleri hemen ön tarafta hızlı ve ucuz bir şekilde filtreleyebilirsiniz.
  • Topluluk. OpenResty, NGINX tabanlı olduğundan, bir bonusu vardır - bu NGINX topluluğu. Çok büyük ve ilk başta soracağınız soruların çoğu NGINX topluluğu tarafından zaten yanıtlanmış durumda.

    Lua geliştiricileri. Dün HighLoad ++ eğitim gününe gelen adamlarla konuştum ve Lua'da sadece Tarantool yazıldığını duydum. Bu öyle değil, Lua'da çok şey yazılıyor. Örnekler: OpenResty, Prosody XMPP sunucusu, Love2D oyun motoru, Lua, Warcraft ve başka yerlerde komut dosyası olarak yazılmıştır. Çok sayıda Lua geliştiricisi var, geniş ve duyarlı bir topluluğa sahipler. Lua ile ilgili tüm sorularım birkaç saat içinde yanıtlandı. Posta listesine yazdığınızda, kelimenin tam anlamıyla birkaç dakika içinde zaten bir sürü cevap var, neyin ve nasıl, neyin ne olduğunu açıklıyorlar. Bu harika. Ne yazık ki, böyle nazik bir samimi topluluk her yerde değil.
    OpenResty'de, bir şey bozulursa sorunu açabileceğiniz GitHub vardır. Google Grupları'nda genel konuları tartışabileceğiniz bir posta listesi var, Çince bir posta listesi var - asla bilemezsiniz, belki İngilizce bilmiyorsunuz ama Çince bilginiz var.

sonuçlar

  • Umarım OpenResty'nin çok kullanışlı bir web framework olduğunu aktarabilmişimdir.
  • Düşük bir giriş eşiğine sahiptir, kod bizim yazdığımıza benzer olduğu için dili oldukça basit ve minimalisttir.
  • Geri aramalar olmadan eşzamansız G/Ç sağlar, bazen NodeJS'de yazabileceğimiz için erişte olmaz.
  • Kurulumu kolaydır, çünkü yalnızca doğru modül ve kodumuzla NGINX'e ihtiyacımız vardır ve her şey hemen çalışır.
  • Büyük ve duyarlı topluluk.

Yönlendirmenin nasıl yapıldığını ayrıntılı olarak anlatmadım, çok uzun bir hikaye olduğu ortaya çıktı.

Teşekkürler!

Oynat Video

Vladimir Protasov - OpenResty: NGINX'i tam teşekküllü bir uygulama sunucusuna dönüştürmek

Kaynak: habr.com

Yorum ekle