OpenResty: تبدیل NGINX به یک سرور برنامه کامل

OpenResty: تبدیل NGINX به یک سرور برنامه کاملما دوباره متن گزارش کنفرانس را منتشر می کنیم HighLoad++ 2016، که در Skolkovo در نزدیکی مسکو در 7-8 نوامبر سال گذشته برگزار شد. ولادیمیر پروتاسوف نحوه گسترش عملکرد NGINX با OpenResty و Lua را توضیح می دهد.

سلام به همه، نام من ولادیمیر پروتاسوف است، من در Parallels کار می کنم. من کمی از خودم برایتان می گویم. سه چهارم عمرم را صرف نوشتن کد می کنم. من به معنای واقعی کلمه یک برنامه نویس شدم: گاهی اوقات در رویاهایم کد می بینم. یک چهارم عمر توسعه صنعتی است، نوشتن کدی که مستقیماً وارد تولید می شود. کدی که برخی از شما از آن استفاده می کنید اما متوجه آن نمی شوید.

پس میفهمی چقدر بد بود وقتی کمی کوچکتر بودم، آمدم و این بانک های اطلاعاتی دو ترابایتی را به من دادند. اکنون اینجا برای همه زیاد است. به کنفرانس‌ها رفتم و پرسیدم: «بچه‌ها، به من بگویید، شما داده‌های بزرگی دارید، آیا همه چیز عالی است؟ چند تا پایگاه داری اونجا؟ آنها به من پاسخ دادند: "ما 100 گیگابایت داریم!" گفتم: "باحال، 100 گیگ!" و من با خودم فکر می کردم که چگونه چهره پوکر خود را با دقت حفظ کنم. شما فکر می کنید، بله، بچه ها باحال هستند، و سپس به عقب برگردید و با این پایگاه داده های چند ترابایتی سر و کله بزنید. و این جونیور بودن است. می توانید تصور کنید این چه ضربه ای است؟

من بیش از 20 زبان برنامه نویسی بلدم. این چیزی است که من باید در حین کار به آن پی می بردم. آنها به شما کدهایی به زبان های Erlang، C، C++، Lua، Python، Ruby و چیز دیگری می دهند و شما باید همه آن را برش دهید. در کل مجبور بودم. نمی شد عدد دقیق را محاسبه کرد، اما در حدود بیستم این عدد گم شد.

از آنجایی که همه حاضران می دانند که Parallels چیست و ما چه کار می کنیم، در مورد اینکه چقدر خوب هستیم و چه کار می کنیم صحبت نمی کنم. من فقط به شما می گویم که ما 13 دفتر در سراسر جهان، بیش از 300 کارمند، توسعه در مسکو، تالین و مالت داریم. در صورت تمایل، اگر در زمستان سرد است و نیاز به گرم کردن پشت خود دارید، می توانید آن را بردارید و به مالت بروید.

به طور خاص، بخش ما در پایتون 2 می نویسد. ما در تجارت هستیم و زمانی برای پیاده سازی فناوری های مد روز نداریم، بنابراین رنج می بریم. ما از جنگو استفاده می کنیم زیرا همه چیز دارد و چیزهای غیر ضروری را برداشتیم و دور انداختیم. همچنین MySQL، Redis و NGINX. ما خیلی چیزهای جالب دیگه هم داریم. ما MongoDB داریم، خرگوش‌هایی داریم که دور و بر می‌دوند، همه چیز داریم - اما این مال من نیست و من این کار را نمی‌کنم.

OpenResty

از خودم گفتم بیایید بفهمیم که امروز در مورد چه چیزی صحبت خواهم کرد:

  • OpenResty چیست و با چه چیزی خورده می شود؟
  • چرا وقتی پایتون، نود جی اس، پی اچ پی، گو و چیزهای جالب دیگری داریم که همه از آن راضی هستند، چرخ دیگری را دوباره اختراع کنیم؟
  • و چند نمونه از زندگی. من مجبور شدم گزارش را زیاد برش دهم زیرا 3,5 ساعت طول کشید، بنابراین نمونه های کمی وجود خواهد داشت.

