搞这个是因为Vultr最近又调整了产品线,最低配置是512M的服务器2.5usd,但只有V6地址,而3.5usd的则有个V4地址。
实际上512M运行三五个LEMP架构的网站是足足够用的,再多几个也可以(当然要进行一些设置方面的调整),内存使用量大概在200多到300多M。但因为我这机器还要运行其他程序,所以内存使用量恰好在470左右,为了避免一些突发情况,所以稍微折腾了一下。
现有资源是这样,后端一个性能较高的服务器,但因为是物理机,所以无法绝对避免软硬件故障情况(虽然已经超过120天在线了),另有一些性能稍低的机器,但可以确保绝对稳定,而如果用512M的机器做前端,则有必要对后端资源进行合理使用。
所以呢,需求就是能够对后端资源进行合理的分派(负载均衡),同时在遇到突发故障的时候需要能够自动处理(故障迁移或者说热备)。
下面贴出这个站点配置文件:
后端配置:
#######################################################
# www.tingtao.org
server {
listen 801;
server_name www.tingtao.org;
keepalive_timeout 120;
listen 4431 ssl;
ssl_certificate /var/www/ca/www.tingtao.org/Nginx/1_www.tingtao.org_bundle.crt;
ssl_certificate_key /var/www/ca/www.tingtao.org/Nginx/2_www.tingtao.org.key;
##############################################
error_log /dev/null;
access_log /dev/null;
root /var/www/www.tingtao.org;
location ~ ^.+\.php {
fastcgi_split_path_info ^(.+\.php)(.*)$;
fastcgi_pass unix:/var/run/php7-fpm-www.tingtao.org.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /var/www/www.tingtao.org$fastcgi_script_name;
include fastcgi_params;
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param PHP_ADMIN_VALUE "cgi.fix_pathinfo=1";
fastcgi_param PHP_ADMIN_VALUE "include_path= .:/usr/share/php/";
fastcgi_param PHP_ADMIN_VALUE "open_basedir= $document_root/:/tmp:/usr/share/php/";
fastcgi_param PHP_ADMIN_VALUE "upload_max_filesize= 50M";
fastcgi_param PHP_ADMIN_VALUE "max_execution_time= 30";
fastcgi_param PHP_ADMIN_VALUE "max_input_time= 60";
fastcgi_param PHP_ADMIN_VALUE "memory_limit= 128M";
fastcgi_param PHP_ADMIN_VALUE "output_buffering= 4096";
fastcgi_param PHP_ADMIN_VALUE "disable_functions= system,exec,shell_exec,passthru,error_log,dl,sys_getloadavg,pfsockopen,openlog,syslog,readlink,symlink,link,leak,popen,escapeshellcmd,proc_close,proc_get_status,proc_nice,proc_open,proc_terminate,escapeshellarg,pcntl_exec,show_source,highlight_file,ini_restore,apache_child_terminate,apache_get_modules,apache_get_version,apache_getenv,apache_note,apache_setenv,virtual,mb_send_mail,set_time_limit,max_execution_time,php_uname,disk_free_space,diskfreespace,stream_copy_to_stream";
fastcgi_param PHP_ADMIN_VALUE "allow_url_fopen= off";
fastcgi_param PHP_ADMIN_VALUE "expose_php= Off";
fastcgi_param PHP_ADMIN_VALUE "display_errors= Off";
fastcgi_intercept_errors on;
fastcgi_ignore_client_abort on;
fastcgi_read_timeout 180;
}
location / {
#定义首页索引文件的名称
index index.php index.html index.htm;
#下面这行和后面的跟wordpress有关
try_files $uri $uri/ /index.php?$args;
}
rewrite /wp-admin$ $scheme://$host$uri/ permanent;
}
注意,我在这里改了默认的80和443端口,因为后端的默认端口也进行了一次反向代理,这样如果前端进行调整的时候,则不需要再对后端节点做调整,改一下解析就行。
前端配置:
upstream svr_web_www_tingtao {
server 主节点:801 weight=10;
server 次要节点:801 weight=5;
server 备用机:801 backup;
}
upstream svr_web_www_tingtao_ssl {
server 主节点:4431 weight=10;
server 次要节点:4431 weight=5;
server 备用机:4431 backup;
}
map $scheme $svr_www_tingtao {
default "svr_web_www_tingtao";
https "svr_web_www_tingtao_ssl";
}
###############################################
# www.tingtao.org
server {
listen 80;
listen [::]:80;
server_name www.tingtao.org;
keepalive_timeout 120;
listen 443 ssl;
listen [::]:443 ssl;
ssl_certificate /var/www/ca/www.tingtao.org/Nginx/1_www.tingtao.org_bundle.crt;
ssl_certificate_key /var/www/ca/www.tingtao.org/Nginx/2_www.tingtao.org.key;
##############################################
access_log /var/www/logs/www.tingtao.org_access.log;
error_log /var/www/logs/www.tingtao.org_err.log;
root /var/www/www.tingtao.org;
resolver 9.9.9.9;
#php和后台管理做直通,不进行任何缓存
location ~ (wp-admin|\.php)$ {
proxy_pass $scheme://$svr_www_tingtao;
proxy_set_header Host $host:$proxy_port ;
proxy_no_cache 1;
proxy_cache_bypass 1;
}
#这些静态文件不太可能会更改,所以单独指定较长的过期时间
location ~ .*\.(js|css|gif|jpg|jpeg|png|bmp|swf|flv|ico|woff)$ {
proxy_pass $scheme://$svr_www_tingtao ;
proxy_set_header Host $host ;
proxy_cache staticfile;
proxy_cache_valid 200 302 301 5d;
proxy_cache_valid any 1m;
proxy_cache_use_stale error timeout invalid_header;
#设置浏览器过期时间
expires 1d;
add_header I-Cache "$upstream_cache_status";
}
#默认设置,所有上面未能匹配到的则自动使用这个配置
location / {
proxy_pass $scheme://$svr_www_tingtao ;
proxy_set_header Host $host ;
proxy_cache staticfile;
proxy_cache_valid 200 302 301 1h;
proxy_cache_valid any 1m;
proxy_cache_use_stale error timeout invalid_header;
#设置浏览器过期时间
expires 2h;
add_header I-Cache "$upstream_cache_status";
}
}
简单解释:
主节点和备用节点以2:1的比例进行负载摊派,具体怎么设置可以根据自己情况来。在正常情况下呢,备用节点不参与负载,但如果上面的两个都挂了,则最终由备用节点提供服务。
我未曾测试,但我估计有这么一个情况。比如主节点的数据库挂了,或者主节点返回了500、404这类“http协议”的错误,那么nginx应该不会视为该节点挂了,因为这些状态码和200/304一样,也是一种正常的http回应,我估计只有无法连接才会导致该节点处于down的状态。印象中好像这个有办法解决,回头再琢磨。
只需要简单的复制即可使用,思路也写在注释中了。需要对应更改的就是几个节点的IP以及ssl证书、域名。
缓存定义是这样的(在前端节点):
proxy_cache_path /cache_dir/staticfile levels=2:2 keys_zone=staticfile:10m inactive=1d max_size=3000m; proxy_cache_key $scheme$host$request_uri;
最后记录一个坑,个人认为应该算是个bug:
如果访问前端使用的是https协议,而向后端节点请求是http的话,nginx依然会使用https协议头跟后端通信,所以会导致400错误,这个情况让我折腾了很久才测试出来。
我记得以前呢,不论浏览器使用的是什么协议,都可以通过
proxy_pass http或https://$svr_www_tingtao;
这一行来单独指定前后端之间使用什么协议通信,但现在似乎这样不行了,必须严格匹配。
还有就是,上面配置文件中的 resolver 9.9.9.9; 这一行在这里不是必须的,因为不涉及dns解析,但习惯性加上了。
