OpenResty: NGINX толыққанды қолданбалы серверге айналдыру

OpenResty: NGINX толыққанды қолданбалы серверге айналдыруКонференция баяндамасының стенограммасын тағы да жариялап отырмыз Жоғары жүктеме++ Өткен жылдың 2016-7 қарашасында Мәскеу түбіндегі Сколковода өткен 8 ж. Владимир Протасов NGINX функциясын OpenResty және Lua көмегімен кеңейту жолын түсіндіреді.

Барлығына сәлем, менің атым Владимир Протасов, мен Parallels компаниясында жұмыс істеймін. Мен өзім туралы аздап айтып беремін. Мен өмірімнің төрттен үш бөлігін код жазуға жұмсаймын. Мен тура мағынада бағдарламашы болдым: кейде түсімде кодты көремін. Өмірдің төрттен бірі - өнеркәсіптік даму, тікелей өндіріске түсетін кодты жазу. Кейбіреулеріңіз қолданатын, бірақ оны түсінбейтін код.

Осылайша сіз оның қаншалықты жаман болғанын түсінесіз. Кішкентай кезімде маған екі терабайттық мәліметтер базасы берілді. Мұнда қазір барлығына жүктеме жоғары. Мен конференцияларға барып: «Балалар, айтыңдаршы, сізде үлкен деректер бар, бәрі жақсы ма? Сізде қанша база бар? Олар маған: «Бізде 100 гигабайт бар!» деп жауап берді. Мен: «Керемет, 100 гигабайт!» дедім. Мен өзімнің покер бетімді қалай мұқият ұстау керек деп ойладым. Сіз ойлайсыз, иә, жігіттер керемет, содан кейін сіз қайтып оралып, осы көп терабайттық деректер базасымен айналысасыз. Ал бұл кіші сынып болу. Бұл қандай соққы екенін елестете аласыз ба?

Мен 20-дан астам бағдарламалау тілдерін білемін. Бұл мен жұмыс істеген кезде түсінуім керек нәрсе болды. Олар сізге Erlang, C, C++, Lua, Python, Ruby, тағы бірдеңе код береді, және сіз бәрін қиып алуыңыз керек. Жалпы, маған тура келді. Нақты санды есептеу мүмкін болмады, бірақ 20-ға жуық жерде сан жоғалып кетті.

Қатысушының бәрі параллельдердің не екенін және не істейтінімізді білетіндіктен, мен біздің қаншалықты керемет екеніміз және не істейтініміз туралы айтпаймын. Мен сізге айта кетейін, біздің дүние жүзінде 13 кеңсеміз, 300-ден астам қызметкеріміз бар, Мәскеуде, Таллинде және Мальтада даму. Қаласаңыз, қыста суық болса және арқаңызды жылыту керек болса, оны алып, Мальтаға көшуге болады.

Нақтырақ айтсақ, біздің бөлім Python 2-де жазады. Біз бизнеспен айналысамыз және сәнді технологияларды енгізуге уақыт жоқ, сондықтан зардап шегеміз. Біз Django-ны қолданамыз, өйткені онда бәрі бар, ал қажет емес нәрсені алып тастадық. Сондай-ақ MySQL, Redis және NGINX. Бізде басқа да көптеген керемет нәрселер бар. Бізде MongoDB бар, бізде қояндар жүгіреді, бізде бәрі бар - бірақ бұл менікі емес, мен мұны істемеймін.

OpenResty

Мен өзім жайлы айттым. Бүгін мен не туралы сөйлесетінімді анықтайық:

  • OpenResty дегеніміз не және оны немен жейді?
  • Бізде Python, NodeJS, PHP, Go және барлығы риза болатын басқа да керемет нәрселер болған кезде неге басқа дөңгелекті қайта ойлап табу керек?
  • Және өмірден бірнеше мысал. Есепті көп қысқартуға тура келді, себебі бұл маған 3,5 сағатты алды, сондықтан мысалдар аз болады.

