之前写过用Varnish作为前端承载服务器的文章,不可否认的是,Varnish纯内存缓存的效率绝对超过任何其他缓存服务器,但是Varnish的作者有点洁癖,不肯增加HTTPS支持,在现今看来,确实有点跟不上时代了。
首先需要明确的是,其实最佳方案是Varnish和Nginx各自负责http和https的流量,这样是效率最大化的。我之前一直比较反感Nginx,是因为这货被人称道的优点我全都用不上,而他的缺点却会让我很麻烦。今天折腾他是因为有几个节点需要单独作为文件下载用,所以用他,比较简单一点,也节约内存。
安装就不多说了,各个平台的流程大同小异,我用Debian 8,几行命令即可:
echo "deb http://nginx.org/packages/debian/ jessie nginx" >> /etc/apt/sources.list echo "deb-src http://nginx.org/packages/debian/ jessie nginx" >> /etc/apt/sources.list wget http://nginx.org/keys/nginx_signing.key apt-key add nginx_signing.key apt-get update apt-get install nginx
我这是把官方给的源加入系统列表,那么直接可以安装官方提供的最新稳定版。个人比较反感源代码编译。
首先创建缓存目录:
mkdir /usr/share/nginx/cache_dir
因为这个目录是我指定在这里,所以需要手工创建。
然后先把默认配置给关掉:
mv /etc/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf.bak
接着编辑一下全局配置文件:
nano /etc/nginx/nginx.conf
我记不清改过那些了,直接贴内容吧,我的配置文件内容:
#运行用户
user nginx;
#启动进程,通常设置成和cpu的数量相等
worker_processes 1;
#全局错误日志及PID文件
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
#工作模式及连接数上限
events {
#epoll是多路复用IO(I/O Multiplexing)中的一种方式,
#仅用于linux2.6以上内核,可以大大提高nginx的性能
use epoll;
#单个后台worker process进程的最大并发连接数
worker_connections 1024;
# 并发总数是 worker_processes 和 worker_connections 的乘积
# 即 max_clients = worker_processes * worker_connections
# 在设置了反向代理的情况下,max_clients = worker_processes * worker_connections / 4 为什么
# 为什么上面反向代理要除以4,应该说是一个经验值
# 根据以上条件,正常情况下的Nginx Server可以应付的最大连接数为:4 * 8000 = 32000
# worker_connections 值的设置跟物理内存大小有关
# 因为并发受IO约束,max_clients的值须小于系统可以打开的最大文件数
# 而系统可以打开的最大文件数和内存大小成正比,一般1GB内存的机器上可以打开的文件数大约是10万左右
# 我们来看看360M内存的VPS可以打开的文件句柄数是多少:
# $ cat /proc/sys/fs/file-max
# 输出 34336
# 32000 < 34336,即并发连接总数小于系统可以打开的文件句柄总数,这样就在操作系统可以承受的范围之内
# 所以,worker_connections 的值需根据 worker_processes 进程数目和系统可以打开的最大文件总数进行适当地进行设置
# 使得并发总数小于操作系统可以打开的最大文件数目
# 其实质也就是根据主机的物理CPU和内存进行配置
# 当然,理论上的并发总数可能会和实际有所偏差,因为主机还有其他的工作进程需要消耗系统资源。
# ulimit -SHn 65535
}
http {
#设定mime类型,类型由mime.type文件定义
include /etc/nginx/mime.types;
default_type application/octet-stream;
#设定日志格式
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
#sendfile 指令指定 nginx 是否调用 sendfile 函数(zero copy 方式)来输出文件,
#对于普通应用,必须设为 on,
#如果用来进行下载等应用磁盘IO重负载应用,可设置为 off,
#以平衡磁盘与网络I/O处理速度,降低系统的uptime.
sendfile on;
#tcp_nopush on;
#连接超时时间
#keepalive_timeout 0;
keepalive_timeout 120;
tcp_nodelay on;
# 开启gzip
gzip on;
# 启用gzip压缩的最小文件,小于设置值的文件将不会压缩
gzip_min_length 1k;
# gzip 压缩级别,1-10,数字越大压缩的越好,也越占用CPU时间,后面会有详细说明
gzip_comp_level 2;
# 进行压缩的文件类型。javascript有多种形式。其中的值可以在 mime.types 文件中找到。
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
# 是否在http header中添加Vary: Accept-Encoding,建议开启
gzip_vary on;
# 禁用IE 6 gzip
gzip_disable "MSIE [1-6]\.";
#设定请求缓冲
# client_header_buffer_size 128k;
# large_client_header_buffers 4 128k;
#server_names_hash_bucket_size 128; #服务器名字的hash表大小
#proxy_headers_hash_max_size 51200; #设置头部哈希表的最大值,不能小于你后端服务器设置的头部总数
#proxy_headers_hash_bucket_size 6400;#设置头部哈希表大小
include /etc/nginx/conf.d/*.conf;
}有些调试用的我注释掉了,还有性能方面我这暂时没发现瓶颈,你可以根据情况调整。
具体include的路径么,各个系统不太相同,各位要根据自己系统调整,我的文件只确保在Debian 8上面正常运行。
最后就是站点配置文件了,路径为/etc/nginx/conf.d/default.conf,不一定非要用default.conf,只要在这个目录里面的conf文件就可以。
我这的配置:
#levels设置目录层次
#keys_zone设置缓存名字和共享内存大小
#inactive在指定时间内没人访问则被删除在这里是1天
#max_size最大缓存空间
proxy_cache_path /usr/share/nginx/cache_dir/tingtao levels=2:2 keys_zone=tingtao:100m inactive=1d max_size=2g;
proxy_cache_path /usr/share/nginx/cache_dir/tingtaoit levels=2:2 keys_zone=tingtaoit:10m inactive=1d max_size=500m;
proxy_cache_key $scheme$host$request_uri;
proxy_connect_timeout 600;
proxy_send_timeout 600;
proxy_read_timeout 600;
send_timeout 600;
proxy_buffers 256 16k;
proxy_buffer_size 32k;
add_header Cache-Control public;
add_header X-Cache-Status $upstream_cache_status;
upstream web_http {
server 1.1.1.1:80;
}
upstream web_http_ssl {
server 1.1.1.1:443;
}
################################################
# old.tingtao.org
server {
listen 80;
server_name old.tingtao.org;
keepalive_timeout 120;
##############################################
access_log off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# 不缓存的文件和路径
location ~ (wp-admin|\.php)$ {
proxy_pass http://web_http;
proxy_no_cache 1;
proxy_cache_bypass 1;
}
# 默认的缓存策略
location / {
proxy_cache tingtao;
proxy_pass http://web_http;
proxy_redirect off;
proxy_cache_valid 200 302 301 1d; #对不同的HTTP状态码设置不同的缓存时间,h小时,d天数
proxy_cache_valid any 1m;
proxy_cache_use_stale error timeout invalid_header;
}
}
server {
listen 443 ssl;
server_name old.tingtao.org;
ssl_certificate /var/www/ca/old.tingtao.org/Nginx/1_old.tingtao.org_bundle.crt;
ssl_certificate_key /var/www/ca/old.tingtao.org/Nginx/2_old.tingtao.org.key;
keepalive_timeout 120;
access_log off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# 不缓存的文件
location ~ (wp-admin|\.php)$ {
proxy_pass https://web_http_ssl;
proxy_no_cache 1;
proxy_cache_bypass 1;
}
# 默认的
location / {
proxy_cache tingtao;
proxy_pass https://web_http_ssl;
proxy_redirect off;
proxy_cache_valid 200 302 301 1d; #对不同的HTTP状态码设置不同的缓存时间,h小时,d天数
proxy_cache_valid any 1m;
proxy_cache_use_stale error timeout invalid_header;
}
}
#默认站点
server {
listen 80 default;
server_name www.tingtao.org;
#定义服务器的默认网站根目录位置
root /var/www/re.haote.net;
#默认请求
location / {
#定义首页索引文件的名称
index index.html index.php index.htm;
}
# 定义错误提示页面
error_page 404 = http://re.haote.net/index.html;
#禁止访问 .htaxxx 文件
location ~ /.hta {
deny all;
}
}
简单说明一下:
1,文件中有3个站点,分别是old.tingtao.org的http和https,以及一个默认站点。默认站点不是必须的。默认站点的listen里需要有“default”关键字。
2,location ~ (wp-admin|\.php)$ 这个条件对于wordpress站点来说其实意义不大,这里只是为了举个例子。怎样可以只用一行就定义多个文件名+路径的形式,我看了很多人写的文章,都没这种写法,明明一段搞定的事情,非要折腾一屏幕……
我个人觉得,对于缓存服务器来说,无非就是缓存和不缓存两种情况,当然有些网站可能需要更细致的根据文件类型设置不同的缓存周期,或者根据不同路径丢到不同的后端服务器,这类需求照着修改就是了,比葫芦画瓢的事情不再多说。
3,实际上不论一个站点是http还是https,都可以从https/http两种后端请求内容,也就是说,http站点也可以从https的后端请求内容,反过来亦可。因为严格界定的话,其实缓存服务器可以理解为“中间人攻击”的一种,哈哈。
那么,也就是说,如果你灵活运用的话,只需要在我的配置文件里面增加一点点rewrite内容就可以实现一个http后端,衍生出http+https的前端。
4,proxy_cache tingtao;这行里面的tingtao对应着顶部的存储区配置,我复制了一点说明,对照修改即可。
5,add_header X-Cache-Status $upstream_cache_status;这一行是增加一个http响应头,方便调试缓存状态。
6,Nginx应该算是内存+硬盘缓存的,更深入的缓存调整细节还是仔细看看文档比较靠谱。Nginx和Varnish都不能取代对方,他们的适用场景不同:
如果配置牛B,内存大,并且是纯http,那用Varnish绝对飞起来;
如果配置差一些,内存小,硬盘大而且是SSD盘,那么Nginx会经济一些;
如果配置差,内存小,还硬盘差,那你最好别用缓存服务器了,这玩意不适合你,硬上的话只会让你的网站更慢 :mrgreen:
其他的想起来再补充吧。
