搞这个是因为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解析,但习惯性加上了。

作者 听涛

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注