OpenResty — NGINX. Оның арқасында бізде жақсы жазылған және жылдам жұмыс істейтін толыққанды веб-сервер бар. Менің ойымша, көпшілігіміз өндірісте NGINX пайдаланамыз. Оның жылдам және салқын екенін бәріңіз білесіз. Олар онда керемет синхронды енгізу/шығару жасады, сондықтан бізге Python-да gevent жасағандай, ештеңені айналдырудың қажеті жоқ. Gevent керемет, керемет, бірақ егер сіз C кодын жазсаңыз және бірдеңе дұрыс болмаса, Gevent көмегімен сіз оны жөндеуден ада боласыз. Менде тәжірибе болды: ол жерде не болғанын анықтау үшін екі күн қажет болды. Егер біреу бірнеше апта бойы қазбалап, мәселені таппаса, Интернетте жазбаса және Google оны таппаса, біз мүлдем есінен танып қалар едік.

NGINX-те кэштеу және статикалық мазмұн бұрыннан бар. Бір жерде баяуламау үшін және бір жерде дескрипторларды жоғалтпау үшін мұны адамдық түрде қалай жасау керектігі туралы алаңдамаудың қажеті жоқ. Nginx орналастыруға өте ыңғайлы, сізге не алу керектігін ойлаудың қажеті жоқ - WSGI, PHP-FPM, Gunicorn, Unicorn. Nginx орнатылды, әкімшілерге берілді, олар онымен қалай жұмыс істеу керектігін біледі. Nginx сұрауларды құрылымдық түрде өңдейді. Мен бұл туралы сәл кейінірек айтамын. Қысқаша айтқанда, оның сұрауды жаңа ғана қабылдаған, оны өңдеген және пайдаланушыға мазмұнды берген кезі бар.

Nginx керемет, бірақ бір мәселе бар: ол конфигурациялауға болатынына қарамастан, жігіттер конфигурацияға кіргізген барлық керемет мүмкіндіктерге қарамастан, жеткілікті икемді емес. Бұл күш жеткіліксіз. Сол себепті Таобао жігіттері баяғыда, сегіз жыл бұрын Луаны салған сияқты. Ол не береді?

  • мөлшері. Ол кішкентай. LuaJIT шамамен 100-200 килобайт жадты және ең аз өнімділікті береді.
  • Жылдамдық. LuaJIT интерпретаторы көптеген жағдайларда C тіліне жақын, кейбір жағдайларда ол Java-дан жеңіледі, басқаларында ол одан асып түседі. Біраз уақыт бойы ол ең керемет JIT компиляторы болып саналды. Енді салқындары бар, бірақ олар өте ауыр, мысалы, бірдей V8. Кейбір JS аудармашылары мен Java HotSpot кейбір нүктелерде жылдамырақ, бірақ кейбір жерлерде олар әлі де жоғалады.
  • Үйрену оңай. Егер сізде, айталық, Perl код базасы болса және сіз брондау жасамасаңыз, Perl бағдарламашыларын таба алмайсыз. Олар жоқ болғандықтан, олардың барлығы алынып тасталды және оларды оқыту ұзақ және қиын. Бағдарламашыларды басқа нәрсе үшін алғыңыз келсе, сізге оларды қайта даярлау немесе табу қажет болуы мүмкін. Луа жағдайында бәрі қарапайым. Кез келген кіші Луаны үш күнде үйрене алады. Оны анықтауға екі сағаттай уақыт кетті. Екі сағаттан кейін мен өндірісте код жазып жатырмын. Арада бір апта өткенде ол тікелей өндіріске кіріп кетті.

Нәтижесінде келесідей көрінеді:

OpenResty: NGINX толыққанды қолданбалы серверге айналдыру

Мұнда көп. OpenResty luash және қозғалтқыш модульдерінің жиынтығын жинады. Сізде барлығы дайын - орналастырылған және жұмыс істеуде.

