nginx 代理服务器
Nginx是一款轻量级的高性能的Web 服务器、反向代理服务器及电子邮件(IMAP/POP3)代理服务器
正向代理
正向代理,是一个位于客户端和原始服务器(origin server)之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标(原始服务器),然后代理向原始服务器转交请求并将获得的内容返回给客户端。客户端才能使用正向代理。
正向代理的典型用途是为在防火墙内的局域网客户端提供访问Internet的途径。正向代理还可以使用缓冲特性(由mod_cache提供)减少网络使用率。
通过正向代理访问任意网站并且隐藏客户端自身
反向代理
反向代理(Reverse Proxy)方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给internet上请求连接的客户端,此时代理服务器对外就表现为一个反向代理服务器。
CDN
称是Content Delivery Network,即内容分发网络。其基本思路是尽可能避开互联网上有可能影响数据传输速度和稳定性的瓶颈和环节,使内容传输的更快、更稳定。通过在网络各处放置反向代理节点服务器所构成的在现有的互联网基础之上的一层智能虚拟网络,CDN系统能够实时地根据网络流量和各节点的连接、负载状况以及到用户的距离和响应时间等综合信息将用户的请求重新导向离用户最近的服务节点上。其目的是使用户可就近取得所需内容,解决 Internet网络拥挤的状况,提高用户访问网站的响应速度
nginx最大连接数配置
为了让Nginx支持更多的并发连接数,根据实际情况对工作线程数和每个工作线程支持的最大连接数进行调整。例如设置"worker_processes 10"和"worker_connections 1024",那这台服务器支持的最大连接数就是10×1024=10240。
worker_processes 10;
events {
use epoll;
worker_connections 10240;
}
访问控制配置
涉及模块:ngx_http_access_module
模块概述:允许限制某些 IP 地址的客户端访问。
- allow
语法: allow address | CIDR | unix: | all;
默认值: —
作用域: http, server, location, limit_except
允许某个 IP 或者某个 IP 段访问
*deny
语法: deny address | CIDR | unix: | all;
默认值: —
作用域: http, server, location, limit_except
禁止某个 IP 或者一个 IP 段访问。
配置范例
location / {
deny192.168.1.1;
allow192.168.1.0/24;
allow10.1.1.0/16;
allow2001:0db8::/32;
deny all;
}
IPv4 的网络中只有 10.1.1.0/16 和 192.168.1.0/24 允许访问,但 192.168.1.1 除外;对于 IPv6 的网络,只有 2001:0db8::/32 允许访问。
响应的速率限制
limit_rate_after和 limit_rate配合使用表示在下载的文件大小达到设定数后开启限速效果(逐渐降速)。
-
limit_rate
语法: limit_rate rate;
默认值: limit_rate 0;
作用域: http, server, location, if in location
命令概述:限制向客户端传送响应的速率限制。参数 rate 的单位是字节/秒,设置为 0 将关闭限速。 nginx 按连接限速,所以如果某个客户端同时开启了两个连接,那么客户端的整体速率是这条指令设置值的 2 倍。 - limit_rate_after
语法: limit_rate_after size;
默认值: limit_rate_after 0;
作用域:http, server, location, if in location
命令概述:设置不限速传输的响应大小。当传输量大于此值时,超出部分将限速传送。
实现并发连接数限制的具体配置
这个的配置是基于 ngx_http_limit_zone_module 模块的,要简单完成并发限制,我们要涉及到 limit_conn_zone 和 limit_conn 这两个指令:
-
limit_conn_zone
语法: limit_conn_zone zone_name $variable the_size
作用域: http
本指令定义了一个数据区,里面记录会话状态信息。 variable 定义判断会话的变量;the_size 定义记录区的总容量。 - limit_conn
语法: limit_conn zone_name the_size
作用域: http, server, location
指定一个会话最大的并发连接数。 当超过指定的最发并发连接数时,服务器将返回 "Service unavailable" (503)
配置示例
http {
limit_conn_zone $binary_remote_addr zone=one:10m;
...
server {
...
location /seven/ {
limit_conn one 1;
.....
}
定义一个叫“one”的记录区,总容量为 10M,以变量 $binary_remote_addr 作为会话的判断基准(即一个地址一个会话)。 限制 /seven/ 目录下,一个会话只能进行一个连接。 简单点,就是限制 /seven/ 目录下,一个 IP 只能发起一个连接,多过一个,一律 503。
$binary_remote_addr 的长度为 4 bytes,会话信息的长度为 32 bytes。 当 zone 的大小为 1M 的时候,大约可以记录 32000 个会话信息(一个会话占用 32 bytes)。
http {
limit_rate 500k; #每个连接的速度限制,0表示取消限制
limit_rate_after 800k; #大于500K才进行限速
limit_zone to_vhost $server_name 1m; #每个域名的总带宽限制
limit_conn to_vhost 30; #每个连接可以开多少个线程
}
limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s模块开启对单个ip、单个会话在单位时间内请求的限制。这里zone和limit_conn_zone模块一样,rate表示限制的速率,1r/s表示一秒之内最多1次请求,也可以用5r/m,表示一分钟之内最多5次请求。limit_req_zone同样配置在http配置段。与limit_req指令配合使用才生效。limit_req zone=one burst=5表示该location段使用one定义的limit_req_zone,如果请求数超过 rate=1r/s,剩下的请求将被延迟处理,如果请求数超过burst定义的数量,多余的请求则直接返回503错误。
如果开启nodelay,则超过rate=1r/s的请求直接返回503,不再延迟处理。
详细的官方规则:
http://wiki.nginx.org/NginxChsHttpLimit_zoneModule
DDOS 预防配置
DDOS 的特点是分布式,针对带宽和服务***,也就是四层流量***和七层应用***,相应的防御瓶颈四层在带宽,七层的多在架构的吞吐量。对于七层的应用***,我们还是可以做一些配置来防御的,使用 nginx 的 http_limit_conn 和 http_limit_req 模块通过限制连接数和请求数能相对有效的防御。
ngx_http_limit_conn_module 可以限制单个 IP 的连接数
ngx_http_limit_req_module 可以限制单个 IP 每秒请求数
主动防御
-
限制每秒请求数
涉及模块:ngx_http_limit_req_module
通过漏桶原理来限制单位时间内的请求数,一旦单位时间内请求数超过限制,就会返回 503 错误。
配置范例:http {
limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s;
...
server {
...
location ~ .php$ {
limit_req zone=one burst=5 nodelay;
}
}
}
配置说明:
$binary_remote_addr 二进制远程地址
rate=10r/s; 限制频率为每秒 10 个请求
burst=5 允许超过频率限制的请求数不多于 5 个,假设 1、2、3、4 秒请求为每秒 9 个,那么第 5 秒内请求 15 个是允许的;反之,如果第一秒内请求 15 个,会将 5 个请求放到第二秒,第二秒内超过 10 的请求直接 503,类似多秒内平均速率限制。
nodelay 超过的请求不被延迟处理,设置后 5(不延时)+10(延时)个请求在 1 秒内处理。(这只是理论数据,最多的情况)
-
限制 IP 连接数
http { limit_conn_zone $binary_remote_addr zone=addr:10m; ... server { ... location /操作目录/ { limit_conn addr 1; } } }
被动防御方法
封IP地址
访问者通过浏览器正常访问网站,与服务器建立的连接一般不会超过20个,我们可以通过脚本禁止连接数过大的IP访问。以下脚本通过netstat命令列举所有连接,将连接数最高的一个IP如果连接数超过150,则通过 iptables阻止访问:
#!/bin/sh
status=`netstat -na|awk '$5 ~ /[0-9]+:[0-9]+/ {print $5}' |awk -F ":" -- '{print $1}' |sort -n|uniq -c |sort -n|tail -n 1`
NUM=`echo $status|awk '{print $1}'`
IP=`echo $status|awk '{print $2}'`
result=`echo "$NUM > 150" | bc`
if [ $result = 1 ]
then
echo IP:$IP is over $NUM, BAN IT!
/sbin/iptables -I INPUT -s $IP -j DROP
fi
运行crontab -e,将上述脚本添加到crontab每分钟自动运行:
* * * * * /root/xxxx.sh
长连接nginx配置:
http://nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive
用法: keepalive connections;
upstream http_backend {
server 127.0.0.1:8080;
keepalive 16;
}
server {
...
location /http/ {
proxy_pass http://http_backend;
proxy_http_version 1.1;
proxy_set_header Connection "";
...
}
}
connections 连接到上游服务器的最大并发空闲keepalive长连接数(默认是未设置)当这个数被超过时,使用"最近最少使用算法(LUR)"来淘汰并关闭连接
http://nginx.org/en/docs/http/ngx_http_core_module.html#keepalive_requests
用法:keepalive_requests number;
设置通过"一个存活长连接"送达的最大请求数(默认是100,建议根据客户端在"keepalive"存活时间内的总请求数来设置) 当送达的请求数超过该值后,该连接就会被关闭。
keepalive_requests 8192;
http://nginx.org/en/docs/http/ngx_http_core_module.html#keepalive_timeout
用法:keepalive_timeout timeout [header_timeout];
第一个参数设置"keep-alive客户端长连接"将在"服务器端"继续打开的超时时间 可选的第二个参数设置“Keep-Alive: timeout=time”响应头字段的值
http {
keepalive_timeout 20; --长连接timeout
keepalive_requests 8192; --每个连接最大请求数
}
配置Nginx的负载均衡与分发策略
通过在upstream参数中添加的应用服务器IP后添加指定参数即可实现,如:
upstream tomcatserver1 {
server 192.168.72.49:8080 weight=3;
server 192.168.72.49:8081;
}
server {
listen 80;
server_name 8080.max.com;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
proxy_pass http://tomcatserver1;
index index.html index.htm;
}
}
通过以上配置,便可以实现,在访问8080.max.com这个网站时,由于配置了proxy_pass地址,所有请求都会先通过nginx反向代理服务器,在服务器将请求转发给目的主机时,读取upstream为 tomcatsever1的地址,读取分发策略,配置tomcat1权重为3,所以nginx会将大部分请求发送给49服务器上的tomcat1,也就是8080端口;较少部分给tomcat2来实现有条件的负载均衡,当然这个条件就是服务器1、2的硬件指数处理请求能力。
upstream myServer {
server 192.168.72.49:9090 down;
server 192.168.72.49:8080 weight=2;
server 192.168.72.49:6060;
server 192.168.72.49:7070 backup;
}
down 表示单前的server暂时不参与负载
Weight 默认为1.weight越大,负载的权重就越大。
max_fails 允许请求失败的次数默认为1.当超过最大次数时,返回proxy_next_upstream 模块定义的错误
fail_timeout max_fails 次失败后,暂停的时间。
Backup 其它所有的非backup机器down或者忙的时候,请求backup机器。所以这台机器压力会最轻。
使用Nginx的高可用
负载均衡服务器也需要高可用,以防如果负载均衡服务器挂掉了,后面的应用服务器也紊乱无法工作。
实现高可用的方案:添加冗余。添加n台nginx服务器以避免发生上述单点故障keepalive+nginx实现负载均衡高可用
主备机上都运行高可用(High Availability)监控程序,通过传送心跳信息来监控对方的运行状况。当备份机不能在一定的时间内收到对方的正常心跳时,它就接管主服务器的服务IP并继续提供负载均衡服务;当备份管理器又从主管理器收到“I am alive”这样的信息时,它就释放服务IP地址,这样的主服务器就开始再次提供负载均衡服务。
1.提供两个Nginx负载服务器
2.分别在两台服务器上安装keepalived
3、配置keepalived
虚拟IP指向A和B,当A宕机时,虚拟IP漂移到B上,A启起来后自动成为master
通过对两台服务器的keepalive进行配置,区分出主机和备机服务器,state MASTER 为主机,priority 优先级值大于备机,state BACKUP为备机。
Nginx的缓存
nginx的http_proxy模块,可以实现类似于Squid的缓存功能。Nginx对客户已经访问过的内容在Nginx服务器本地建立副本,这样在一段时间内再次访问该数据,就不需要通过Nginx服务器再次向后端服务器发出请求,所以能够减少Nginx服务器与后端服务器之间的网络流量,减轻网络拥塞,同时还能减小数据传输延迟,提高用户访问速度。同时,当后端服务器宕机时,Nginx服务器上的副本资源还能够回应相关的用户请求。
nginx 目录索引
auto_index
直接映射到目录/home/test
location /home/test {
root /;
autoindex on; #开启
autoindex_localtime on; #开启显示功能
autoindex_exact_size off;
autoindex_format html;
}
映射到目录/home
location /home {
root /;
rewrite ^/home/(.*)$ /home/$1 break;
autoindex on; #开启
autoindex_localtime on; #指定目录列表中时间是本地时区显示还是 UTC
autoindex_exact_size off; #autoindex_exact_size :对于 HTML 输出格式,指定是否准确的输出文件的大小
autoindex_format html; #设置目录列表的输出格式 autoindex_format html | xml | json | jsonp;
}
或者
location /home/eyou/Downloads {
alias /home/;
fancyindex on; #开启fancy索引
fancyindex_exact_size off; # 不使用精确大小,使用四舍五入
fancyindex_default_sort date_desc;
fancyindex_localtime on; # 使用本地时间
}
或者
location / {
root /home/eayou;
fancyindex on; #开启fancy索引
fancyindex_exact_size off; # 不使用精确大小,使用四舍五入
fancyindex_default_sort date_desc;
}
fancyindex
由于nginx自带的文件索引服务功能比较单一,所以一般采用Fancy Index插件,Ubuntu下安装Fancy Index插件的方法是
sudo apt-get install nginx-extras
location /test/ {
root /;
rewrite ^/test/(.*)$ /home/$1 break;
fancyindex on; #开启fancy索引
fancyindex_exact_size off; # 不使用精确大小,使用四舍五入
fancyindex_default_sort date_desc;
fancyindex_localtime on; # 使用本地时间
fancyindex_footer "myfooter.shtml"; #当前路径下的myfooter.shtml内容作为底部
}
nginx进行重定向Redirect
配置:
location /home/test-redirect {
rewrite ^/home/test-redirect/(.*) https://www.baidu.com$1 redirect;
}
访问127.0.0.1/home/test-redirect跳转到https://www.baidu.com, 返回状态码是 302 Moved Temporarily
强制将http转换到https链接
rewrite ^(.*)$ https://$host$1 permanent;
防盗链
不想让别人调用自己的图片,一是因为个人版权的问题,再一点就是会增加服务器的负载、还会产生一些没必要的流量。
对gif、jpg、png、swf、flv后缀的文件实行防盗链
location ~* \.(gif|jpg|png|swf|flv)$ {
valid_referers none blocked www.kenmy.com kenmy.com ;
if ($invalid_referer) {
rewrite ^/ http://www.kenmy.com/retrun.html;
#return 403;
}
}
第一行:gif|jpg|png|swf|flv
表示对gif、jpg、png、swf、flv后缀的文件实行防盗链
第二行: 表示对www.kenmy.com、kenmy.com 这2个来路进行判断
if{}里面内容的意思是,如果来路不是指定来思是,如果来路不是指定来路就跳转到http://www.kenmy.com/retrun.html页面,当然直接返回403也是可以的。
针对图片目录防止盗链
location /images/ {
alias /data/images/;
valid_referers none blocked server_names *.xok.la xok.la ;
if ($invalid_referer) {return 403;}
}
负载均衡
http {
upstream myproject {
server 127.0.0.1:8000 weight=3;
server 127.0.0.1:8001;
server 127.0.0.1:8002;
server 127.0.0.1:8003;
}
server {
listen 80;
server_name www.domain.com;
location / {
proxy_pass http://myproject;
}
}
}
检查配置文件是否正确
nginx -t #结果显示ok和success没问题便可重启
重启nginx
nginx -s reload
nginx HTTP基础功能
灵活简单的配置;
处理静态文件,索引文件以及自动索引;
反向代理加速,简单的负载均衡和容错;
模块化的结构。过滤器包括gzipping, byte ranges, chunked responses, 以及 SSI-filter 。
SSL 和 TLS SNI 支持;
支持 keep-alive 和管道连接;
重新配置和在线升级而无须中断客户的工作进程;
可定制的访问日志,日志写入缓存,以及快捷的日志回卷;
4xx-5xx 错误代码重定向;
基于 PCRE 的 rewrite 重写模块;
带宽限制
nginx优点
-
占用CPU内存少,并发能力强
-
支持负载均衡,支持容错和健康检查
- 支持热部署,启动速度快,可以在不间断服务的情况下对软件和配置进行升级
-
-
提高访问速度
起到了缓存的作用,尤其对于热门站点能明显提高请求速度。 -
防火墙作用(访问安全控制)
可在代理服务器上设限,过滤某些不安全信息。防止外网对内网服务器的恶性*** - 通过代理服务器访问不能访问的目标站点
互联网上有许多开发的代理服务器,客户机在访问受限时,可通过不受限的代理服务器访问目标站点,通俗说,我们使用的×××浏览器就是利用了代理服务器
nginx负载均衡的作用
1、转发功能
按照一定的算法,将客户端请求转发到不同应用服务器上,提高系统并发量
分发策略有轮询、权重、ip_哈希算法
权重:指定轮询几率,权重和访问比率成正比,用于应用服务器性能不均的情况。
每个请求按访问ip的hash结果分配,这样每个访客固定访问一个应用服务器,可以解决session共享的问题。
2、故障移除(通过心跳检测的方式,判断应用服务器当前是否可以正常工作,如果服务器期宕掉,自动将请求发送到其他应用服务器)
3、恢复添加(如检测到发生故障的应用服务器恢复工作,自动将其添加到处理用户请求队伍中)