OpenResty NGINX است. به لطف او، ما یک وب سرور کامل داریم که به خوبی نوشته شده و به سرعت کار می کند. من فکر می کنم بیشتر ما از NGINX در تولید استفاده می کنیم. همه شما می دانید که او سریع و باحال است. آنها I/O همزمان جالبی را در آن ایجاد کردند، بنابراین ما نیازی به چرخه چیزی نداریم، درست مانند آنها در پایتون. Gevent جالب است، عالی است، اما اگر کد C را بنویسید و مشکلی پیش بیاید، با Gevent دیوانه وار دیباگ آن خواهید شد. من این تجربه را داشتم: دو روز تمام طول کشید تا بفهمم چه مشکلی در آنجا رخ داده است. اگر کسی چندین هفته اطراف را جستجو نمی کرد، مشکل را پیدا نمی کرد، در اینترنت نمی نوشت، و گوگل آن را پیدا نمی کرد، کاملاً دیوانه می شدیم.

NGINX در حال حاضر حافظه پنهان و محتوای استاتیک را انجام داده است. لازم نیست نگران این باشید که چگونه این کار را به صورت انسانی انجام دهید، تا جایی سرعتتان را کاهش ندهید، تا توصیفگرها را در جایی گم نکنید. Nginx برای استقرار بسیار راحت است، نیازی نیست به این فکر کنید که چه چیزی بگیرید - WSGI، PHP-FPM، Gunicorn، Unicorn. Nginx نصب شد، به ادمین ها داده شد، آنها می دانند چگونه با آن کار کنند. Nginx درخواست ها را به روشی ساختاریافته پردازش می کند. در این مورد کمی بعد صحبت خواهم کرد. به طور خلاصه، مرحله ای دارد که فقط درخواست را می پذیرد، زمانی که آن را پردازش می کند و زمانی که محتوا را به کاربر ارائه می دهد.

Nginx جالب است، اما یک مشکل وجود دارد: به اندازه کافی انعطاف پذیر نیست، حتی با تمام ویژگی های جالبی که بچه ها در پیکربندی جمع کرده اند، با وجود این واقعیت که می توان آن را پیکربندی کرد. این قدرت کافی نیست. به همین دلیل است که بچه‌های تائوبائو، مدت‌ها پیش، به نظر می‌رسد هشت سال پیش، لوا را در آن ساختند. چه چیزی می دهد؟

  • اندازه. این کوچک است. LuaJIT حدود 100-200 کیلوبایت سربار حافظه و حداقل سربار عملکرد را ارائه می دهد.
  • سرعت. مفسر LuaJIT در بسیاری از موقعیت ها به C نزدیک است، در برخی شرایط به جاوا می بازد و در برخی دیگر از آن بهتر عمل می کند. برای مدتی به عنوان بهترین کامپایلر JIT به عنوان بهترین کامپایلر JIT شناخته می شد. الان سردترها هستن ولی خیلی سنگین هستن مثلا همون V8. برخی از مفسرهای JS و جاوا هات اسپات در برخی نقاط سریع‌تر هستند، اما در برخی مکان‌ها همچنان از دست می‌دهند.
  • آسان برای یادگیری. اگر مثلاً یک پایه کد Perl دارید و رزرو نمی کنید، برنامه نویس Perl را پیدا نخواهید کرد. از آنجا که آنها وجود ندارند، همه آنها برداشته شدند و آموزش آنها طولانی و دشوار است. اگر برنامه نویسان را برای چیز دیگری می خواهید، ممکن است مجبور شوید آنها را دوباره آموزش دهید یا آنها را پیدا کنید. در مورد لوا، همه چیز ساده است. هر جوانی می‌تواند لوا را در سه روز یاد بگیرد. حدود دو ساعت طول کشید تا بفهمم. دو ساعت بعد من در حال نوشتن کد در مرحله تولید بودم. حدود یک هفته بعد او مستقیماً به سمت تولید رفت و آنجا را ترک کرد.

در نتیجه، به نظر می رسد این است:

OpenResty: تبدیل NGINX به یک سرور برنامه کامل