мысалдар

Ән мәтіні жеткілікті, кодқа көшейік. Міне, сәлем әлемі:

OpenResty: NGINX толыққанды қолданбалы серверге айналдыру

Онда не бар? Бұл Engins орналасқан жер. Біз алаңдамаймыз, өз маршрутымызды жазбаймыз, дайынын алмаймыз - бізде ол NGINX-те бар, біз жақсы және жалқау өмір сүреміз.

content_by_lua_block - бұл Lua сценарийі арқылы мазмұнға қызмет көрсететінімізді көрсететін блок. Біз Engins айнымалысын аламыз remote_addr және оны салыңыз string.format. Бұл бірдей sprintf, тек Луада, тек дұрыс. Ал біз оны клиентке береміз.

Нәтижесінде ол келесідей болады:

OpenResty: NGINX толыққанды қолданбалы серверге айналдыру

Бірақ нақты әлемге оралайық. Hello World қолданбасын өндіріске ешкім қолданбайды. Біздің қолданба әдетте дерекқорға немесе басқа жерге барады және көп жағдайда жауап күтеді.

OpenResty: NGINX толыққанды қолданбалы серверге айналдыру

Ол жай ғана отырады және күтеді. Бұл өте жақсы емес. 100.000 XNUMX қолданушы келгенде біз үшін өте қиын. Сондықтан мысал ретінде қарапайым қолданбаны қолданайық. Біз суреттерді іздейміз, мысалы, мысықтар. Бірақ біз жай ғана іздемейміз, кілт сөздерді кеңейтеміз және егер пайдаланушы «котята» деп іздесе, біз мысықтарды, жүнді мысықтарды және т.б. табамыз. Біріншіден, сұрау деректерін серверде алуымыз керек. Бұл келесідей көрінеді:

OpenResty: NGINX толыққанды қолданбалы серверге айналдыру

Екі жол GET параметрлерін алуға мүмкіндік береді, ешқандай қиындықтар жоқ. Әрі қарай, кілт сөз бен кеңейтімге арналған белгісі бар дерекқордан біз бұл ақпаратты әдеттегі SQL сұрауы арқылы аламыз делік. Бәрі оңай. Бұл келесідей көрінеді:

OpenResty: NGINX толыққанды қолданбалы серверге айналдыру

Кітапхананы қосу resty.mysql, ол бізде жинақта бар. Бізге ештеңе орнатудың қажеті жоқ, бәрі дайын. Біз SQL сұрауын қалай қосу және жасау керектігін көрсетеміз:

OpenResty: NGINX толыққанды қолданбалы серверге айналдыру

Бұл жерде аздап қорқынышты, бірақ бәрі жұмыс істейді. Мұнда 10 - шек. Біз 10 жазбаны шығарамыз, біз жалқаумыз, көбірек көрсеткіміз келмейді. Мен SQL-дегі шектеу туралы ұмытып кеттім.

Әрі қарай біз барлық сұрауларға арналған суреттерді табамыз. Біз көптеген сұраныстарды жинап, Луа деп аталатын кестені толтырамыз reqs, және біз жасаймыз ngx.location.capture_multi.

OpenResty: NGINX толыққанды қолданбалы серверге айналдыру

Барлық осы сұраулар параллель түрде жіберіледі және жауаптар бізге қайтарылады. Жұмыс уақыты ең баяуының жауап беру уақытына тең. Егер бәріміз 50 миллисекундта түсіріп, жүз сұрау жіберсек, 50 миллисекундта жауап аламыз.

Біз жалқау болғандықтан және HTTP және кэштеуді жазуды қаламайтындықтан, біз NGINX-ті біз үшін бәрін жасауға мәжбүр етеміз. Көріп отырғаныңыздай, сұраныс болды url/fetch, Мінеки:

OpenResty: NGINX толыққанды қолданбалы серверге айналдыру

