Nginx学习笔记
前几天研究百度的disconf,遇到了nginx,感觉上比haproxy要好用一些,就着手去摸得更透点,为此也查看了十来篇文档,有些写得很好:
nginx主要的使用功能:
- 反向代理服务器
- 代理缓存
- 负载均衡
- 其他功能
1.反向代理服务器
什么是反向代理服务器,我在知乎上面看到一个浅显易懂的答案
正向代理
A同学在大众创业、万众创新的大时代背景下开启他的创业之路,目前他遇到的最大的一个问题就是启动资金,于是他决定去找马云爸爸借钱,可想而知,最后碰一鼻子灰回来了,情急之下,他想到一个办法,找关系开后门,经过一番消息打探,原来A同学的大学老师王老师是马云的同学,于是A同学找到王老师,托王老师帮忙去马云那借500万过来,当然最后事成了。不过马云并不知道这钱是A同学借的,马云是借给王老师的,最后由王老师转交给A同学。这里的王老师在这个过程中扮演了一个非常关键的角色,就是代理,也可以说是正向代理,王老师代替A同学办这件事,这个过程中,真正借钱的人是谁,马云是不知道的,这点非常关键。
我们常说的代理也就是只正向代理,正向代理的过程,它隐藏了真实的请求客户端,服务端不知道真实的客户端是谁,客户端请求的服务都被代理服务器代替来请求,科学上网工具 Shadowsocks 扮演的就是典型的正向代理角色。在天朝用浏览器访问 www.google.com 时会被无情的墙掉,要想翻阅这堵墙,你可以在国外用 Shadowsocks 来搭建一台代理服务器,让代理帮我们去请求 www.google.com,代理再把请求响应结果再返回给我。
反向代理
大家都有过这样的经历,拨打10086 客服电话,一个地区的 10086 客服有几个或者几十个,你永远都不需要关心在电话那头的是哪一个,叫什么,男的,还是女的,漂亮的还是帅气的,你都不关心,你关心的是你的问题能不能得到专业的解答,你只需要拨通了10086 的总机号码,电话那头总会有人会回答你,只是有时慢有时快而已。那么这里的 10086 总机号码就是我们说的反向代理。客户不知道真正提供服务的人是谁。
反向代理隐藏了真实的服务端,当我们访问 www.baidu.com 的时候,就像拨打 10086 一样,背后可能有成千上万台服务器为我们服务,但具体是哪一台,你不知道,也不需要知道,你只需要知道反向代理服务器是谁就好了,www.baidu.com 就是我们的反向代理服务器,反向代理服务器会帮我们把请求转发到提供真实计算的服务器那里去。Nginx 就是性能非常好的反向代理服务器,它可以用来做负载均衡。
两者的区别在于代理的对象不一样,「正向代理」代理的对象是客户端,「反向代理」代理的对象是服务端
转载请注明来源:正向代理与反向代理
反向代理配置
location / { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; #设置主机头和客户端真实地址 proxy_buffering off; #禁用缓存 proxy_pass http://192.168.1.1; #设置反向代理的地址 }
- proxy_set_header : 设置主机头
- proxy_set_header X-Real_IP : 设置远程地址
- proxy_set_header X-Forwarded-For : 真实地址
- proxy_buffering : 是否启用缓存,下面会介绍
- proxy_pass : 代理地址
2.代理缓存
随着网站流量的提升,如果只是单台机器既处理静态文件,又处理动态脚本,显然效率很难上升,不能处理日益上涨的流量压力。nginx的web缓存功能的主要是由proxy_cache、fastcgi_cache指令集和相关指令集完成,proxy_cache指令负责反向代理缓存后端服务器的静态内容,fastcgi_cache主要用来处理FastCGI动态进程缓存.主要的配置项有:
http { ... // $upstream_cache_status记录缓存命中率 log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"' '"$upstream_cache_status"'; proxy_temp_path /usr/local/nginx-1.6/proxy_temp; proxy_cache_path /usr/local/nginx-1.6/proxy_cache levels=1:2 keys_zone=cache_one:100m inactive=2d max_size=2g; server { listen 80; server_name ittest.example.com; root html; index index.html index.htm index.jsp; location ~ .*\.(gif|jpg|png|html|css|js|ico|swf|pdf)(.*) { proxy_pass http://backend; proxy_redirect 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; proxy_cache cache_one; add_header Nginx-Cache $upstream_cache_status; proxy_cache_valid 200 304 301 302 8h; proxy_cache_valid 404 1m; proxy_cache_valid any 2d; proxy_cache_key $host$uri$is_args$args; expires 30d; } location ~ /purge(/.*) { #设置只允许指定的IP或IP段才可以清除URL缓存。 allow 127.0.0.1; allow 172.29.73.0/24; deny all; proxy_cache_purge cache_one $host$1$is_args$args; error_page 405 =200 /purge$1; } } }
proxy_temp_path
: 缓存临时目录。后端的响应并不直接返回客户端,而是先写到一个临时文件中,然后被rename一下当做缓存放在 proxy_cache_path 。0.8.9版本以后允许temp和cache两个目录在不同文件系统上(分区),然而为了减少性能损失还是建议把它们设成一个文件系统上。-
proxy_cache_path ...
: 设置缓存目录,目录里的文件名是 cache_key 的MD5值。levels=1:2 keys_zone=cache_one:50m
表示采用2级目录结构,Web缓存区名称为cache_one,内存缓存空间大小为100MB,这个缓冲zone可以被多次使用。文件系统上看到的缓存文件名类似于 /usr/local/nginx-1.6/proxy_cache/c/29/b7f54b2df7773722d382f4809d65029c 。inactive=2d max_size=2g
表示2天没有被访问的内容自动清除,硬盘最大缓存空间为2GB,超过这个大学将清除最近最少使用的数据。 -
proxy_cache
: 引用前面定义的缓存区 cache_one proxy_cache_key
: 定义cache_keyproxy_cache_valid
: 为不同的响应状态码设置不同的缓存时间,比如200、302等正常结果可以缓存的时间长点,而404、500等缓存时间设置短一些,这个时间到了文件就会过期,而不论是否刚被访问过。expires
: 在响应头里设置Expires:
或Cache-Control:max-age
,返回给客户端的浏览器缓存失效时间。
关于缓存的失效期限上面有三个选项:X-Accel-Expires
、inactive
、proxy_cache_valid
、expires
,它们之间是有优先级的,按上面的顺序如果在header里设置 X-Accel-Expires 则它的优先级最高,否则inactive优先级最高。
清除缓存
上述配置的proxy_cache_purge
指令用于方便的清除缓存,但必须按照第三方的 ngx_cache_purge 模块才能使用,项目地址:https://github.com/FRiCKLE/ngx_cache_purge/ 。
使用 ngx_cache_purge 模块清除缓存有2种办法(直接删除缓存目录下的文件也算一种办法):
-
echo发送PURGE指令
proxy_cache_purge PURGE from 127.0.0.1
表示只允许在来自本地的清除指令# echo -e 'PURGE / HTTP/1.0\r\n' | nc 127.0.0.1 80
-
GET方式请求URL
即使用配置文件中的location ~ /purge(/.*)
,浏览器访问http://ittest.example.com/purge/your/may/path
来清除缓存,或者echo -e 'GET /purge/ HTTP/1.0\r\n' | nc ittest.example.com 80
3.负载均衡
nginx有多种负载均衡算法
轮询
(默认) : 每个请求按时间顺序逐一分配到不同的后端服务器,如果后端某台服务器宕机,故障系统被自动剔除,使用户访问不受影响。Weight 指定轮询权值,Weight值越大,分配到的访问机率越高,主要用于后端每个服务器性能不均的情况下。ip_hash
: 每个请求按访问IP的hash结果分配,这样来自同一个IP的访客固定访问一个后端服务器,有效解决了动态网页存在的session共享问题。当然如果这个节点不可用了,会发到下个节点,而此时没有session同步的话就注销掉了。least_conn
: 请求被发送到当前活跃连接最少的realserver上。会考虑weight的值。url_hash
: 此方法按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,可以进一步提高后端缓存服务器的效率。Nginx本身是不支持url_hash的,如果需要使用这种调度算法,必须安装Nginx 的hash软件包 nginx_upstream_hash 。fair
: 这是比上面两个更加智能的负载均衡算法。此种算法可以依据页面大小和加载时间长短智能地进行负载均衡,也就是根据后端服务器的响应时间来分配请求,响应时间短的优先分配。Nginx本身是不支持fair的,如果需要使用这种调度算法,必须下载Nginx的 upstream_fair 模块。
配置示例:
upstream backend { ip_hash; server 172.29.88.226:8080 weight 2; server 172.29.88.226:8080 weight=1 max_fails=2 fail_timeout=30s ; server 172.29.88.227:8080 backup; } server { location / { proxy_pass http://backend; proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504; }
weight
: 轮询权值也是可以用在ip_hash的,默认值为1max_fails
: 允许请求失败的次数,默认为1。当超过最大次数时,返回proxy_next_upstream 模块定义的错误。fail_timeout
: 有两层含义,一是在 30s 时间内最多容许 2 次失败;二是在经历了 2 次失败以后,30s时间内不分配请求到这台服务器。backup
: 预留的备份机器。当其他所有的非backup机器出现故障的时候,才会请求backup机器,因此这台机器的压力最轻。(为什么我的1.6.3版本里配置backup启动nginx时说invalid parameter "backup"
?)-
max_conns
: 限制同时连接到某台后端服务器的连接数,默认为0即无限制。因为queue
指令是commercial,所以还是保持默认吧。 -
proxy_next_upstream
: 这个指令属于 http_proxy 模块的,指定后端返回什么样的异常响应时,使用另一个realserver
4.其他功能
Nginx本身不支持PHP等语言,但是它可以通过FastCGI来将请求扔给某些语言或框架处理()例如PHP、Python、Perl)
Nginx还支持虚拟主机,可以当做多个域名的服务器,这些都只是稍微看下,待续...
参考文章: http://blog.csdn.net/hechurui/article/details/51065508
http://www.cnblogs.com/meteoric_cry/archive/2011/05/14/2046263.html