اینجا خیلی هست OpenResty مجموعه ای از ماژول ها را جمع آوری کرده است، هم لواش و هم موتور. و شما همه چیز را آماده دارید - مستقر و کار می کنید.

نمونه

شعر بس است، بریم سراغ کد. در اینجا یک سلام کوچک وجود دارد:

OpenResty: تبدیل NGINX به یک سرور برنامه کامل

چه چیزی وجود دارد؟ این مکان انجینز است. ما نگران نیستیم، ما مسیریابی خود را نمی نویسیم، ما یک مسیر آماده را انتخاب نمی کنیم - ما قبلاً آن را در NGINX داریم، ما یک زندگی خوب و تنبل داریم.

content_by_lua_block بلوکی است که می گوید ما در حال ارائه محتوا با استفاده از اسکریپت Lua هستیم. متغیر Engins را می گیریم remote_addr و در آن قرار دهید string.format. این همان است sprintf، فقط در لوا، فقط صحیح است. و به مشتری می دهیم.

در نتیجه به شکل زیر خواهد بود:

OpenResty: تبدیل NGINX به یک سرور برنامه کامل

اما بیایید به دنیای واقعی برگردیم. هیچ کس Hello World را برای تولید مستقر نمی کند. برنامه ما معمولاً به پایگاه داده یا جای دیگری می رود و بیشتر اوقات منتظر پاسخ است.

OpenResty: تبدیل NGINX به یک سرور برنامه کامل

او فقط می نشیند و منتظر است. خیلی خوب نیست وقتی 100.000 کاربر می آیند، برای ما بسیار سخت است. بنابراین بیایید از یک برنامه ساده به عنوان مثال استفاده کنیم. ما به دنبال تصاویر، به عنوان مثال، از گربه ها خواهیم بود. اما ما فقط جستجو نمی‌کنیم، کلمات کلیدی را گسترش می‌دهیم و اگر کاربر «گربه‌ها» را جستجو کرد، گربه‌ها، گربه‌های خزدار و غیره را پیدا می‌کنیم. ابتدا باید داده های درخواست را در باطن دریافت کنیم. به نظر می رسد این است:

OpenResty: تبدیل NGINX به یک سرور برنامه کامل

دو خط به شما امکان می دهد پارامترهای GET را انتخاب کنید، بدون عارضه. در مرحله بعد، فرض کنید، از یک پایگاه داده با علامت یک کلمه کلیدی و پسوند، این اطلاعات را با استفاده از یک پرس و جو معمولی SQL به دست می آوریم. ساده است. به نظر می رسد این است:

OpenResty: تبدیل NGINX به یک سرور برنامه کامل

اتصال کتابخانه resty.mysql، که قبلاً در کیت داریم. ما نیازی به نصب نداریم، همه چیز آماده است. نحوه اتصال و ایجاد یک پرس و جو SQL را نشان می دهیم:

OpenResty: تبدیل NGINX به یک سرور برنامه کامل

اینجا کمی ترسناک است، اما همه چیز کار می کند. در اینجا 10 حد است. ما 10 ورودی را بیرون می آوریم، تنبل هستیم، نمی خواهیم بیشتر نشان دهیم. محدودیت در SQL را فراموش کردم.

در مرحله بعد، تصاویری را برای همه سؤالات پیدا می کنیم. ما یک دسته درخواست جمع آوری می کنیم و یک جدول Lua به نام پر می کنیم reqs، و ما انجام می دهیم ngx.location.capture_multi.

OpenResty: تبدیل NGINX به یک سرور برنامه کامل

همه این درخواست ها به صورت موازی ارسال می شوند و پاسخ ها به ما بازگردانده می شود. زمان عملکرد برابر است با زمان پاسخ آهسته ترین. اگر همه ما در 50 میلی ثانیه شلیک کنیم و صد درخواست ارسال کنیم، در 50 میلی ثانیه پاسخ خواهیم گرفت.

از آنجایی که ما تنبل هستیم و نمی‌خواهیم HTTP و مدیریت حافظه پنهان بنویسیم، NGINX را مجبور می‌کنیم همه کارها را برای ما انجام دهد. همانطور که دیدید درخواستی وجود داشت url/fetch، او اینجا است:

OpenResty: تبدیل NGINX به یک سرور برنامه کامل

ما آن را ساده می کنیم proxy_pass، ما نشان می دهیم که کجا کش کنیم، چگونه این کار را انجام دهیم، و همه چیز برای ما کار می کند.

اما این کافی نیست، ما هنوز باید داده ها را به کاربر بدهیم. ساده ترین ایده این است که همه چیز را در JSON به راحتی و در دو خط سریال کنید. Content-Type را می دهیم، JSON را می دهیم.

اما یک مشکل وجود دارد: کاربر نمی خواهد JSON را بخواند. ما باید توسعه دهندگان فرانت اند را جذب کنیم. گاهی اوقات ما در ابتدا نمی خواهیم این کار را انجام دهیم. و متخصصان سئو می گویند که اگر ما به دنبال عکس هستیم، برای آنها مهم نیست. و اگر مقداری محتوا به آنها بدهیم، می گویند که موتورهای جستجوی ما چیزی را ایندکس نمی کنند.

در مورد آن چه باید کرد؟ البته به کاربر HTML می دهیم. تولید با دست comme il faut نیست، بنابراین ما می خواهیم از الگوها استفاده کنیم. یک کتابخانه برای این وجود دارد lua-resty-template.

OpenResty: تبدیل NGINX به یک سرور برنامه کامل

احتمالاً سه حرف ترسناک OPM را دیده اید. OpenResty با مدیریت بسته خود ارائه می شود که از طریق آن می توانید مجموعه ای از ماژول های مختلف را نصب کنید، به ویژه، lua-resty-template. این یک موتور قالب ساده، شبیه به قالب های جنگو است. در آنجا می توانید کد بنویسید و جایگزینی متغیر را انجام دهید.

در نتیجه، همه چیز چیزی شبیه به این خواهد بود:

OpenResty: تبدیل NGINX به یک سرور برنامه کامل

ما داده ها را گرفتیم و قالب را دوباره در دو خط رندر کردیم. کاربر خوشحال است، او گربه دریافت کرد. از آنجایی که ما درخواست را گسترش دادیم، او همچنین یک مهر خز برای بچه گربه ها دریافت کرد. شما هرگز نمی دانید، شاید او دقیقاً به دنبال این بود، اما نتوانست درخواست خود را به درستی فرموله کند.

همه چیز عالی است، اما ما در حال توسعه هستیم و هنوز نمی‌خواهیم آن را به کاربران نشان دهیم. بیایید مجوز را انجام دهیم. برای انجام این کار، بیایید ببینیم NGINX چگونه درخواست را در شرایط OpenResty مدیریت می کند:

  • فاز اول - دسترسی، زمانی که کاربر تازه وارد شد، و ما او را با هدر، آدرس IP و سایر داده ها نگاه کردیم. اگر دوست نداشتیم می توانیم فوراً آن را قطع کنیم. این می تواند برای مجوز استفاده شود، یا اگر درخواست های زیادی دریافت کنیم، می توانیم به راحتی آنها را در این مرحله قطع کنیم.
  • باز نویسی. ما برخی از داده های درخواست را بازنویسی می کنیم.
  • محتوا. ما محتوا را به کاربر تحویل می دهیم.
  • فیلتر هدر. سرصفحه های پاسخ را جایگزین می کنیم. اگر استفاده کردیم proxy_pass، می توانیم برخی از سرفصل ها را قبل از دادن آن به کاربر بازنویسی کنیم.
  • فیلتر بدنه. ما می توانیم بدن را تغییر دهیم.
  • ورود به سیستم - چوب بری شما می توانید گزارش ها را در elasticsearch بدون لایه اضافی بنویسید.

مجوز ما چیزی شبیه به این خواهد بود:

OpenResty: تبدیل NGINX به یک سرور برنامه کامل

ما این را به آن یکی اضافه می کنیم location، که قبلا توضیح دادیم و کد زیر را در آنجا قرار دهید:

OpenResty: تبدیل NGINX به یک سرور برنامه کامل