Біз оны қарапайым етеміз proxy_pass, біз қай жерде кэштеу керектігін, оны қалай жасау керектігін көрсетеміз және бәрі біз үшін жұмыс істейді.

Бірақ бұл жеткіліксіз, біз әлі де пайдаланушыға деректерді беруіміз керек. Ең қарапайым идея - JSON ішіндегі барлығын оңай, екі жолға сериялау. Біз Content-Type береміз, JSON береміз.

Бірақ бір қиындық бар: пайдаланушы JSON оқығысы келмейді. Біз алдыңғы қатарлы әзірлеушілерді тартуымыз керек. Кейде біз алдымен мұны істегіміз келмейді. SEO мамандары егер біз суреттерді іздейтін болсақ, олар үшін бұл маңызды емес екенін айтады. Егер біз оларға кейбір мазмұнды берсек, олар біздің іздеу жүйелері ештеңені индекстемейтінін айтады.

Бұл туралы не істеу керек? Әрине, біз пайдаланушыға HTML береміз. Қолмен жасау comme il faut емес, сондықтан біз үлгілерді пайдаланғымыз келеді. Бұл үшін кітапхана бар lua-resty-template.

OpenResty: NGINX толыққанды қолданбалы серверге айналдыру

Сіз OPM деген үш қорқынышты әріпті көрген шығарсыз. OpenResty өзінің пакет менеджерімен бірге жеткізіледі, ол арқылы сіз әртүрлі модульдердің жиынтығын орнатуға болады, атап айтқанда, lua-resty-template. Бұл Django үлгілеріне ұқсас қарапайым үлгі қозғалтқышы. Онда кодты жазуға және айнымалы ауыстыруды орындауға болады.

Нәтижесінде бәрі келесідей болады:

OpenResty: NGINX толыққанды қолданбалы серверге айналдыру

Біз деректерді алып, шаблонды қайтадан екі жолға шығардық. Пайдаланушы бақытты, ол мысықтарды алды. Біз сұранысты кеңейткендіктен, ол котят үшін аң терісін де алды. Сіз ешқашан білмейсіз, мүмкін ол дәл осыны іздеген шығар, бірақ өз өтінішін дұрыс тұжырымдай алмады.

Барлығы тамаша, бірақ біз әзірлеу үстіндеміз және оны әлі пайдаланушыларға көрсеткіміз келмейді. Рұқсат берейік. Мұны істеу үшін NGINX сұрауды OpenResty шарттарында қалай өңдейтінін қарастырайық:

  • Бірінші кезең - қол, пайдаланушы жаңа келген кезде және біз оған тақырыптар, IP мекенжайы және басқа деректер бойынша қарадық. Біз оны ұнатпайтын болсақ, оны бірден кесіп тастай аламыз. Бұл авторизация үшін пайдаланылуы мүмкін немесе егер біз көп сұраулар алсақ, біз оларды осы кезеңде оңай кесіп тастай аламыз.
  • қайта жазыңыз. Кейбір сұрау деректерін қайта жазамыз.
  • мазмұны. Біз пайдаланушыға мазмұнды жеткіземіз.
  • тақырыптар сүзгісі. Жауап тақырыптарын ауыстырамыз. Егер біз пайдалансақ proxy_pass, біз кейбір тақырыптарды пайдаланушыға бермес бұрын қайта жаза аламыз.
  • дене сүзгісі. Біз денені өзгерте аламыз.
  • журнал — ағаш кесу. Сіз журналдарды elasticsearch қолданбасында қосымша қабатсыз жаза аласыз.

Біздің рұқсатымыз келесідей болады:

OpenResty: NGINX толыққанды қолданбалы серверге айналдыру

Мұны оған қосамыз location, біз бұрын сипаттаған және сол жерге келесі кодты қойыңыз:

OpenResty: NGINX толыққанды қолданбалы серверге айналдыру

