معماری و تنظیمات اولیه | Nginx from scratch
3 روز پیش
با معماری داخلی Nginx آشنا میشیم و تنظیمات اولیه اون رو بررسی میکنیم.
برای استفاده از nginx ابتدا باید آن را نصب و راه اندازی کنید. روش نصب بر حسب اینکه از چه سیستم عاملی استفاده میکنید ممکن است متفاوت باشد.
در صورتی که از سیستم عامل ویندوز استفاده میکنید ابتدا فایل فشرده شده ی nginx را دانلود کنید و سپس بر حسب مستندات اون رو نصب و اجرا کنید.
به عنوان روش دوم در ویندوز میتونید از winget استفاده کنید. این ابزار یک پکیج منیجر هست و براتون نرم افزارهایی که میخواید رو نصب میکنه. کافیست winget رو از طریق Microsoft Store نصب کنید و سپس با توجه به مستندات nginx رو نصب کنید.
- اگر از لینوکس (Linux) یا FreeBSD استفاده میکنید میتونید طبق مستندات nginx رو نصب و راه اندازی کنید.
- توی MacOS میتونید از brew برای نصب استفاده کنید کافیست دستور را اجرا کنید.
روش پیشنهادی من استفاده از داکر (docker) است. برای اینکار میتونید ابتدا داکر را نصب کنید و سپس با استفاده از دستور زیر nginx رو اجرا کنید.
اگر به عنوان مهندس نرم افزار یا برنامه نویس کار میکنید و با داکر آشنایی ندارید, الان فرصت خوبیه که اونو نصب کنید و ازش استفاده کنید.
- اگه روی ویندوز هستین با استفاده از winget تقریبا هرچیزی رو میتونید نصب کنید. مثلا میتونید Docker رو با winget نصب کنید.
برای اطمینان از نصب, کافیه با استفاده از مرورگر خود, به یکی از ادرس های localhost
یا 127.0.0.1
برید و باید با صفحه ای مانند تصویر زیر روبرو بشید.
نکته: در صورتی که از سیستم عامل ویندوز یا MacOS استفاده میکنید ممکن است nginx به صورت پیش فرض روی پورت 8080 صفحه ی بالا را نمایش دهد. بدین منظور تهه آدرس خودتون باید :8080
را وارد کنید. پس اگه ادرس بالا کار نکرد میتونید localhost:8080
یا 127.0.0.1:8080
را نیز امتحان کنید.
روی ویندوز Make رو نیز نصب کنید چون جلوتر ازش استفاده میکنیم. روی MacOS و Linux به صورت پیش فرض این ابزار موجود است. برای اطمینان از نصب میتونید دستور make -v
رو اجرا کنید و باید ورژنی که نصب هست رو بهتون نشون بده.
فایل ها و مسیرهای مهم
/etc/nginx/
: به صورت پیش فرض فایل های تنظیمات nginx در این مسیر قرار دارند./etc/nginx/nginx.conf
: این فایل به صورت پیش فرض نقطه ی شروعی برای لود کردن باقی تنظیمات است. یکسری تنظیمات اولیه مربوط به وب سرورهای http و همچنین تنظیمات مربوط به نوشتن لاگ ها درون این فایل قرار دارد و سپس این فایل باقی تنظیمات رو از مسیر/etc/nginx/conf.d/
لود میکند./etc/nginx/conf.d/
: به صورت پیش فرض هر فایلی که با پسوندconf
درون این دایرکتوری بسازید به عنوان تنظیمات لود میشود./var/log/nginx/
: در این مسیر دو فایلaccess.log
وerror.log
رو میتونیم ببینیم که لاگ های دسترسی (access logs) و همچنین لاگ های مربوط به خطاها (error logs) درون این فایل ها ذخیره میشوند.
کنسول کمندهای پایه
nginx -h
: این دستور حکم راهنما یا help را دارد. با استفاده از اون میتونید با لیست باقی دستورات و نحوه استفاده ازشون آشنا بشید.
nginx -v
: این دستور ورژن nginx شما رو بهتون نشون میده.nginx -V
: این دستور علاوه بر ورژن nginx اطلاعات بیشتری راجب تنظیمات و ماژول های nginx به شما میدهد.
nginx -t
: این دستور صحت تنظیمات شما که به صورت پیش فرض در مسیر/etc/nginx/
هست رو چک میکند و نتیجه را به شما اعلام میکند.
nginx -T
: این دستور همانند دستور قبل هست با این تفاوت که تنظیماتی که بررسی شدن رو در صفحه چاپ میکند.nginx -s signal
: با استفاده از این دستور میتونید یکسری سیگنال به nginx ارسال کنید. سیگنال میتواندstop
,quit
,reload
یاreopen
باشد.- stop باعث توقف آنی nginx میشود.
- quit باعث میشود تا nginx ابتدا درخواست هایی که دریافت کرده است را اجرا کند و سپس متوقف شود.
- reload باعث میشود تا nginx دوباره تنظیمات را بخواند و خود را برحسب آنها تنظیم کند.
- reopen باعث میشود تا nginx فایل های لاگ را دوباره باز کند.
در مثال زیر هرکدام از سیگنال ها رو به صورت جداگانه به nginx ارسال کرده ایم:
بعد از تغییر دادن تنظیمات Nginx، باید حتماً یک بار دستور nginx -s reload
رو اجرا کنید تا تغییرات اعمال شوند.
Event و Event loop چیست؟
قبل از اینکه بتونیم در مورد معماری nginx توضیح بدیم لازمه که بدونید event loop چیه و چطور کار میکنه. در دنیای کامپیوتر یک رویداد یا event به معنی یک اتفاقی است افتاده و باید به آن واکنش نشون داد.
ایونت لوپ (Event Loop) مانند یک حلقهی دائمی عمل میکند که همواره در حال گوشدادن به رویدادهاست و بهمحض وقوع هر رویداد، آن را پردازش میکند.
هر event loop یک صف انتظار (Queue) دارد که رویدادها به ترتیب در آن قرار میگیرند. سپس event loop، این رویدادها را یکییکی از صف خارج کرده و پردازش میکند.
به صورت ساده, یک event loop مراحل زیر رو انجام میده:
- منتظر دریافت یک رویداد میماند (مثلاً دریافت یک درخواست کاربر).
- در صورت دریافت رویداد، تابع مربوط به پردازش آن را اجرا میکند (مثلاً نمایش صفحه ای از وبسایت)
- اگر پردازش نیازمند صبر بود (مثلاً خواندن فایل از دیسک)، آن را بهصورت همروند (asynchronous) انجام میدهد و بلافاصله سراغ رویداد بعدی میرود.
- پس از پایان عملیاتِ همروند، نتیجهی آن دوباره وارد صف رویدادها میشود تا در زمان مناسب ادامهی پردازش انجام گیرد.
یک مثال واقعی برای درک بهتر: فستفود
برای درک سادهتر مفهوم Event Loop
، تصور کنید در یک رستوران فستفود حضور دارید:
- مشتریها مانند رویدادها (Events) یکییکی وارد صف میشوند.
- تنها یک صندوقدار در محل حضور دارد که وظیفهی رسیدگی به سفارشها را بر عهده دارد. این صندوقدار نقش Event Loop را ایفا میکند.
روند کار بهصورت زیر است:
- هر بار که یک مشتری به جلوی صف میرسد، صندوقدار سفارش او را ثبت میکند.
- صندوقدار بدون معطلی، بلافاصله به سراغ مشتری بعدی میرود, حتی اگر سفارش مشتری قبلی هنوز آماده نشده باشد.
- نکتهی کلیدی اینجاست که صندوقدار هیچگاه منتظر آماده شدن سفارش مشتری نمیماند. اگر آمادهسازی سفارش زمانبر باشد، به مشتری میگوید: «لطفاً بنشینید؛ پس از آماده شدن غذا شما را صدا میزنیم.»
- این روش نشاندهندهی عملکرد همروند (asynchronous) است؛ یعنی فرآیند ثبت سفارش متوقف نمیشود و صندوقدار بدون انتظار، به رسیدگی سایر رویدادها (مشتریها) ادامه میدهد.
معماری و نحوه عملکرد
به صورت ساده, معماری nginx رویدادگرا (event based) و همروند (asynchronous) است که به صورت master-worker پیاده سازی شده است.
در nginx دو نوع پروسه (process) اصلی وجود دارد:
- حداکثر یک پروسه master
- حداقل یک پروسه worker
پروسه master
حداکثر یک پروسه master اجرا میشود و دارای وظایف زیر خواهد بود:
- خوندن و بارگذاری فایل پیکربندی (nginx.conf)
- ساختن و مدیریت worker processes
- اعمال عملیات مدیریتی مثل: ریستارت نرم (graceful restart) اجرای سیگنالها (reload, stop, etc) و نظارت روی سلامت workerها (اگر worker دچار مشکل شود یا به خطا روبرو شود, آن را دوباره راهاندازی می کند)
وظایف پروسه worker
معمولا چندین پروسه worker اجرا میشود که دارای وظایف زیر خواهند بود:
- مدیریت کردن اتصال ها (TCP, UDP)
- پردازش درخواست ها
- ارسال پاسخ به درخواست ها
تعداد پروسه های worker را در تنظیمات با استفاده از دستور worker_processes
میتوان مشخص کرد.
تنظیمات پیش فرض
همانطور که اشاره کردیم /etc/nginx/nginx.conf
فایلی است که به صورت پیش فرض توسط Nginx برای لود کردن تنظیمات مورد استفاده قرار میگیرد. این فایل به صورت پیش فرض دارای تنظیماتی مشابه زیر است:
در این بخش، بهطور خلاصه به بررسی هر یک از دستورات میپردازیم تا درکی اولیه از تنظیمات به دست آورید. در قسمت های بعد، هر دستور را بهصورت مفصل توضیح خواهیم داد.
- در خط اول دستور
user
دسترسی ورکر پروسزهایی که توسط nginx ایجاد میشوند را مشخص میکند. ساختار این دستور میتواند به صورت زیر باشد:
پارامتر user
به نام یوزر و پارامتر group
به نام گروه اشاره میکند. در صورتی که group
را مشخص نکنیم از نام یوزر به عنوان گروه نیز استفاده میشود. [مستندات]
در خط دوم تعداد پروسه های ورکر (worker processes) را مشخص میکنیم که در اینجا از
auto
استفاده شده و بدین معنی است که nginx تعداد پروسه های ورکر را بر اساس ظرفیت و تعداد هسته CPU مشخص میکند. [مستندات]دستور
error_log
دو پارامتر قبول میکند. پارامتر اول مسیری که لاگ خطاها در آنجا نوشته میشوند را مشخص میکند و پارامتر دوم میزان حساسیت لاگ ها را مشخص میکند. در اینجا مشخص شده است که خطاهایی که حداقلnotice
باشند درون لاگ نوشته میشوند.pid
مسیر فایلی که حاوی ID پروسه master خواهد بود را مشخص میکند. nginx توسط این ID میتواند سیگنال هایی که با استفاده از دستور nginx -s
ارسال میکنیم را دریافت و مدیریت کند.بلاک
events
تنظیمات مربوط بهevent loops
را انجام میدهد. قبل تر گفتیم که هر پروسه worker دارای یک ایونت لوپ درونی است. با استفاده از دستور worker_connections
میتوان مشخص کرد که هر پروسه ورکر حداکثر چندین کانکشن همزمان را میتواند قبول کند.بلاک
http
تنظیمات مرتبط با پروتکل HTTP را شامل میشود.در خط اول با استفاده از دستور
include
فایل/etc/nginx/mime.types
را به درون تنظیمات فعلی اضافه شده است. این فایل شامل یک لیست از پسوند فایل ها به همراهcontent-type
اونها هست. برای مثال مشخص شده که اگه پسوند فایلtxt
بود, در هنگام ارسال این فایل به کلاینت, از هدرplian/text
استفاده شود.- در خط بعدی با استفاده از دستور
default_type
مشخص شده است در صورتی که نوع فایل تشخیص داده نشود, به صورت پیش فرض برای آن از هدر application/octet-stream
استفاده شود. دو خط بعدی مربوط به فرمت لاگ ها و محل ذخیره سازی لاگ ها است. دستور
log_format
دو پارامتر قبول میکند. پارامتر اول نامی است که برای فرمت در نظر میگیریم و پارامتر دوم فرمت مورد نظر ما برای نوشتن لاگ است. سپس در دستورaccess_log
ابتدا مسیر ذخیره ی لاگ ها و سپس فرمت لاگ را با استفاده از نام آن مشخص شده است.دستور
keepalive_timeout
مشخص میکند که هر کانکشن چه طول عمری دارد. در اینجا مشخص شده است که هر کانکشن حداکثر ۶۵ ثانیه طول عمر دارد. بدین صورت مرورگر کاربر تنها با استفاده از یک کانکشن میتواند چندین درخواست دهد و نیاز نیست برای لود کردن فایل ها و تصاویر یک صفحه وب چندین کانکشن با سرور ایجاد کند.در خط اخر دستور
include
هر فایلی که دارای پسوندconf
باشد را از مسیر/etc/nginx/conf.d
درون بلوک http لود میکند. بنابراین هر تنظیماتی را که در این مسیر قرار دهید به عنوان تنظیماتی برای پروتکل HTTP در نظر گرفته میشود.
دستوراتی که در اینجا بهصورت خلاصه معرفی شد، در بخش core_modules از مستندات رسمی Nginx بهطور کامل توضیح داده شدهاند.
قسمت قبل: معرفی و تاریخچه | Nginx from stratch
قسمت بعد: وب سرور برای فایل های استاتیک | Nginx from stratch