ما نگاه می کنیم تا ببینیم آیا رمز کوکی داریم یا خیر. اگر نه، پس ما مجوز درخواست می کنیم. کاربران حیله گر هستند و می توانند حدس بزنند که باید یک رمز کوکی تنظیم کنند. بنابراین، آن را در Redis نیز قرار می دهیم:

OpenResty: تبدیل NGINX به یک سرور برنامه کامل

کد کار با Redis بسیار ساده است و هیچ تفاوتی با زبان های دیگر ندارد. در همان زمان، تمام ورودی/خروجی، اینجا و آنجا مسدود نمی شود. اگر کد همزمان بنویسید، به صورت ناهمزمان کار می کند. تقریبا شبیه gevent، اما خوب انجام شده است.

OpenResty: تبدیل NGINX به یک سرور برنامه کامل

اجازه دهید خود مجوز را انجام دهیم:

OpenResty: تبدیل NGINX به یک سرور برنامه کامل

ما می گوییم که باید بدنه درخواست را بخوانیم. ما آرگومان های POST را دریافت می کنیم و بررسی می کنیم که ورود و رمز عبور صحیح است. اگر آنها نادرست هستند، ما شما را برای مجوز دعوت می کنیم. و اگر درست است، توکن را در Redis بنویسید:

OpenResty: تبدیل NGINX به یک سرور برنامه کامل

فراموش نکنید که کوکی را تنظیم کنید، این کار نیز در دو خط انجام می شود:

OpenResty: تبدیل NGINX به یک سرور برنامه کامل