Бізде печенье белгісі бар-жоғын іздейміз. Егер жоқ болса, біз рұқсат сұраймыз. Пайдаланушылар айлакер және олар cookie таңбалауышын орнату керек деп болжауы мүмкін. Сондықтан біз оны Redis-ке де қоямыз:

OpenResty: NGINX толыққанды қолданбалы серверге айналдыру

Redis-пен жұмыс істеу коды өте қарапайым және басқа тілдерден еш айырмашылығы жоқ. Сонымен қатар, мұнда және мұнда барлық кіріс/шығыс блокталмайды. Синхронды код жазсаңыз, ол асинхронды түрде жұмыс істейді. Gevent сияқты дерлік, бірақ жақсы орындады.

OpenResty: NGINX толыққанды қолданбалы серверге айналдыру

Авторизацияны өзі жасайық:

OpenResty: NGINX толыққанды қолданбалы серверге айналдыру

Өтініш мәтінін оқу керек дейміз. Біз POST аргументтерін аламыз және логин мен құпия сөздің дұрыстығын тексереміз. Егер олар қате болса, авторизацияға шағымданамыз. Егер дұрыс болса, Redis-те таңбалауышты жазыңыз:

OpenResty: NGINX толыққанды қолданбалы серверге айналдыру

Cookie файлын орнатуды ұмытпаңыз, бұл да екі жолда орындалады:

OpenResty: NGINX толыққанды қолданбалы серверге айналдыру

