تنظیم php.ini روی دایرکتادمین، انتخاب درست اکستنشنها، و شناخت معماری وبسرورها — از فرآیندهای Apache تا حلقهٔ رویداد NGINX و LSAPI لایتاسپید.
اول موتور را تنظیم میکنیم، بعد سراغ بدنهای میرویم که این موتور را حمل میکند. هر دو بخش با کانفیگ واقعی و قابل کپی همراه است.
مسیرها و ترتیب بارگذاری در دایرکتادمین، محدودیت منابع، OPcache، لاگ، سختسازی، اکستنشنهای پرریسک و اکستنشنهای موردنیاز وردپرس.
Apache با مدل process/thread، LiteSpeed با LSAPI و کش داخلی، و NGINX با حلقهٔ رویداد غیر بلاکینگ — هرکدام با دیاگرام و کانفیگ تیونینگ.
NGINX جلو، Apache عقب در حالت nginx_apache: چه به دست میآوریم و چه هزینهای میدهیم؟ در پایان جدول مقایسه و راهنمای تصمیم.
systemctl. همهٔ مسیرها و دستورها بر پایهٔ چیدمان استاندارد دایرکتادمین و CustomBuild نوشته شدهاند: نسخهٔ PHP در مثالها php83 است — آن را با نسخهٔ سرور خودتان جایگزین کنید.یک فایل متنی ساده که تعیین میکند هر درخواست چقدر حافظه بگیرد، چند ثانیه زنده بماند و آیا کد دوباره کامپایل شود؛ و یک فهرست اکستنشن که تعیین میکند یک اسکریپت آلوده چه کارهایی میتواند بکند.
/usr/local/php83/، /usr/local/php82/ و … . نسخههای فعال در options.conf با کلیدهای php1_release و php2_release تعیین میشوند.php.ini را CustomBuild تولید میکند؛ ویرایش مستقیم آن با اولین ./build php n از بین میرود. تغییرات شما جای دیگری میرود./usr/local/php83/bin/php --ini برای CLI و یک صفحهٔ phpinfo() در همان دامنه برای وب.php.conf.d/ یا در تمپلیت custom/ بگذارید و سپس ./build rewrite_confs بزنید.php_admin_value قفل شده باشد. لایهٔ ۱ و ۳ را دایرکتادمین بازتولید میکند.این دایرکتیوها تکتک معنا ندارند؛ نسبتشان با هم مهم است. یک سقف ناهماهنگ، آپلود را بیهیچ خطای واضحی خراب میکند.
the upload chain; ترتیب صحیح: memory ≥ post ≥ upload memory_limit = 256M post_max_size = 128M upload_max_filesize = 64M max_file_uploads = 50 ; فرمهای سنگین (ووکامرس، المنتور) max_input_vars = 5000 ; زمانها — با FPM هماهنگ شود max_execution_time = 60 max_input_time = 60 ; کش مسیرها؛ برای پروژههای پرفایل realpath_cache_size = 8M realpath_cache_ttl = 600
اگر post_max_size از upload_max_filesize کوچکتر باشد، PHP کل بدنهٔ درخواست را دور میریزد و $_POST و $_FILES هر دو خالی میشوند — بدون خطا. جلوی وبسرور هم سقف جداگانه دارد: client_max_body_size در NGINX و LimitRequestBody در Apache.
max_execution_time همهٔ ماجرا نیستاین شمارنده فقط زمان اجرای کد PHP را میشمارد؛ انتظار برای دیتابیس یا sleep در آن حساب نمیشود. مهلت واقعی را request_terminate_timeout در pool و fastcgi_read_timeout در وبسرور تعیین میکنند.
fastcgi_read_timeout > request_terminate_timeout > max_execution_time. برعکسش یعنی خطای ۵۰۲ بهجای پیام خطای قابلفهم./etc/php/8.3/fpm/conf.d/10-opcache.iniopcache.enable=1 opcache.memory_consumption=256 ; MB opcache.interned_strings_buffer=32 opcache.max_accelerated_files=100000 opcache.revalidate_freq=2 opcache.save_comments=1 ; برای annotation ها لازم است opcache.validate_timestamps=1 ; پروداکشن: 0 + ریلود بعد از دیپلوی
opcache_get_status() را ببینید؛ اگر num_cached_keys به سقف نزدیک شده یا oom_restarts بالا رفته، حافظه کم است.validate_timestamps=0 بیشترین سود را دارد ولی تا ریلود FPM یا opcache_reset() کد جدید دیده نمیشود — فقط با دیپلوی خودکار.opcache.jit=tracing) برای بار CPU‑محور سود دارد؛ اپلیکیشن وب معمولی که منتظر I/O است تفاوت محسوسی نمیبیند.opcache.save_comments=0 نگذارید مگر مطمئن باشید هیچ کتابخانهای (Doctrine، PHPUnit، Symfony) به annotation نیاز ندارد.نمایش خطا در پروداکشن هم نشت اطلاعات است (مسیر فایل، نام دیتابیس، نسخهٔ کتابخانه) و هم تجربهٔ کاربری خراب. دقیقاً همان تنظیمات در محیط توسعه باید برعکس باشند.
display_errors = Off display_startup_errors = Off html_errors = Off log_errors = On error_log = /var/log/php-fpm/83-errors.log error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT log_errors_max_len = 2048 ignore_repeated_errors = On
display_errors = On display_startup_errors = On html_errors = On log_errors = On error_reporting = E_ALL zend.assertions = 1 opcache.validate_timestamps = 1 opcache.revalidate_freq = 0
/var/log/httpd/domains/DOMAIN.error.log/var/log/nginx/domains/DOMAIN.error.log/var/log/php-fpm//var/log/directadmin/error.logدر تمپلیت pool مقدار request_slowlog_timeout را روی 5s بگذارید. خروجی، دقیقاً stack trace همان درخواستهایی است که سرور را زمین میزنند — نه حدس و گمان.
دایرکتادمین لاگ دامنهها را خودش میچرخاند، اما فایلی که شما در error_log تعریف کردهاید در این چرخه نیست. یک قانون logrotate با copytruncate برایش بنویسید.
security block; اثر انگشت سرور expose_php = Off ; توابع پرخطر — با فهرست افزونهها تطبیق دهید disable_functions = exec,passthru,shell_exec, system,proc_open,popen,dl,pcntl_exec ; جداسازی هر کاربر — دایرکتادمین این را ; در pool هر کاربر خودش تنظیم میکند open_basedir = /home/USER/:/tmp/:/var/tmp/ session.save_path = /home/USER/tmp upload_tmp_dir = /home/USER/tmp ; ورودی از راه دور allow_url_fopen = Off allow_url_include = Off ; کوکی نشست session.cookie_httponly = 1 session.cookie_secure = 1 session.cookie_samesite = Lax session.use_strict_mode = 1 session.gc_maxlifetime = 1440
proc_open برای بکاپگیری و exec برای پردازش تصویر در بسیاری از افزونهها استفاده میشود. قطع سراسری آنها معمولاً بهجای امنیت، یک تیکت پشتیبانی میسازد. اول در staging.
تنظیم قدیمی cgi.fix_pathinfo=0 هنوز توصیه میشود، اما لایهٔ اصلی در pool است: security.limit_extensions = .php و در وبسرور، بلاک کردن اجرای PHP در مسیر uploads/.
مقادیر عمومی در php.conf.d/99-custom.ini؛ مقادیر وابسته به کاربر (مثل open_basedir) در تمپلیت /usr/local/directadmin/data/templates/custom/php-fpm.conf و سپس ./build rewrite_confs. حفاظت open_basedir در پنل هم بهصورت هرکاربره قابل روشنکردن است.
روی سرور اشتراکی، فهرست اکستنشنها یعنی فهرست کارهایی که یک اسکریپت آلوده میتواند انجام دهد. قاعده ساده است: چیزی که هیچ سایتی روی سرور لازم ندارد، نباید کامپایل شده باشد.
| EXTENSION | چرا پرریسک است | توصیه |
|---|---|---|
| ffi | فراخوانی مستقیم توابع کتابخانههای C از دل PHP — عملاً خروج کامل از هر محدودیتی که در php.ini گذاشتهاید | هرگز روی هاست اشتراکی |
| imap | متکی به کتابخانهٔ قدیمی c-client با سابقهٔ اجرای کد از راه دور؛ از PHP 8.4 از هستهٔ زبان جدا شده است | فقط اگر سرویس ایمیل خاصی لازمش دارد |
| pcntl | pcntl_exec یعنی جایگزینی فرآیند با هر باینری دلخواه روی سرور | فقط در SAPI خط فرمان، نه در FPM |
| posix | posix_getpwuid کاربران سیستم را فهرست میکند و posix_kill فرآیند میکشد | در disable_functions محدود شود |
| shmop · sysv* | حافظهٔ اشتراکی سیستمعامل، بدون مرز بین کاربران — نشت داده بین اکانتهای یک سرور | غیرفعال در هاست اشتراکی |
| soap | پردازش WSDL از منبع بیرونی: زمینهٔ XXE و SSRF به شبکهٔ داخلی | فقط برای درگاههایی که نیاز دارند |
| xmlrpc | سابقهٔ deserialization و XXE؛ از PHP 8 از هسته حذف شده و نگهداری نمیشود | نصب نکنید |
exif هم سابقهٔ آسیبپذیری دارد اما وردپرس واقعاً به آن نیاز دارد؛ xmlrpc را هیچکس نیاز ندارد. تصمیم بر پایهٔ «چه کسی استفاده میکند» گرفته میشود، نه ترس./usr/local/php83/lib/php.conf.d/99-custom.ini; FFI فقط در حالت preload، نه در کد کاربر ffi.enable = Off ; جلوگیری از ساخت/تغییر آرشیو phar در زمان اجرا phar.readonly = On ; بارگذاری ماژول دلخواه در زمان اجرا enable_dl = Off ; یک MySQL مخرب نتواند فایل سرور را بخواند mysqli.allow_local_infile = Off pdo_mysql.default_socket = /usr/local/mysql/data/mysql.sock ; ورودی از راه دور allow_url_fopen = Off allow_url_include = Off
هر اکستنشن یک فایل ini جدا در php.conf.d/ دارد. کافی است پسوندش را عوض کنید تا دیگر بارگذاری نشود — بدون کامپایل مجدد PHP:
cd /usr/local/php83/lib/php.conf.d/ mv 50-imap.ini 50-imap.ini.disabled systemctl restart php-fpm83 /usr/local/php83/bin/php -m | grep imap
phar:// باشد. phar.readonly=On فقط جلوی نوشتن را میگیرد؛ حملهٔ deserialization از راه خواندن رخ میدهد. مهار واقعی، ندادن مسیر فایل کنترلشدهٔ کاربر به توابع فایل است.در ابزار «سلامت سایت» وردپرس تنها یک ماژول با برچسب «الزامی» گزارش میشود؛ بقیه «توصیهشده»اند — اما نبودشان بخشهای واقعی سایت را میشکند، نه اینکه فقط هشدار بدهد.
json تنها موردی است که وردپرس رسماً «الزامی» میداند؛ بقیهٔ این فهرست جزو هستهٔ PHP هستند و معمولاً دستکاری نمیشوند.
zip و sodium برای بروزرسانی خودکار و بررسی امضای بستهها؛ fileinfo برای تشخیص نوع فایل آپلودی.
imagick کیفیت تصویر بهتری از gd میدهد، bcmath برای ووکامرس، و redis برای آبجکتکش پایدار.
mbstring برای برش و شمارش درست حروف فارسی، و intl برای مرتبسازی، قالببندی عدد و تاریخ. بدون این دو، نامکهای فارسی و خلاصهٔ نوشتهها خراب میشوند.exif استثنای قاعده است: در فهرست پرریسک قرار میگیرد، ولی وردپرس برای چرخاندن خودکار تصاویر موبایل به آن نیاز دارد. حذفش نکنید — بهجایش PHP را بهروز نگه دارید.۱ · مسیر CustomBuildcd /usr/local/directadmin/custombuild ./build update ./build options # دیدن نام دقیق گزینهها ./build set php1_release 8.3 ./build set php1_mode php-fpm ./build php n # کامپایل مجدد PHP ./build rewrite_confs
۲ · افزودن ماژول PECL روی یک نسخهٔ خاص/usr/local/php83/bin/pecl install redis echo 'extension=redis.so' > \ /usr/local/php83/lib/php.conf.d/70-redis.ini systemctl restart php-fpm83
۳ · راستیآزمایی# فهرست ماژولهای یک نسخه /usr/local/php83/bin/php -m # مقایسهٔ دو نسخهٔ نصبشده روی سرور diff <(/usr/local/php82/bin/php -m) \ <(/usr/local/php83/bin/php -m) # آنچه واقعاً روی وب فعال است # ← یک فایل phpinfo() در همان دامنه
php82 نصب کنید و سایت روی php83 اجرا شود. هر نسخه باینری، php.ini و pecl جداگانه دارد. همیشه مسیر کامل نسخه را بنویسید، نه php خالی../build php n فهرست ماژولها را دوباره بگیرید؛ کامپایل مجدد میتواند ماژولهای دستینصبشده را کنار بگذارد. اگر ماژولی همیشگی است، آن را از راه options.conf فعال کنید تا در هر build بازساخته شود.در معماری مدرن، PHP یک فرآیند جداست. آنچه ظرفیت واقعی سرور را تعیین میکند، تنظیمات pool است — نه php.ini.
تمپلیت: data/templates/custom/php-fpm.conf
خروجی: /usr/local/php83/etc/php-fpm.d/USER.conf[USER] user = USER group = USER listen = /usr/local/php83/sockets/USER.sock pm = dynamic pm.max_children = 30 pm.start_servers = 6 pm.min_spare_servers = 4 pm.max_spare_servers = 10 pm.max_requests = 500 request_terminate_timeout = 90s slowlog = /var/log/php-fpm/83-USER-slow.log request_slowlog_timeout = 5s ; بازنویسی php.ini فقط برای این کاربر php_admin_value[memory_limit] = 256M php_admin_flag[log_errors] = on php_admin_value[open_basedir] = /home/USER/:/tmp/ php_admin_value[session.save_path] = /home/USER/tmp
pm.max_children را حدس نزنیدمیانگین حافظهٔ هر worker را اندازه بگیرید (معمولاً ۴۰ تا ۱۲۰ مگابایت) و آن را بر رم قابلتخصیص تقسیم کنید. عدد بزرگتر از این یعنی swap و کندی کل سرور — نه ظرفیت بیشتر.
php_value یا php_admin_value؟نسخهٔ admin قفل میکند: کد اپلیکیشن نمیتواند با ini_set() آن را دور بزند. برای open_basedir و disable_functions همیشه از این نسخه استفاده کنید.
pm: static برای سرور اختصاصی پرترافیک، dynamic پیشفرض متعادل، و ondemand برای دهها سایت کمبازدید روی یک سرور — حالت رایج در هاستینگ اشتراکی دایرکتادمین.php-fpm.conf را از data/templates/ به data/templates/custom/ کپی کنید، آنجا ویرایش کنید، سپس ./build rewrite_confs. فایل php-fpm.d/USER.conf خروجی است، نه ورودی.| DIRECTIVE | DEFAULT | PRODUCTION | چرا |
|---|---|---|---|
| memory_limit | 128M | 256M | فضای کافی برای فریمورک و افزونهها بدون میداندادن به نشت حافظه |
| upload_max_filesize | 2M | 64M | آپلود رسانه و بکاپ؛ همیشه کوچکتر از post_max_size |
| post_max_size | 8M | 128M | سقف کل بدنهٔ درخواست، شامل همهٔ فیلدها و فایلها |
| max_input_vars | 1000 | 5000 | فرمهای تنظیمات بزرگ بیسروصدا بریده میشوند |
| realpath_cache_size | 4096K | 8M | کاهش چشمگیر syscall در پروژههای با هزاران فایل |
| opcache.memory_consumption | 128 | 256 | جا برای کل کدبیس؛ در غیر اینصورت restart مکرر کش |
| opcache.max_accelerated_files | 10000 | 100000 | وردپرس با افزونهها بهراحتی از ۱۰٬۰۰۰ فایل عبور میکند |
| expose_php | On | Off | حذف هدر X-Powered-By و افشای نسخهٔ PHP |
| display_errors | On | Off | جلوگیری از نشت مسیر فایل و ساختار پروژه |
| session.cookie_httponly | 0 | 1 | کوکی نشست از دسترس جاوااسکریپت خارج میشود |
php -i | grep memory_limit برای CLI کافی نیست — مقدار مؤثر روی وب را از phpinfo() یا php-fpm -tt بررسی کنید.«چطور هزاران کانکشن همزمان را با حافظهٔ محدود مدیریت کنیم؟» Apache، LiteSpeed و NGINX هر کدام از مسیر متفاوتی به این پرسش رسیدهاند — و همین تفاوت، انتخاب شما را تعیین میکند.
یک فرآیند مستقل بهازای هر درخواست، بدون thread. تنها گزینهٔ سازگار با mod_php، و گرانترین گزینه از نظر حافظه.
چند فرآیند، هرکدام با چندین thread. مصرف حافظه بهازای هر کانکشن بهشدت کمتر، اما نیازمند ماژولهای thread-safe.
مثل worker، بهعلاوهٔ یک thread شنونده برای کانکشنهای keep-alive. پیشفرض توصیهشدهٔ امروز در کنار PHP-FPM.
تنظیمات در سطح دایرکتوری و بدون ریلود سرویس؛ همان چیزی که هاست اشتراکی و اپلیکیشنهای آماده روی آن حساب میکنند. اکوسیستم ماژولها هم بزرگترین در میان وبسرورهاست.
هر درخواست یک فرآیند یا thread میگیرد. با افزایش کانکشنهای همزمان — بهویژه کانکشنهای کند — مصرف حافظه خطی بالا میرود و سرور به سقف MaxRequestWorkers میخورد.
AllowOverride All، Apache برای هر درخواست تمام مسیر تا ریشه را برای یافتن .htaccess جستوجو میکند. اگر قوانین ثابتاند، آنها را به بلاک <Directory> منتقل و AllowOverride None کنید./etc/httpd/conf/extra/httpd-mpm.conf<IfModule mpm_event_module> StartServers 4 MinSpareThreads 25 MaxSpareThreads 75 ThreadsPerChild 25 MaxRequestWorkers 400 ; = ServerLimit × ThreadsPerChild MaxConnectionsPerChild 10000 </IfModule> KeepAlive On MaxKeepAliveRequests 200 KeepAliveTimeout 5 Timeout 60 # در دایرکتادمین این بلاک را خودِ تمپلیت # virtual_host2.conf برای هر دامنه میسازد <FilesMatch \.php$> SetHandler "proxy:unix:/usr/local/php83/sockets/USER.sock|fcgi://localhost" </FilesMatch>
لایتاسپید تلاش میکند هر دو دنیا را بدهد: کارایی مدل رویدادمحور، و سازگاری کامل با کانفیگ و .htaccess آپاچی، بدون بازنویسی چیزی.
پروتکل اختصاصی جایگزین FastCGI با سربار کمتر در تبادل داده و مدیریت مستقیم چرخهٔ عمر فرآیندهای PHP.
کش صفحهٔ کامل در سطح سرور، با پشتیبانی ESI، crawler و افزونهٔ رسمی وردپرس برای باطلسازی هوشمند.
خواندن مستقیم httpd.conf و .htaccess؛ مهاجرت از Apache معمولاً بدون تغییر کانفیگ انجام میشود.
پشتیبانی بومی و از ابتدا؛ ضدِ DDoS ساده و محدودسازی نرخ هم در هستهٔ سرور تعبیه شده است.
| ویژگی | OpenLiteSpeed رایگان | LiteSpeed Enterprise تجاری |
|---|---|---|
| سازگاری .htaccess | قوانین rewrite خوانده میشود، اما بسیاری از تغییرات نیازمند graceful restart است | سازگاری کامل و اعمال آنی، مانند خود Apache |
| جایگزینی drop-in | کانفیگ باید به فرمت خود OLS منتقل شود | httpd.conf را مستقیم میخواند؛ مهاجرت در حد دقایق |
| کنترلپنل | پنل ادمین وب داخلی؛ ادغام با CyberPanel | ادغام رسمی با cPanel، Plesk، DirectAdmin |
| LSCache | موجود | موجود، بههمراه امکانات پیشرفتهٔ ESI و crawler |
| هزینه | متنباز، بدون محدودیت تعداد سایت | لایسنس دورهای، معمولاً بر اساس تعداد worker و رم |
| مناسب برای | سرور اختصاصی، پروژهٔ تکسایته، محیط کانتینری | هاستینگ اشتراکی و سرورهای پرمشتری با کنترلپنل |
./build set webserver litespeed یا openlitespeed و سپس ./build rewrite_confs فعال میشوند. کانفیگ سرور در /usr/local/lsws/conf/ است و دایرکتادمین همچنان vhostها را به فرمت آپاچی تولید میکند.مصرف حافظه با تعداد کانکشن رشد نمیکند. برای کانکشنهای کند، فایلهای استاتیک و نقش reverse proxy بیرقیب است.
نبودِ .htaccess یعنی هیچ جستوجوی فایل بهازای هر درخواست انجام نمیشود — سریعتر و قابل بازبینی در گیت.
همان نبودِ .htaccess در هاست اشتراکی مشکلساز است، و افزودن ماژول اغلب نیازمند کامپایل مجدد یا ماژول پویاست.
127.0.0.1:9000 تنها گزینه است.upstream sent too big header در لاگ یعنی fastcgi_buffers کوچک است — نه اینکه اپلیکیشن خراب باشد.worker_rlimit_nofile باید از worker_connections بزرگتر باشد، وگرنه سقف فایلهای باز سیستمعامل زودتر از کانفیگ شما میرسد.fastcgi_cache میتوان پاسخ صفحات را در خود NGINX نگه داشت — معادل کاری که LSCache بهصورت داخلی انجام میدهد، فقط با کانفیگ دستیِ بیشتر./etc/nginx/nginx.confworker_processes auto; worker_rlimit_nofile 65535; events { worker_connections 8192; multi_accept on; use epoll; } http { sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 30; client_max_body_size 128m; # با post_max_size هماهنگ gzip on; gzip_types text/css application/javascript image/svg+xml; fastcgi_buffers 16 16k; fastcgi_buffer_size 32k; fastcgi_read_timeout 120s; # > request_terminate_timeout }
هدف این معماری، برداشتن نقطهٔ ضعف Apache بدون از دست دادن نقطهٔ قوت آن است: کانکشنهای کند و فایلهای استاتیک را NGINX میگیرد، و .htaccess سرِ جایش میماند.
NGINX پاسخ Apache را کامل میگیرد و worker آپاچی را فوراً آزاد میکند؛ کاربر با شبکهٔ ضعیف دیگر یک thread گران را اشغال نمیکند.
میتوانید مسیر به مسیر ترافیک را از Apache به NGINX منتقل کنید، بدون توقف سرویس و بدون بازنویسی یکبارهٔ همهٔ قوانین.
دو فایل لاگ، دو مجموعه هدر، دو جای تنظیم timeout. هر اشکالی باید در دو لایه ردیابی شود و مصرف رم پایه هم بالاتر میرود.
خروجی دایرکتادمین: data/users/USER/nginx.conf
تمپلیت قابل ویرایش: templates/custom/nginx_server_secure.confserver { listen 443 ssl; http2 on; server_name example.ir; root /var/www/site/public; # استاتیک مستقیم از NGINX location ~* \.(jpg|png|webp|css|js|woff2)$ { expires 30d; access_log off; try_files $uri @apache; } location / { proxy_pass http://127.0.0.1:8080; } location @apache { proxy_pass http://127.0.0.1:8080; } proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_read_timeout 120s; }
فعالسازی حالت ترکیبی در CustomBuildcd /usr/local/directadmin/custombuild ./build set webserver nginx_apache ./build nginx_apache ./build rewrite_confs # آپاچی خودکار روی 127.0.0.1:8080 میرود # و mod_remoteip در تمپلیت گنجانده میشود
آنچه باید در آپاچی تأیید کنیدListen 127.0.0.1:8080 <IfModule mod_remoteip.c> RemoteIPHeader X-Forwarded-For RemoteIPInternalProxy 127.0.0.1 </IfModule> # %a بهجای %h تا IP واقعی لاگ شود LogFormat "%a %l %u %t \"%r\" %>%s %O" combined
mod_remoteip را جا بیندازید، تمام لاگهای Apache و همهٔ ابزارهای امنیتی مثل fail2ban فقط 127.0.0.1 میبینند — یعنی مسدودسازی مهاجم عملاً کل سایت را میبندد.127.0.0.1.X-Forwarded-Proto را بهعنوان proxy مورد اعتماد تعریف کنید تا حلقهٔ ریدایرکت رخ ندهد.| معیار | Apache (event) | LiteSpeed | NGINX | NGINX + Apache |
|---|---|---|---|---|
| مدل همزمانی | فرآیند + thread | رویدادمحور | رویدادمحور | رویدادمحور در لبه، thread در عقب |
| حافظه در کانکشن بالا | رشد خطی | تقریباً ثابت | تقریباً ثابت | متوسط |
| .htaccess | بومی | بومی (کامل در Enterprise) | ندارد | بومی، در لایهٔ Apache |
| کش داخلی صفحه | mod_cache | LSCache، آماده | fastcgi_cache، دستی | proxy_cache در NGINX |
| اتصال به PHP | proxy_fcgi → FPM | LSAPI، داخلی | fastcgi_pass → FPM | از راه Apache |
| HTTP/3 | محدود | بومی | پشتیبانی میشود | در لایهٔ NGINX |
| پیچیدگی نگهداری | کم | کم | متوسط | بالا |
| بهترین کاربرد | اپهای قدیمی، ماژولهای خاص | هاست اشتراکی، وردپرس پرترافیک | API، اپ اختصاصی، کانتینر | مهاجرت تدریجی، سرورهای موجود |
پاسخ به «کدام سریعتر است؟» تقریباً همیشه «بستگی دارد» است. اما پاسخ به این چهار پرسش، تصمیم را قطعی میکند.
هر مشتری قوانین .htaccess خودش را میخواهد و شما نمیتوانید برای هر تغییر سرویس را ریلود کنید.
بیشترین سود از کش صفحهٔ کامل میآید، نه از خود وبسرور. LSCache این را آماده میدهد؛ با NGINX باید fastcgi_cache را دستی بسازید.
کانکشن زیاد، کانفیگ نسخهبندیشده در گیت، و استقرار کانتینری. نیازی به .htaccess ندارید.
پیش از هر مهاجرتی، NGINX را جلو بگذارید. اغلب همین یک لایه، بدون تغییر اپلیکیشن، فشار را برمیدارد.
php.ini را از روی داده تنظیم کنید، نه از روی مقاله. phpinfo()، opcache_get_status() و slowlog سه منبع حقیقت شما هستند.
سقفها زنجیرهاند. از client_max_body_size تا post_max_size، و از fastcgi_read_timeout تا max_execution_time — یک حلقهٔ ناهماهنگ کافی است.
معماری یعنی نحوهٔ خرجکردن حافظه. Apache حافظه را به ازای کانکشن میدهد، NGINX و LiteSpeed به ازای کار واقعی.
ترکیب، یک ابزار است نه یک هدف. اگر Apache را برای .htaccess لازم ندارید، لایهٔ دوم فقط پیچیدگی است.
ab یا wrk قبل و بعد از فعالسازی OPcache تست کنید.pm.max_children را از روی مصرف واقعی حافظهٔ workerها محاسبه کنید.mod_remoteip را درست کنید.سیزدهمین بوتکمپ لینوکس ایرانسرور