Nie&Gao
Anyway, life is elsewhere and we all know it.
「Nginx」
正向代理服务器是一个为用户(user)转发请求(http request)到Internet上的服务器的中介服务器。而反向代理服务器reverse proxy server 是代理服务器的特例,它代理的用户是公司的后端服务器。当反向代理服务器收到来自internet上的请求时候,它转发请求到公司内部网络的上游服务器,并将从服务器上返回的结果返回给用户。此时反向代理服务器对外表现就是一个服务器。
反向代理服务器的作用:
-
负载均衡
-
网络加速
2.1 cache2.2 compress inbound and outbound data
2.3 perform additional taks such as SSL encrpyion to take load off of your web servers.
-
安全和匿名
一个反向代理服务器通常具有的功能 : 负载均衡 + 反向代理 + 页面缓存
1. 负载均衡
upstream是Nginx的HTTP Upstream模块,这个模块通过一个简单的调度算法来实现客户端IP到后端服务器的负载均衡。
upstream 支持的负载均衡算法:
Nginx的负载均衡模块目前支持4种调度算法,其中后两项属于第三方调度算法。
- 轮询(默认)。每个请求按时间顺序逐一分配到不同的后端服务器,如果后端某台服务器宕机,故障系统被自动剔除,使用户访问不受影响。Weight 指定轮询权值,Weight值越大,分配到的访问机率越高,主要用于后端每个服务器性能不均的情况下。
- ip_hash。每个请求按访问IP的hash结果分配,这样来自同一个IP的访客固定访问一个后端服务器,有效解决了动态网页存在的session共享问题。
- fair。这是比上面两个更加智能的负载均衡算法。此种算法可以依据页面大小和加载时间长短智能地进行负载均衡,也就是根据后端服务器的响应时间来分配请求,响应时间短的优先分配。Nginx本身是不支持fair的,如果需要使用这种调度算法,必须下载Nginx的upstream_fair模块。
- url_hash。此方法按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,可以进一步提高后端缓存服务器的效率。Nginx本身是不支持url_hash的,如果需要使用这种调度算法,必须安装Nginx 的hash软件包。
2. 反向代理
- proxy_pass 此配置项将当前请求反向代理到URL参数指定的服务器上,URL可以是主机名or IP地址加端口形式
- proxy_method Nginx会将上游服务器的响应转发给客户端,但默认不会转发以下HTTP头部字段:Date, Server,X-Pad 和X-Access-*。
- proxy_hide_header 使用proxy_hide_header后可以任意地指定那些HTTP头部字段不能被转发。
- proxy_pass_header 与proxy_hide_header相反,proxy_pass_header会将原来禁止转发的header设置为允许转发。
- proxy_set_header
设置请求头并将请求头信息传递给服务器端。
使用场景:需要获取用户IP地址,比如做异地登录判断,或者统计IP访问次数等。通常情况下可以在后端使用request.getRemoteAddr()获取客户端ip,但是当我们使用nginx做反向代理后,使用request.getRemoteAddr() 获取到的就是nginx的ip地址。但是,nginx是可以获得用户的真实ip的,也就是说nginx使用$remote_addr变量时获得的是用户的真实ip,如果我们想要在web端获得用户的真实ip,就必须在nginx这里作一个赋值操作,如下:
proxy_set_header X-real-ip $remote_addr;
其中这个X-real-ip是一个自定义的变量名,名字可以随意取,这样做完之后,用户的真实ip就被放在X-real-ip这个变量里了,然后,在web端可以这样获取:request.getHeader("X-real-ip")
3. 页面缓存
nginx为了实现页面缓存的需求而增加了一个ngx_http_proxy_module模块。http://nginx.org/en/docs/http/ngx_http_proxy_module.html
关于页面缓存
静态资源,比如新闻等这类基本不变化的页面,提供一个静态页面缓存机制,避免每次都动态拉取数据渲染生成HTML. 总体原则:应用服务器(tomcat)不处理静态资源的缓存,由前端缓存来处理。前端缓存主要包括Nginx缓存,CDN缓存,浏览器缓存。这些缓存都是针对HTTP请求和相应的静态HTML资源。所以都是遵循HTTP协议中关于缓存的控制的。应用通过HTTP head 控制前端静态资源缓存的缓存时间和机制。应用服务器这边缓存的是数据(redis等cache),而不是静态页面。这样的好处是系统的边界和职责更加明确,也不需要再次实现一套静态资源缓存机制。[2]
缓存及时清理出现问题。目前清理Nginx缓存两种方式:
-
手动清理proxy_cache_path目录,重启Nginx服务
-
使用proxy_cache_purge模块清空。需要安装此模块。推荐
主要配置: - proxy_cache:指定用于页面缓存的共享内存
- proxy_cache_bypass:定义nginx不从缓存取响应的条件
- proxy_no_cache: 定义nginx不将响应写入缓存的条件。可以和proxy_cache_bypass指令一起使用
- proxy_cache_key:定义如何生成缓存的键
- proxy_cache_path:设置缓存的路径和其他参数。缓存数据是保存在文件中的,缓存的键和文件名都是在代理URL上执行MD5的结果
- proxy_cache_use_stale:如果后端服务器出现状况,nginx是可以使用过期的响应缓存的
- proxy_cache_valid:为不同的响应状态码设置不同的缓存时间
- proxy_store:开启将文件保存到磁盘上的功能
- proxy_store_access: 设置缓存目录和文件的访问权限
### 配置文件
#user nobody;
worker_processes 1;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
proxy_buffering on;
#在日志格式中加入$upstream_cache_status
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent $request_body "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"'
'"$upstream_cache_status" $request_time';
# Begin Proxy Cache Config
# keys_zone=cache:1024m 表示这个zone名称为cache,分配的内存大小为1024MB
# D:/data/nginx/cache 表示cache这个zone的文件要存放的目录
# levels=1:2 表示缓存目录的第一级目录是1个字符,第二级目录是2个字符,即/usr/local/nginx/proxy_cache_dir/cache1/a/1b这种形式
# inactive=1d 表示这个zone中的缓存文件如果在1天内都没有被访问,那么文件会被cache manager进程删除掉
# max_size=10g 表示这个zone的硬盘容量为10GB
proxy_cache_path D:/data/nginx/cache levels=1:2 keys_zone=cache:1024m max_size=1g;
proxy_temp_path D:/data/nginx/proxy_temp 1 2;
#设置缓存的key
# Putting the host name in the cache key allows different virtual hosts to share the same cache zone
proxy_cache_key "$scheme://$host$request_uri";
# Pass some client identification headers back to the backend_server
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# Cache different return codes for different lengths of time
# We cached normal pages for 10 minutes
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;
server_names_hash_bucket_size 64;
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
gzip on;
## 反向代理-设置代理的后端tomcat集群
upstream web_server{
ip_hash;
server 10.14.138.164 max_fails=2 fail_timeout=3s;
server 10.14.135.242:8080 max_fails=2 fail_timeout=3s;
}
## 反向代理
server {
listen 80;
server_name gsm.com;
add_header Server-Address $server_addr;
# $upstream_cache_status表示资源缓存的状态,有HIT MISS EXPIRED UPDATING STALE BYPASS几种状态
add_header Nginx-Cache $upstream_cache_status;
# nginx的proxy_cache不支持if判断,所以规定/cache的走缓存
location ~/cache {
proxy_cache cache;
# 也可以单独配缓存失效时间
# proxy_cache_valid 200;
# # If it's not in the cache pass back to the backend-server
proxy_pass http://web_server;
}
# Proxy all remaining content to the backend-server
location / {
proxy_pass http://web_server;
}
error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
参考
- 深入理解Nginx 陶辉[著] 出版社: 机械工业出版社
- http://blog.arganzheng.me/posts/http-caching.html
- http://seanlook.com/2015/06/02/nginx-cache-check/
- Nginx 查看命中率 http://www.361way.com/nginx-cache/2665.html