Мысал қарапайым және алыпсатарлық. Әрине, біз адамдарға мысықтарды көрсететін сервис жасамаймыз. Бірақ бізді кім біледі. Сонымен, өндірісте не істеуге болатынын қарастырайық.

  • Минималистикалық сервер. Кейде бізге деректердің аз ғана бөлігін серверге шығару керек: бір жерде күнді енгізу керек, бір жерде тізімді көрсету, сайтта қазір қанша пайдаланушы бар екенін айту, есептегішті немесе статистиканы тіркеу керек. Сондай кішкентай нәрсе. Кейбір минималды бөлшектерді өте оңай жасауға болады. Бұл оны жылдам, оңай және керемет етеді.
  • Деректерді алдын ала өңдеу. Кейде біз жарнаманы парақшамызға енгізгіміз келеді және біз бұл жарнаманы API сұраулары арқылы аламыз. Бұл жерде мұны істеу өте оңай. Біз қазірдің өзінде отырып, жұмыс істеп жатқан бэкендімізді жүктемейміз. Сіз оны осы жерден алып, жинай аласыз. Біз кейбір JS біріктіре аламыз немесе, керісінше, оны ажыратып, пайдаланушыға бермес бұрын бір нәрсені алдын ала өңдей аламыз.
  • Микросервиске арналған қасбет. Бұл да өте жақсы жағдай, мен оны жүзеге асырдым. Бұған дейін мен электронды есеп берумен айналысатын және елдегі заңды тұлғалардың жартысына жуығына есеп беретін Tenzor компаниясында жұмыс істедім. Біз қызмет жасадық, сол механизм арқылы көп нәрсе орындалды: маршруттау, авторизация және т.б.
    OpenResty микросервистеріңіз үшін желім ретінде пайдаланылуы мүмкін, ол бәріне бір қол жеткізуді және бір интерфейсті қамтамасыз етеді. Микросервистерді сізде Node.js, мұнда PHP, мұнда Python, мұнда Erlang сияқты нәрсе болатындай етіп жазуға болатындықтан, біз барлық жерде бірдей кодты қайта жазғымыз келмейтінін түсінеміз. Сондықтан OpenResty-ді алдыңғы бөлікке қосуға болады.

  • Статистика және аналитика. Әдетте NGINX кіреберісте болады және барлық сұраулар ол арқылы өтеді. Дәл осы жерде оны жинау өте ыңғайлы. Сіз бірден бір нәрсені есептеп, оны бір жерге жүктей аласыз, мысалы, Elasticsearch, Logstash немесе оны журналға жазып, содан кейін бір жерге жібере аласыз.
  • Көп қолданушы жүйелер. Мысалы, онлайн ойындарды жасау өте жақсы. Бүгін Кейптаун қаласында Александр Гладиш OpenResty көмегімен көп ойыншы ойынының прототипін қалай тез жасау керектігі туралы әңгімелейді.
  • Сұраныс сүзу (WAF). Қазіргі уақытта веб-қосымшалардың брандмауэрлерінің барлық түрлерін жасау сәнге айналды, оларды ұсынатын көптеген қызметтер бар. OpenResty көмегімен сіз өз талаптарыңызға сәйкес сұрауларды оңай және оңай сүзетін веб-бағдарлама брандмауэрін жасай аласыз. Егер сізде Python болса, онда сіз оны консольден кез келген жерде шығармасаңыз, PHP сізге міндетті түрде енгізілмейтінін түсінесіз. Сізде MySQL және Python бар екенін білесіз. Мүмкін, олар қандай да бір каталогты айналып өтуге және дерекқорға бірдеңе енгізуге тырысуы мүмкін. Сондықтан, сіз оғаш сұрауларды алдыңғы жағында тез және арзан түрде сүзуге болады.
  • Қоғамдастық. OpenResty NGINX негізінде құрылғандықтан, оның бонусы бар - бұл NGINX қауымдастығы. Бұл өте үлкен және сізде болатын сұрақтардың лайықты бөлігін NGINX қауымдастығы шешіп қойған.

    Lua әзірлеушілері. Кеше HighLoad++ жаттығу күніне келген жігіттермен сөйлесіп, Луада тек Tarantool жазылғанын естідім. Бұл дұрыс емес, Луада көп нәрсе жазылған. Мысалдар: OpenResty, Prosody XMPP сервері, Love2D ойын қозғалтқышы, Warcraft-та және басқа жерлерде жазылған Lua. Lua әзірлеушілері өте көп, олардың үлкен және жауап беретін қауымдастығы бар. Менің барлық Луа сұрақтарым бірнеше сағат ішінде шешілді. Пошталық тізімге жазған кезде, бірнеше минут ішінде не және қалай, не екенін сипаттайтын көптеген жауаптар пайда болады. Бұл тамаша. Өкінішке орай, мұндай мейірімді, рухани қауым барлық жерде бола бермейді.
    OpenResty үшін GitHub бар, онда бірдеңе бұзылған жағдайда мәселені ашуға болады. Google топтарында жалпы мәселелерді талқылауға болатын тарату тізімі бар, қытай тілінде жіберу тізімі бар - сіз ешқашан білмейсіз, мүмкін сіз ағылшын тілін білмейсіз, бірақ сіз қытай тілін білесіз.

Нәтижелері

  • Мен OpenResty вебке арналған өте ыңғайлы құрылым екенін жеткізе алдым деп үміттенемін.
  • Оның кіруге кедергісі төмен, өйткені код біз жазғанға ұқсас, тіл өте қарапайым және минималистік.
  • Ол кері қоңырауларсыз асинхронды енгізу/шығаруды қамтамасыз етеді, бізде кейде NodeJS-де жаза алатындай кеспе болмайды.
  • Оны орналастыру оңай, өйткені бізге тек қажетті модуль және кодымыз бар NGINX қажет және бәрі бірден жұмыс істейді.
  • Үлкен және жауап беретін қауымдастық.

Маршрутизация қалай жасалатынын егжей-тегжейлі айтқан жоқпын, бұл өте ұзақ әңгіме болып шықты.

Назарларыңызға рахмет!


Владимир Протасов - OpenResty: NGINX толыққанды қолданбалы серверге айналдыру

Ақпарат көзі: www.habr.com

пікір қалдыру