Все нижесказанное имеет отношение к NGINX 0.7.62 и SMF 1.1.10. На момент написания этого топика apt-get install nginx инсталлирует старую версию 0.6, а нам нужно более новая и стабильная 0.7.62. Поэтому скачиваем sources компилируем и устанавливаем.
Наша цель: на гостей форума не тратить процессорное время - не трогать SMF по возможности и все готовые страницы хранить в cache, а пользователям наоборот позволять видеть самые последние изменения на форуме без задержек.
Вопрос первый: Как отличить пользователя от гостя? После установки SMF форума в окне настроек сервера есть поле "Имя Cookie". Наличие cookie с таким именем говорит о том, что перед нами пользователь, а отсутствие - гость. Обратите внимание на то, что количество использований перед тем как страница попадает в cache выставлена в 2 - это предотвращает кеширование ненужных страниц.
Вопрос второй? Стоит ли использовать GZIP сжатие в SMF или нет? Стоит! Хотя на это и тратиться процессорное время в PHP, но включать сжатие в NGINX точно не стоит - процессорное время будет тратиться на каждый запрос хотя и в меньшем количестве, но запросов-то многие тыщи!
Теперь еще один важный вопрос: загруженные пользователями аватары и картинки в SMF он загружаются через PHP, что существенно просаживает сервер. Они одинаковы для пользователей и гостей. И меняются ну очень очень редко. Наша задача их положить в cache и потом брать их только оттуда.
В этой статье не отражена тема реакции на 503 ошибку выдаваемую NGINX при исчерпании лимитов,а так же вопросы блокирования ботов со скоростью долбежки 1 раз в несколько секунд запрашивающих каждый раз произвольную страницу.
/etc/nginx/nginx.conf
user www-data www-data;
worker_processes 1;
worker_rlimit_nofile 80000;
#error_log /var/log/nginx/error.log;
pid /var/run/nginx.pid;
events {
use epoll;
worker_connections 50000;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format filter '$remote_addr [$time_local] $status $bytes_sent $request_time "$request"';
keepalive_timeout 10;
send_timeout 5;
client_body_timeout 10;
client_header_timeout 10;
tcp_nopush on;
tcp_nodelay on;
reset_timedout_connection on;
sendfile on;
server_tokens off;
gzip off;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
/etc/nginx/sites-available/default
limit_req_zone $binary_remote_addr zone=req_php:10m rate=2r/s;
limit_zone conn_php $binary_remote_addr 10m;
limit_zone conn_static $binary_remote_addr 10m;
fastcgi_cache_path /var/lib/nginx/cache levels= keys_zone=fcgi_php:10m max_size=512m inactive=1d;
server {
listen 80;
server_name example.net;
access_log /var/log/nginx/example.access.log filter;
location = / {
limit_req zone=req_php;
limit_conn conn_php 2;
rewrite .* /forum/index.php permanent;
}
location = /forum {
limit_req zone=req_php;
limit_conn conn_php 2;
rewrite .* /forum/index.php permanent;
}
location = /forum/ {
limit_req zone=req_php;
limit_conn conn_php 2;
rewrite .* /forum/index.php permanent;
}
location / {
root /var/www/example;
index index.php index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /var/www/nginx-default;
}
location ~ ^/forum/attachments/.*\.php$ {
deny all;
}
location ~ \.php$ {
limit_req zone=req_php burst=10;
limit_conn conn_php 4;
set $userid $http_if_modified_since|$http_if_none_match|$cookie_CookieSMF;
if ($http_cookie !~ CookieSMF) {
set $userid "";
}
if ($query_string ~ ^action=dlattach\;) {
set $userid "";
}
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /var/www/example$fastcgi_script_name;
fastcgi_pass_header Cookie;
fastcgi_ignore_headers Cache-Control Expires;
fastcgi_cache fcgi_php;
fastcgi_cache_min_uses 2;
fastcgi_cache_key $request_method|$host|$request_uri|$userid;
fastcgi_cache_valid 301 8h;
fastcgi_cache_valid 302 404 1h;
fastcgi_cache_valid 200 15m;
include /etc/nginx/fastcgi_params;
}
limit_conn conn_static 8;
location ~ \.inc$ {
deny all;
}
location ~ \.bak$ {
deny all;
}
location ~ \~$ {
deny all;
}
location ~ /\.ht {
deny all;
}
}