之前写过用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:
其他的想起来再补充吧。