مثال ساده و حدسی است. البته ما سرویسی نخواهیم ساخت که به مردم گربه نشان دهد. اما چه کسی ما را می شناسد. بنابراین بیایید آنچه را که می توان در تولید انجام داد بررسی کنیم.

  • باطن مینیمالیستی. گاهی اوقات ما نیاز داریم که فقط کمی داده را به باطن خروجی دهیم: جایی که باید تاریخ را وارد کنیم، جایی باید لیستی را نمایش دهیم، بگوییم اکنون چند کاربر در سایت هستند، شمارنده یا آماری را پیوست کنیم. یه چیز خیلی کوچیک برخی از قطعات مینیمال را می توان خیلی راحت ساخت. این کار را سریع، آسان و عالی می کند.
  • پیش پردازش داده ها. گاهی اوقات می خواهیم تبلیغات را در صفحه خود جاسازی کنیم و این تبلیغات را با استفاده از درخواست های API دریافت می کنیم. انجام این کار در اینجا بسیار آسان است. ما باطن خود را که در حال حاضر نشسته و سخت کار می کند، بارگذاری نمی کنیم. می توانید آن را بردارید و از اینجا جمع آوری کنید. ما می‌توانیم برخی از JS را کنار هم بچینیم یا برعکس، آن را از هم جدا کنیم و قبل از ارائه آن به کاربر، آن را از قبل پردازش کنیم.
  • نما برای میکروسرویس. این هم مورد خیلی خوبی است، اجرا کردم. قبل از آن، من در تنزور کار می کردم، شرکتی که با گزارشگری الکترونیکی سروکار دارد و تقریباً نیمی از اشخاص حقوقی کشور را گزارش می دهد. ما یک سرویس ایجاد کردیم، بسیاری از کارها در آنجا با استفاده از مکانیسم مشابه انجام شد: مسیریابی، مجوز و موارد دیگر.
    OpenResty می تواند به عنوان چسب برای میکروسرویس های شما استفاده شود و یک دسترسی واحد به همه چیز و یک رابط واحد فراهم می کند. از آنجایی که میکروسرویس‌ها را می‌توان به گونه‌ای نوشت که Node.js را در اینجا، PHP اینجا، پایتون در اینجا، برخی چیزهای Erlang در اینجا داشته باشید، می‌دانیم که نمی‌خواهیم همان کد را در همه جا بازنویسی کنیم. بنابراین، OpenResty را می توان به جلو وصل کرد.

  • آمار و تجزیه و تحلیل. معمولا NGINX در ورودی است و تمام درخواست ها از طریق آن انجام می شود. در این مکان است که جمع آوری آن بسیار راحت است. شما می توانید بلافاصله چیزی را محاسبه کرده و در جایی آپلود کنید، مثلاً Elasticsearch، Logstash، یا به سادگی آن را در گزارش بنویسید و سپس آن را به جایی ارسال کنید.
  • سیستم های چند کاربره. به عنوان مثال، بازی های آنلاین نیز بسیار خوب هستند. امروز در کیپ تاون، الکساندر گلادیش در مورد چگونگی ساخت سریع یک بازی چند نفره با استفاده از OpenResty صحبت خواهد کرد.
  • درخواست فیلتر (WAF). امروزه ساخت انواع فایروال برنامه های وب مد شده است؛ خدمات زیادی وجود دارد که آنها را ارائه می دهند. با استفاده از OpenResty، می توانید برای خود یک فایروال برنامه وب بسازید که به سادگی و به راحتی درخواست ها را بر اساس نیازهای شما فیلتر می کند. اگر پایتون دارید، پس می‌دانید که قطعاً PHP به شما تزریق نمی‌شود، مگر اینکه، البته، آن را در هر جایی از کنسول پخش کنید. می دانید که MySQL و Python دارید. احتمالاً آنها ممکن است سعی کنند نوعی پیمایش دایرکتوری را انجام دهند و چیزی را به پایگاه داده تزریق کنند. بنابراین، می توانید پرس و جوهای عجیب و غریب را به سرعت و ارزان در جلو فیلتر کنید.
  • انجمن. از آنجایی که OpenResty بر روی NGINX ساخته شده است، یک امتیاز دارد - این انجمن NGINX. این بسیار بزرگ است و بخش مناسبی از سوالاتی که در ابتدا خواهید داشت قبلاً توسط انجمن NGINX حل شده است.

    توسعه دهندگان Lua. دیروز با بچه هایی که به روز آموزش HighLoad++ آمدند صحبت کردم و شنیدم که فقط Tarantool در Lua نوشته شده است. این درست نیست، خیلی چیزها در لوا نوشته شده است. مثال ها: OpenResty، سرور Prosody XMPP، موتور بازی Love2D، Lua اسکریپت شده در Warcraft و جاهای دیگر. توسعه دهندگان Lua زیادی وجود دارد، آنها یک جامعه بزرگ و پاسخگو دارند. تمام سوالات Lua من در عرض چند ساعت حل شد. وقتی به لیست پستی می نویسید، به معنای واقعی کلمه در عرض چند دقیقه تعداد زیادی پاسخ وجود دارد که توضیح می دهند چه چیزی و چگونه، چه چیزی چیست. عالیه. متأسفانه چنین جامعه معنوی و مهربانی در همه جا وجود ندارد.
    GitHub برای OpenResty وجود دارد که می توانید در صورت خرابی مشکلی را باز کنید. یک لیست پستی در Google Groups وجود دارد که می توانید در مورد مسائل کلی بحث کنید، یک لیست پستی به زبان چینی وجود دارد - شما هرگز نمی دانید، شاید انگلیسی صحبت نکنید، اما چینی می دانید.

نمایش نتایج: از

  • امیدوارم توانسته باشم بیان کنم که OpenResty یک چارچوب بسیار راحت است که برای وب طراحی شده است.
  • از آنجایی که کد مشابه چیزی است که ما در آن می نویسیم، مانع ورود کمی است، زبان بسیار ساده و مینیمال است.
  • ورودی/خروجی ناهمزمان را بدون کال بک ارائه می دهد، ما هیچ نودلی نخواهیم داشت که گاهی اوقات می توانیم در NodeJS بنویسیم.
  • استقرار آسانی دارد، زیرا ما فقط به NGINX با ماژول لازم و کد خود نیاز داریم و همه چیز فوراً کار می کند.
  • جامعه بزرگ و پاسخگو

من با جزئیات نگفتم که مسیریابی چگونه انجام می شود، معلوم شد که داستان بسیار طولانی است.

با تشکر از شما!


ولادیمیر پروتاسوف - OpenResty: تبدیل NGINX به یک سرور برنامه کامل

منبع: www.habr.com

اضافه کردن نظر