nginx的反向代理及缓存
基本概念
-
在反向代理和使用到缓存功能的时候,还会启动有两个进程cache loader和cache manager
-
cache loader的作用:
-
检查缓存存储中的缓存对象
-
使用缓存元数据建立内存数据库
-
-
cache manager的作用:缓存的失效,过期检验以及清理
-
nginx的反向代理模块
-
Module ngx_http_proxy_module
-
配置文语法格式
location /uri {
proxy_pass http://back_sercer:port/newuri
}
- 简单示例
location / {
proxy_pass http://localhost:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
-
proxy_pass:表示只要用户访问'/'下的所有请求都反向代理到此处指定的url“http://localhost:8000”下
-
proxy_set_header:表示代理服务器nginx向后端服务器发送请求报文时的首部信息
-
Host:$host是请求报文中Host首部的值,后端服务器有可能使用虚拟主机,而nginx进行代理时,在proxy_pass上指定的是后端服务器的ip地址,所以请求的时候,可能是请求到默认的虚拟主机,而不是用户真正请求的虚拟主机,所以要指定该首部值
-
X-Real-IP:$remote_addr表示客户端的ip地址,由于是通过nginx进行代理,所以nginx将请求报文发送给后端服务器的源地址是nginx的地址,所以后端服务器记录日志时,其中的客户端ip始终是nginx的地址,然而我们分析日志时想要得到的是客户端的ip地址,因此要在请求报文首部中包含客户端的ip地址,服务器端记录日志时是记录该地址
-
-
示例1:
- 在nginx服务器(192.168.182.130)上编辑配置文件nginx.conf,内容如下
http { server { listen 80; server_name localhost; location / { #root html; proxy_pass http://192.168.182.132/; index index.html index.htm; } } }
- 在后端服务器上(192.168.182.132)上开启web服务并编辑默认页面
[root@backserver ~]# service httpd start [root@backserver ~]# vim /var/www/html/index.html #内容如下: page on backserver
- 客户端进行访问测试,使用浏览器或者curl命令
~]# curl http://192.168.182.130 page on backserver
- 在后端服务器上查看记录的日志信息,会发现记录的客户端ip地址是nginx的地址
[root@backserver ~]# tail -1 /var/log/httpd/access_log 192.168.182.130 - - [10/Jun/2018:11:00:58 +0800] "GET / HTTP/1.0" 200 19 "-" "curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.21 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2"
-
示例2:还可以对指定目录进行反向代理,其他目录的访问仍然访问nginx的web服务
- 编辑配置文件nginx.conf
http { server { listen 80; server_name localhost; location / { root html; index index.html index.htm; } location /forum/ { proxy_pass http://192.168.182.132/bbs/; } } }
- 后端服务器在/var/www/html/bbs/目录下编写访问页面
[root@backserver ~]# cat /var/www/html/bbs/index.html page on bbs
- 测试:
- 示例3:在示例2中要注意的是,如果使用正则表达式匹配,那么proxy_pass后面写的url只能写到'/'
http {
server {
listen 80;
server_name localhost;
location / {
root html;
index index.html index.htm;
}
location ~* \.(jpg|png|gif)$ {
proxy_pass http://192.168.182.132;
#注意ip地址后面不能添加任何路径,‘/’也不可以,不然就是语法错误,如果图片路径在后端服务器的默认发布目录的某个目录下,那么只能够客户端访问的时候补全路径
}
}
}
-
示例4:将例2中添加proxy_set_header
- 编辑配置文件nginx.conf
location /forum/ { proxy_pass http://192.168.182.132/bbs/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; }
- 修改后端服务器中的日志记录格式,将原来记录访问ip的%h修改成%{X-Real-IP}i
[root@backserver html]# vim /etc/httpd/conf/httpd.conf 内容如下: LogFormat "%{X-Real-IP}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined [root@backserver html]# tail -1 /var/log/httpd/access_log 192.168.182.1 - - [10/Jun/2018:18:12:36 +0800] "GET /bbs/ HTTP/1.0" 304 - "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36" #可以看到将客户端的ip记录下来了
-
proxy_http_version:指定http协议版本,客户端发送给nginx的请求和nginx代理给后端服务器的请求有可能都是长连接的,而在nginx上是有缓存的,所以在nginx发送给服务器端的请求并不需要使用长连接,我们可以通过指定协议版本为1.0使得不具有长连接
Syntax:proxy_http_version 1.0 | 1.1;
Default:proxy_http_version 1.0;
Context:http, server, location
- proxy_cache_path:定义缓存文件路径,nginx的缓存是键值存储的,在内存空间中找一个地方进行存储,存储的键是hash过的url,值是该url对应的资源文件路径,而不是资源本身的内容,内容是存储在本地磁盘上,在磁盘上分为一级子目录,二级子目录,三级子目录
Syntax:proxy_cache_path path [levels=levels] [use_temp_path=on|off] keys_zone=name:size [inactive=time] [max_size=size] [manager_files=number] [manager_sleep=time] [manager_threshold=time] [loader_files=number] [loader_sleep=time] [loader_threshold=time] [purger=on|off] [purger_files=number] [purger_sleep=time] [purger_threshold=time];
Default:—
Context:http
-
max_size=size:指定path路径下最大可以使用多少空间进行缓存
-
使用示例:levels是指定子目录的级数和相对应的子目录的个数,使用冒号隔开第一个表示一级子目录名的字符数,第二个表示支持二级子目录名字符数,如果还有一个冒号隔开的数字,那就对应三级子目录名字符数,根据字符数可以计算出子目录的个数
proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=one:10m;
#keys_zone=one:10m表示在内存空间中找一个10m大小的空间命名为one来存放缓存信息
- 在磁盘上的文件路径表示示例
/data/nginx/cache/c/29/b7f54b2df7773722d382f4809d65029c
#可以看到一级目录只使用一个字符表示,二级目录使用2个数字表示,后面的文件名是经过hash的文件名
- proxy_cache:使用缓存功能,zone就是上面提到的keys_zone选项指定的zone的名字
Syntax: proxy_cache zone | off;
Default:
proxy_cache off;
Context: http, server, location
- proxy_cache_methods:只有客户端请求的方法是该处指定的方法时才进行缓存
Syntax: proxy_cache_methods GET | HEAD | POST ...;
Default:
proxy_cache_methods GET HEAD;
Context: http, server, location
- proxy_cache_min_uses:指定某个请求至少要响应多少次才缓存下来
Syntax: proxy_cache_min_uses number;
Default:
proxy_cache_min_uses 1;
Context: http, server, location
- proxy_cache_purge:用来管理缓存空间,当缓存还没有过期,但是后端服务器已经将内容进行了更新,使用该选项就可以将用户请求的内容从缓存中删除,从而实现到后端服务器取新内容
Syntax: proxy_cache_purge string ...;
Default: —
Context: http, server, location
- 示例
proxy_cache_path /data/nginx/cache keys_zone=cache_zone:10m;
map $request_method $purge_method {
PURGE 1;
default 0;
}
server {
...
location / {
proxy_pass http://backend;
proxy_cache cache_zone;
proxy_cache_key $uri;
proxy_cache_purge $purge_method;
}
}
- proxy_cache_revalidate:过期后重新校验,缓存的内容如果过期了并且没有被cache-manager删除,使用该选项表示会向后端服务器询问该内容是否发生了改变,如果没有改变就使用该缓存的内容,如果改变了就从后端服务器取新内容
Syntax: proxy_cache_revalidate on | off;
Default:
proxy_cache_revalidate off;
Context: http, server, location
- proxy_cache_use_stale:当缓存内容过期了或者发生了改变,就要到后端服务器上取新内容,但是无法与后端服务器建立连接,此选项指定了在什么情况下使用过期缓存
Syntax: proxy_cache_use_stale error | timeout | invalid_header | updating | http_500 | http_502 | http_503 | http_504 | http_403 | http_404 | http_429 | off ...;
#表示当后端响应为error,timeout(nginx连接后端服务器超时),invalid_header,http_500,http_502,...的时候使用过期缓存
Default:
proxy_cache_use_stale off;
Context: http, server, location
- proxy_cache_valid:根据不同响应码自定义缓存时长
Syntax: proxy_cache_valid [code ...] time;
Default: —
Context: http, server, location
- 示例
proxy_cache_valid 200 302 10m; #响应码为200和302的缓存10分钟
proxy_cache_valid 301 1h; #响应码为301的缓存1小时
proxy_cache_valid any 1m; #剩余其他的响应码都缓存为1分钟
-
示例:
- 编辑配置文件nginx.conf
http { proxy_cache_path /cache/nginx/ levels=1:1:1 keys_zone=cache_one:32m; } location /forum/ { proxy_cache cache_one; #在该location中使用缓存 proxy_cache_valid 200 302 10m; proxy_cache_valid 301 1h; proxy_cache_valid any 1m; proxy_cache_use_stale error timeout invalid_header http_500 http_502 http_503 http_504; proxy_pass http://192.168.182.132/bbs/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; }
- 创建缓存目录
[root@centos6 html]# mkdir -p /cache/nginx [root@centos6 html]# chown -R nginx.nginx /cache/nginx
- 重新加载配置文件
[root@centos6 html]# /usr/local/nginx/sbin/nginx -s reload
- 客户端访问后就会发现在缓存目录下有缓存内容
[root@centos6 4]# ls d023d5f3c58dab7e7d48ef927f7124b6 [root@centos6 4]# pwd /cache/nginx/6/b/4 [root@centos6 4]# cat d023d5f3c58dab7e7d48ef927f7124b6