Nginx 常规用法
Nginx简介
Nginx是一个高性能的HTTP和反向代理web服务器,同时也提供了IMAP/POP3/SMTP服务。Nginx是由伊戈尔·赛索耶夫为俄罗斯访问量第二的Rambler.ru站点(俄文:Рамблер)开发的,第一个公开版本0.1.0发布于2004年10月4日。2011年6月1日,nginx 1.0.4发布。
其特点是占有内存少,并发能力强,事实上nginx的并发能力在同类型的网页服务器中表现较好,中国大陆使用nginx网站用户有:百度、京东、新浪、网易、腾讯、淘宝等。在全球活跃的网站中有12.18%的使用比率,大约为2220万个网站。
Nginx 是一个安装非常的简单、配置文件非常简洁(还能够支持perl语法)、Bug非常少的服务。Nginx 启动特别容易,并且几乎可以做到7*24不间断运行,即使运行数个月也不需要重新启动。你还能够不间断服务的情况下进行软件版本的升级。
Nginx代码完全用C语言从头写成。官方数据测试表明能够支持高达 50,000 个并发连接数的响应。
Nginx作用
Nginx有三大作用
- 反向代理
- 负载均衡
- 静动分离
反向代理
正向代理,类似于玩Steam开加速器或者梯子,代理客户端
反向代理,服务器网站代理,代理服务器,不知道真实的服务器IP,类似百度,只知道域名
负载均衡
轮询,服务器请求分配均匀
加权轮询,根据权限比分配服务器请求
静动分离
将静态资源如css,js,图片,动图等放入Nginx,让Nginx渲染资源
安装Nginx
Docker
安装nginx
拉镜像
docker pull nginx
Run一个临时容器拷贝文件
docker run --name nginx -p 8080:80 -d nginx
nginx
配置文件目前都在/etc/nginx/conf.d/*.conf
,因为nginx.conf
的配置文件都指向了这个目录。查看nginx.conf
配置docker exec -it nginx cat /etc/nginx/nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
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 on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
}
拷贝配置文件
mkdir -p /docker/data/nginx
#配置文件
docker cp nginx:/etc/nginx/conf.d /docker/data/nginx
#静态资源-html/js/css
docker cp nginx:/usr/share/nginx/html /docker/data/nginx/staticfile
移除测试容器
docker rm -f nginx
Run容器,8082是自定义端口,可自行添加和配置
docker run -d \
-p 8081:80 \
-p 8082:8082 \
--name nginx \
-v /docker/data/nginx/conf.d:/etc/nginx/conf.d \
-v /docker/data/nginx/staticfile:/usr/share/nginx \
nginx
访问http://192.168.1.5:8081/
,这是conf.d
目录的default.conf
配置文件监听了80端口访问默认界面
Nginx配置
在/docker/data/nginx/conf.d
中新建一个myapp.conf
的配置文件(名字可以自定义)。可以添加以下配置。
正常配置
server {
listen 8080;
server_name location;
#set $root /usr/share/nginx;
#root $root;
#设置字符集
charset utf-8;
location / {
charset utf-8;
root html;
index index.html index.htm;
# 本机的8080请求都转发至http://192.168.1.5:8080
proxy_pass http://192.168.1.5:8080;
# 请求头
# 真实的客户端IP
proxy_set_header X-Real-IP $remote_addr;
# 请求头中Host+Port信息
proxy_set_header Host $host:$proxy_port;
# 代理路由信息,此处取IP有安全隐患
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# 真实的用户访问协议
proxy_set_header X-Forwarded-Proto $scheme;
# 编码
proxy_set_header Accept-Encoding "";
}
#不同路由走不同的服务器
location /app {
proxy_pass http://192.168.1.6:8080/app;
}
#报错html界面响应
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
# json响应
error_page 500 502 503 504 /respon_500.json;
location = /respon_500.json {
default_type application/json;
return 403 '{"code":"500","status":"error","message":"Server Error"}';
}
}
负载均衡
#三台机器随机分配资源
upstream myapp {
server 192.168.0.100:8088;
server 192.168.0.101:8088;
server 192.168.0.102:8088;
}
#三台机器均匀分配资源
upstream myapp2 {
server 192.168.0.100:8088 weight=1;
server 192.168.0.101:8088 weight=1;
server 192.168.0.102:8088 weight=1;
}
#第三台访问次数最多,等于1+2的总和
upstream myapp3 {
server 192.168.0.100:8088 weight=1;
server 192.168.0.101:8088 weight=2;
server 192.168.0.102:8088 weight=3;
}
# ip_hash是将每个请求按照访问ip的hash结果进行分配,这种方式可以保证同一个用户会固定访问一个后端服务器。优点:可以保证session会话,解决服务器之间session不能共享的问题。
# 一旦使用了ip_hash,当我们需要移除一台服务器的时候,不能直接删除这个配置项,而是需要在这台服务器配置后面加上关键字down,表示不可用。因为如果直接移除配置项,会导致hash算法发生更改,后续所有的请求都会发生混乱。
upstream myapp4 {
ip_hash;
server 192.168.0.100:8080;
server 192.168.0.101:8080;
server 192.168.0.102:8080 down;
}
server {
listen 8082;
server_name location;
location / {
proxy_pass http://myapp;
#当访问其中一台节点挂了,尝试连接另一台节点的时间间隔
proxy_connect_timeout 1s;
}
}
负载均衡关键字
resolver 10.0.0.1;
upstream myapp {
server 192.168.0.100:8080;
server 192.168.0.101:8080 down;
server 192.168.0.102:8080 backup;
server 192.168.136.136:8000 slow_start=30s;
server 192.168.136.136:8080 max_conns = 1024;
server 192.168.136.136:8081 max_conns=1024 max_fails=3 fail_timeout=10 slow_start=30s;
server example.com resolve;
queue 100 timeout=70; #此参数可以不加
}
- down:说明服务器暂不可用,用来标识某台服务器不参与负载均衡,该状态的使用场景是某台服务器需要停机维护时设置为down,或者发布新功能时
- backup:用来标识将该服务器视作备份服务器,当主服务器不能工作时,备份服务器会开启工作
- slow_start:设置时间段,在此期间服务器将从0到正常值逐渐恢复它的权重,当服务器从不健康变成健康,或者服务器从被标记为不可到达一段时间后变成可到达时。默认值是0, 表示关闭缓慢启动功能。
- max_conns:用来设置最大活动链接数,当设置为 0 时,标识不限制最大活动链接。如果设置了queue,当max_conns最大连接数达到max_conns限制值,请求将会排放到一队列中,队列由queue指令设置其容纳请求的最大数量。以上例为例,backend1最大连接数为1024,超出则存放在队列中,当队列已满100请求数而此时又没有可选的上游服务器处理时,如果设置了timeout可选性参数,超出此timeout时间,则客户端会收到错误提示
- max_fails/fail_timeout :两个参数是配合使用的,max_fails = number 是指:设置允许请求代理服务器最大的失败次数。 fail_timeout 是指:代理服务器在经过 max_fails =number 次失败后,服务器暂停的时间,单位为秒,默认10秒。如果192.168.136.136:8081被请求时,达到了最大失败次数3次,则服务器会暂停10秒【之前的三次请求由代理服务器完成正常响应】,也就是说在这10秒内,无法访问主服务器,如果10秒后主服务器恢复正常,则主服务器继续工作,如果10秒依旧无法正常工作,则继续由备份服务器工作。
- resolve:监视域名对应的服务器IP地址的变化,并自动修改upstream配置而不需要重启nginx服务器(1.5.12版本)。
动静分离
这个需要nginx容器中存在静态文件,直接访问nginx的静态文件,不访问服务器资源。
server {
#set $root /usr/share/nginx;
#root $root;
location /webTestProject/ {
root /usr/myTestData/;
}
location /image/ {
root /static;
#设置缓存的过期时间为1小时
expires 1h;
# 浏览器访问展现目录结构
autoindex on;
}
location ~ .*\.(htm|html|ico|gif|jpg|jpeg|png|bmp|swf|ioc|rar|zip|txt)$ {
root /static;
expires 30d;
}
location ~ .*\.(js|css)?$ {
root /static;
expires 1h;
}
#error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
Nginx 限流
Nginx 限流方式:
- 连接数限速:ngx_http_limit_conn_module用来限制单位时间内的请求数,即速率限制,采用的漏桶算法 "leaky bucket"
- 按请求速率限速:ngx_http_limit_req_module用来限制同一时间连接数,即并发限制
- server max_conns:服务端IP限流,参考上面
负载均衡关键字
文档
其中ngx_http_limit_conn_module
模块可以根据源IP限制单用户并发访问的连接数或连接到该服务的总并发连接数
示例
limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s;
limit_req_zone $binary_remote_addr $uri zone=two:10m rate=1r/s; # $uri:不带客户端请求参数
limit_req_zone $binary_remote_addr $request_uri zone=thre:10m rate=1r/s; # $request_uri:带客户端请求参数
limit_req_status 503; #配置被限流后返回的状态码,默认返回503,此配置可以定义在server级别,也可以定义location 级别
limit_conn_zone $binary_remote_addr zone=one:10m;
limit_conn_zone $server_name zone=perserver:10m;
limit_conn_status 503;
limit_conn_log_level error; #配置记录被限流后的日志级别,默认error级别
server {
location /search/ {
limit_conn one 100;
limit_req zone=one burst=5 nodelay;
}
第一段配置
- limit_req_zone和limit_conn_zone代表两个两种方式配置
- $binary_remote_addr:表示通过remote_addr这个标识来做限制,
binary_
的目的是缩写内存占用量,是限制同一客户端ip地址 - zone=one/two:表示生成一个大小为10M,名字为one的内存区域
- rate=10r/s:表示1秒钟不超过10个请求
按连接数限速
示例
http {
limit_conn_zone $binary_remote_addr zone=one:10m;
limit_conn_zone $server_name zone=perserver:10m;
...
server {
...
location /search/ {
limit_conn one 100;
limit_conn perserver 1000;
limit_conn_status 503;
}
}
}
说明:
- limit_conn one 表示限制每个客户端IP的最大并发连接数100
- limit_conn perserver 表示该服务提供的总连接数不得超过1000,超过请求的会被拒绝
按请求速率限速
limit_req_zone $binary_remote_addr zone=one:10m rate=2r/s;
limit_req_zone $binary_remote_addr zone=two:10m rate=2r/s;
limit_req_zone $binary_remote_addr zone=three:10m rate=2r/s;
server {
location / {
limit_req zone=one;
limit_req zone=two burst=4;
limit_req zone=three burst=4 nodelay;
limit_req_status 503;
}
}
- one:上述规则限制了每个IP访问的速度为2r/s。Nginx的限流统计是基于毫秒的,我们设置的速度是2r/s,转换一下就是500ms内单个IP只允许通过1个请求,从501ms开始才允许通过第二个请求。
- two:
burst
配置的意思是设置一个大小为4的缓冲区当有大量请求(爆发)过来时,超过了访问频次限制的请求可以先放到这个缓冲区内。但是请注意:burst的作用是让多余的请求可以先放到队列里,慢慢处理。如果不加nodelay参数,队列里的请求不会立即处理,而是按照rate设置的速度,以毫秒级精确的速度慢慢处理。 - three:
nodelay
参数允许请求在排队的时候就立即被处理,也就是说只要请求能够进入burst队列,就会立即被后台worker处理。nodelay
参数要跟burst
一起使用才有作用。如果没有设置,则所有请求会等待排队。
限制下载速度
location /download {
limit_rate 128k;
}
如果想设置用户下载文件的前 10m 大小时不限速,大于 10m 后再以 128kb/s 限速可以增加以下配内容,修改 nginx.conf 文件
location /download {
limit_rate_after 10m;
limit_rate 128k;
}
静态资源不限流
保持所有限流:
location / {
limit_req zone=one;
proxy_pass http://myapp;
}
静态资源不限流:
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
proxy_pass http://myapp;
}
限流正常配置
map $remote_addr $rt_filtered_ip {
default $binary_remote_addr;
1.2.3.4 "";
4.4.4.4 "";
}
or
geo $rt_filtered_ip {
default $binary_remote_addr;
127.0.0.1 "";
192.168.1.0/24 "";
10.1.0.0/16 "";
::1 "";
2001:0db8::/32 "";
1.2.3.4 ""
}
limit_conn_zone $binary_remote_addr zone=perip:10m;
limit_conn_zone $server_name zone=perserver:10m;
limit_conn_zone $host$uri zone=peruri:10m;
limit_req_zone $rt_filtered_ip zone=qps:10m rate=1r/s;
server {
location = /wp-login.php {
limit_req zone=qps burst=5 nodelay;
limit_conn perip 10;
limit_conn perserver 100;
limit_rate 500k;
include fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
}
}
$binary_remote_addr是限制同一客户端ip地址;
$server_name是限制同一server最大并发数;
limit_conn为限制并发连接数;
limit_rate为限制下载速度;