Day 57 应用工具_nginx
nginx
Nginx介绍
Nginx(“engine x”)是⼀一款是由俄罗斯的程序设计师Igor Sysoev所开发⾼高性能的 Web和 反向代理理 服务器器,也是⼀一个 IMAP/POP3/SMTP 代理理服务器器。
轻量量级的web服务器器
http://nginx.org 官⽹网
http://www.nginx.cn/doc/index.html 中⽂文⽂文档
Nginx安装
yum -y install gcc pcre-devel zlib zlib-devel wget vim lsof elinks psmisc wget http://nginx.org/download/nginx-1.15.5.tar.gz -P /usr/src cd /usr/src tar xf nginx-1.15.5.tar.gz cd nginx-1.15.5 mkdir /usr/local/nginx ./configure --prefix=/usr/local/nginx make make install /usr/local/nginx/sbin/nginx elinks http://192.168.214.20 --dump
启动
/usr/local/nginx/sbin/nginx
测试
netstat –ntpl
lsof -i :80
相关文件
nginx path prefix: "/usr/local/nginx" nginx binary file: "/usr/local/nginx/sbin/nginx" nginx modules path: "/usr/local/nginx/modules" nginx configuration prefix: "/usr/local/nginx/conf" nginx configuration file: "/usr/local/nginx/conf/nginx.conf" nginx pid file: "/usr/local/nginx/logs/nginx.pid" nginx error log file: "/usr/local/nginx/logs/error.log" nginx http access log file: "/usr/local/nginx/logs/access.log"
配置文件 nginx.conf
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#启动子进程程序默认用户 #user nobody; #一个主进程和多个工作进程。工作进程是单进程的,且不需要特殊授权即可运行;这里定义的是工作进程数量 worker_processes 1; #全局错误日志的位置及日志格式 #error_log logs/error.log; #error_log logs/error.log notice; #error_log logs/error.log info; #pid logs/nginx.pid; events { #每个工作进程最大的并发数 worker_connections 1024; } #http服务器设置 http { #设定mime类型,类型由mime.type文件定义 include 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"'; #$remote_addr与$http_x_forwarded_for用以记录客户端的ip地址; #$remote_user:用来记录客户端用户名称; #$time_local: 用来记录访问时间与时区; #$request: 用来记录请求的url与http协议; #$status: 用来记录请求状态;成功是200, #$body_bytes_sent :记录发送给客户端文件主体内容大小; #$http_referer:用来记录从那个页面链接访问过来的; #$http_user_agent:记录客户浏览器的相关信息; #全局访问日志路径 #access_log logs/access.log main; #sendfile指令指定 nginx 是否调用sendfile 函数(zero copy 方式)来输出文件,对于普通应用,必须设为on。如果用来进行下载等应用磁盘IO重负载应用,可设置为off,以平衡磁盘与网络IO处理速度,降低系统uptime。 sendfile on; #此选项允许或禁止使用socke的TCP_CORK的选项,此选项仅在使用sendfile的时候使用 #tcp_nopush on; #长连接超时时间 #keepalive_timeout 0; keepalive_timeout 65; #开启压缩 #gzip on; #配置虚拟主机 server { #虚拟主机使用的端口 listen 80; #虚拟主机域名 server_name localhost; #虚拟主机支持的字符集 #charset koi8-r; #虚拟主机的访问日志路径 #access_log logs/host.access.log main; #定义web根路径 location / { #根目录路径 root html; #索引页 index index.html index.htm; } #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; } #定义反向代理服务器 数据服务器是lamp模型 # proxy the PHP scripts to Apache listening on 127.0.0.1:80 # #location ~ \.php$ { # proxy_pass http://127.0.0.1; #} #定义PHP为本机服务的模型 # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 # #location ~ \.php$ { # root html; # fastcgi_pass 127.0.0.1:9000; # fastcgi_index index.php; # fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; # include fastcgi_params; #} # deny access to .htaccess files, if Apache's document root # concurs with nginx's one # #拒绝apache DR目录及子目录下的.htaccess文件访问 #location ~ /\.ht { # deny all; #} } # another virtual host using mix of IP-, name-, and port-based configuration # #server { # listen 8000; # listen somename:8080; # server_name somename alias another.alias; # location / { # root html; # index index.html index.htm; # } #} #https的配置方案 # HTTPS server # #server { # listen 443 ssl; # server_name localhost; # ssl_certificate cert.pem; # ssl_certificate_key cert.key; # ssl_session_cache shared:SSL:1m; # ssl_session_timeout 5m; # ssl_ciphers HIGH:!aNULL:!MD5; # ssl_prefer_server_ciphers on; # location / { # root html; # index index.html index.htm; # } #} }
Nginx 默认网站
Nginx默认网站
当Nginx 配置文件中有且只有一个Server 的时候,该Server 就被Nginx 认为是默认网站,所有发给Nginx 服务器 80 端口的数据都会默认给该Server。
server { listen 80; server_name localhost; location / { root html; index index.html index.htm; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } }
Nginx目录访问权限
location /a { allow 192.168.1.0/24; deny all; #return 404; return http://www.jd.com; }
Nginx登陆验证
# auth_basic # 语法: auth_basic string | off; # 默认值: auth_basic off; # auth_basic_user_file file; location /b { auth_basic ”登陆验证"; auth_basic_user_file /etc/nginx/htpasswd; }
日志管理
Nginx访问日志主要有两个参数控制
1) log_format # 用来定义记录日志的格式(可以定义多种日志格式,取不同名字即可)
log_format log_name string
2) access_log # 用来指定日至文件的路径及使用的何种日志格式记录日志
access_log logs/access.log main;
Log_format 格式变量
log_format格式变量量: $remote_addr #记录访问⽹网站的客户端地址 $remote_user #远程客户端⽤用户名 $time_local #记录访问时间与时区 $request #⽤用户的http请求起始⾏行行信息 $status #http状态码,记录请求返回的状态码,例例如:200、301、404等 $body_bytes_sent #服务器器发送给客户端的响应body字节数 $http_referer #记录此次请求是从哪个连接访问过来的,可以根据该参数进⾏行行防盗链设置。 $http_user_agent #记录客户端访问信息,例例如:浏览器器、⼿手机客户端等 $http_x_forwarded_for #当前端有代理理服务器器时,设置web节点记录客户端地址的配置,此参数⽣生效的前提是代理理服务器器也要进⾏行行相关的x_forwarded_for设置
日志自定义
自定义⽇日志格式为 json
log_format main_json '{"@timestamp":"$time_local",' '"client_ip": "$remote_addr",' '"request": "$request",' '"status": "$status",' '"bytes": "$body_bytes_sent",' '"x_forwarded": "$http_x_forwarded_for",' '"referer": "$http_referer"' '}’; access_log logs/access_json.log main_json;
防盗链
location /images/ { alias /data/images/; valid_referers none blocked *.ayitula.com; if ($invalid_referer) { return 403; } }
Nginx 虚拟主机
虚拟主机介绍
一个web服务器软件默认情况下只能发布一个web,因为一个web分享出去需要三个条件(IP、Port、Domain name)
⼀一个web服务器软件如何发布多个web呢?
虚拟主机:就是把一台物理服务器划分成多个“虚拟”的服务器,每一个虚拟主机都可以有独立的域名和独立的目录
基于IP的虚拟主机
每一个网站都需要IP
缺点:需要多个IP,如果是公网IP,每一个IP都需要付费
server { listen 192.168.10.42:80; location / { root html/abc; index index.html index.htm index.php; } } server { listen 192.168.10.52:80; location / { root html/cbd; index index.html index.htm; } }
基于端口的虚拟主机
只需要一个IP
缺点:端口是无法通知公网用户的,无法适用于公网用户,适合内部用户
server { listen 80; server_name www.abc.com; location / { root html/abc; index index.html index.htm index.php; } } server { listen 8080; server_name www.abc.com; location / { root html/cbd; index index.html index.htm; } }
基于域名的虚拟主机
一个网站必然有一个域名
server { listen 80; server_name www.abc.com; location / { root html/abc; index index.html index.htm index.php; } } server { listen 80; server_name www.cbd.com; location / { root html/cbd; index index.html index.htm; } }
Nginx 反向代理
反向代理介绍
代理理服务器器,客户机在发送请求时,不不会直接发送给⽬目的主机,⽽而是先发送给代理理服务器器,代理理服务接受客户机请求之后,再向主机发出,并接收⽬目的主机返回的数
据,存放在代理理服务器器的硬盘中,再发送给客户机。
应用场景
堡垒机场景
注意:安全配置只接受来自堡垒机的链接访问,其他都拒绝。
内网服务器发布场景
缓存场景
反向代理原理
1) 客户端通过浏览器器 发起请求 代理理服务器器
2)代理理服务器器 接受请求
3) 代理理服务器器 发起请求 业务服务器器
4)业务服务器器 接受请求
5)业务服务器器 处理理请求
6) 业务服务器器 响应请求 代理理服务器器
7)代理理服务器器 响应请求 客户端
8)客户端通过浏览器器渲染请求并展示给⽤用户
反向代理实现
location / { index index.php index.html index.htm; # 定义⾸首⻚页索引⽂文件的名称 proxy_pass http://mysvr ; # 请求转向 mysvr 定义的服务器器列列表 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; client_max_body_size 10m; # 允许客户端请求的最⼤大单⽂文件字节数 client_body_buffer_size 128k; # 缓冲区代理理缓冲⽤用户端请求的最⼤大字节数, proxy_connect_timeout 90; # nginx 跟后端服务器器连接超时时间(代理理连接超时) proxy_send_timeout 90; # 后端服务器器数据回传时间(代理理发送超时) proxy_read_timeout 90; # 连接成功后,后端服务器器响应时间(代理理接收超时) proxy_buffer_size 4k; # 设置代理理服务器器(nginx)保存⽤用户头信息的缓冲区大小 proxy_buffers 4 32k; # proxy_buffers 缓冲区,网页平均在 32k 以下的话,这样设置 proxy_busy_buffers_size 64k; # 高负荷下缓冲大小(proxy_buffers*2) proxy_temp_file_write_size 64k; #设定缓存文件夹大小,大于这个值,将从 upstream 服务器传 }
限速
1、限速该特性可以限制某个用户在一个给定时间段内能够产生的HTTP请求数。请求可以简单到就是一个对于主页的GET请求或者一个登陆表格的POST请求。
2、限速也可以用于安全目的上,比如暴力密码破解攻击。通过限制进来的请求速率,并且(结合日志)标记出目标URLs来帮助防范DDoS攻击。一般地说,限流是用在保护上游应用服务器器不被在同一时刻的大量用户请求湮没。
应用场景
DDOS防御
下载场景保护IO
限速原理
算法思想是:
水(请求)从上方倒入水桶,从水桶下方流出(被处理理);
来不及流出的水存在水桶中(缓冲),以固定速率流出;
水桶满后水溢出(丢弃)。
这个算法的核心是:缓存请求、匀速处理、多余的请求直接丢弃。
限速实现
实现方式
Nginx 官方版本限制IP的连接和并发分别有两个模块:
1) limit_req_zone 用来限制单位时间内的请求数,即速率限制。
2) limit_req_conn 用来限制同⼀一时间连接数,即并发限制。
模块使用方法
limit_req_zone 参数配置
• Syntax: limit_req zone=name [burst=number] [nodelay];
• Default: —
• Context: http, server, location
限速案例一
基于IP对下载速率做限制,限制每秒处理 1 次请求,对突发超过 5 个以后的请求放入缓存区
http { limit_req_zone $binary_remote_addr zone=baism:10m rate=1r/s; server { location /search/ { limit_req zone=baism burst=5 nodelay; } } }
limit_req_zone $binary_remote_addr zone=baism:10m rate=1r/s;
第一个参数:$binary_remote_addr 表示通过 remote_addr 这个标识来做限制,“binary_”的目的是缩写内存占用量,是限制同一客户端 ip 地址。
第二个参数:zone=baism:10m 表示生成一个大小为 10M,名字为 one 的内存区域,用来存储访问的频次信息。
第三个参数:rate=1r/s 表示允许相同标识的客户端的访问频次,这里限制的是每秒1次,还可以有比如 30r/m 的。
limit_req zone=baism burst=5 nodelay;
第一个参数:zone=baism 设置使用哪个配置区域来做限制,与上面 limit_req_zone 里的 name 对应。
第二个参数:burst=5,重点说明一下这个配置,burst 爆发的意思,这个配置的意思是设置一个大小为 5 的缓冲区当有大量请求(爆发)过来时,超过了访问频次限制的请
求可以先放到这个缓冲区内。
第三个参数:nodelay,如果设置,超过访问频次而且缓冲区也满了的时候就会直接返回 503,如果没有设置,则所有请求会等待排队。
限速案例二
基于IP做连接限制,限制同一IP并发为 1,下载速度为 100K
limit_conn_zone $binary_remote_addr zone=addr:10m; server { listen 80; server_name localhost; location / { root html; index index.html index.htm; } location /abc { limit_conn addr 1; limit_rate 100k; } }
综合案例
http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; #基于IP做连接限制,限制同一IP并发为 1,下载速度为 100K limit_conn_zone $binary_remote_addr zone=addr:10m; #基于IP对下载速率做限制,限制每秒处理 1 次请求,对突发超过 5 个以后的请求放入缓存区 limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s; server { listen 80; server_name localhost; location / { root html; index index.html index.htm; } location /abc { limit_req zone=one burst=5 nodelay; limit_conn addr 1; limit_rate 100k; } } }
Nginx URL 重写
URL重写介绍
• rewrite模块(ngx_http_rewrite_module)
• Rewrite功能是Nginx 服务提供的一个重要功能。几乎是所有的 web 产品必备技能,用于实现URL重写。URL重写是非常有用的功能,比如它可以在我们在改变网站结构后,需要客户端修改原来的书签,也不需要其他网站修改对我们网站的友情链接,还可以在一定程度上提高网站的安全性,能够让我们的网站显得专业。
• Nginx 服务器Rewrite 功能的实现是依赖于PCRE(Perl Compatible Regular Expression。Perl兼容的正则表达式)的支持,所以在编译安装Nginx 之前,需要安装PCRE库。
应用场景
• 域名变更 (京东)
• 用户跳转 (从某个连接跳到另一个连接)
• 伪静态场景 (便于CDN缓存动态页面数据)
URL 重写理理
URL rewrite 实现
URL 模块语法
1) set 设置变量量
2) if 负责语句句中的判断
3) return 返回返回值或URL
4) break 终⽌止后续的rewrite规则
5) rewrite 重定向URL
Rewrite 规则相关指令
set 指令 自定义变量
# set 指令 自定义变量 Syntax: set $variable value; Default: — Context: server, location, if # 将 http://www.ayitula.com 重写为 http://www.ayitula.com/baism location / { set $name baism; rewrite ^(.*)$ http://www.ayitula.com/$name; }
if 指令 负责判断
模糊匹配:~ 匹配 !~ 不匹配 ~* 不区分大小写的匹配
精准匹配:= 匹配 != 不匹配
# if 指令 负责判断 Syntax: if (condition) { ... } Default: — Context: server, location location / { root html; index index.html index.htm; if ($http_user_agent ~* 'Chrome') { return 403; #return http://www.jd.com; } }
return 指令 定义返回数据
# return 指令 定义返回数据 Syntax: return code [text]; return code URL; return URL; Default: — Context: server, location, if location / { root html; index index.html index.htm; if ($http_user_agent ~* 'Chrome') { return 403; #return http://www.jd.com; } }
break 指令 停止执行当前虚拟主机的后续 rewrite 指令集
# break 指令 停止执行当前虚拟主机的后续 rewrite 指令集 Syntax: break; Default:— Context:server, location, if location / { root html; index index.html index.htm; if ($http_user_agent ~* 'Chrome') { break; return 403; } }
URL rewrite 语法
rewrite <regex> <replacement> [flag];
关键字 正则 替代内容 flag标记
flag:
last # 本条规则匹配完成后,继续向下匹配新的 location URL规则
break # 本条规则匹配完成即终止,不不再匹配后面的任何规则
redirect # 返回 302 临时重定向,浏览器地址会显示跳转后的URL地址
permanent # 返回 301 永久重定向,浏览器地址栏会显示跳转后的URL地址
URL rewrite 案例
域名跳转
# 域名跳转 www.ayitula.com 重写为 www.jd.com server { listen 80; server_name www.ayitula.com; location / { rewrite ^/$ http://www.jd.com permanent ; }
注意:重定向就是将⽹网⻚页⾃自动转向重定向
301 永久性重定向:新⽹网址完全继承旧⽹网址,旧网址的排名等完全清零
301 重定向是网页更改地址后对搜索引擎友好的最好方法,只要不是暂时搬移的情况,都建议使用301来做转址。
302 临时性重定向:对旧网址没有影响,但新网址不会有排名
搜索引擎会抓取新的内容而保留旧的网址
break:本条规则匹配完成即终止,不再匹配后面的任何规则
类似临时重定向,返回客户端 302
last:url 重写后,马上发起一个新的请求,再次进入server 块,重试 location 匹配,超过 10 次匹配不到报 500 错误,地址栏 url 不变。
根据用户浏览器重写访问目录
如果是 chrome 浏览器 就将 http://192.168.10.42/$URI 重写为 http://192.168.10.42/chrome/$URI
location / { ..... if ($http_user_agent ~* 'chrome'){ rewrite ^(.*)$ /chrome/$1 last; } location /chrome { root html ; index index.html; } } #^ 以什么开头 ^a #$ 以什么结尾 c$ #. 除了回车以外的任意一个字符 #* 前面的字符可以出现多次或者不出现 # 更多内容看正则表达式 re
Nginx 优化
优化思路
标准情况下,软件默认的参数都是对安装软件的硬件标准来设置的,目前我们服务器的硬件资源远大于要求的标准,所以为了让服务器性能更加出众,充分利用服务器的硬件资源,我们一般需要优化APP的并发数来提升服务器的性能。
查看相关信息
CPU核数:cat /proc/cpuinfo |grep "flags" | wc -l
查看进程所在哪个核上:ps -eo psr,pid,args | grep "nginx"
查看进程数:top
统计 nginx 当前并发:netstat -antpl | grep nginx | grep ESTABLISHED | wc -l
工作进程优化
• Nginx是主进程 + 工作进程模型
• worker_processes 1; 工作进程数量按CPU的总核心调整
• worker_cpu_affinity 0001 0010 0100 1000; CPU的亲和力力
• worker_connections 1024; 一个工作进程的并发数
长连接设置
http 协议属于TCP协议
优化目标:减少三次握手和四次断开的次数
keepalive_timeout 5; 长连接时间
keepalive_requests 8192; 每个长连接受最大请求数
数据压缩
gzip on; # 启用 gzip 压缩功能
gzip_proxied any; # nginx 做前端代理时启用该选项,表示无论后端服务器的 headers 头返回什么信息,都无条件启用压缩
gzip_min_length 1024; # 最小压缩的页面,如果页面过于小,可能会越压越大,这里规定大于 1K的页面才启用压缩
gzip_buffers 4 8k; # 设置系统获取几个单位的缓存用于存储 gzip 的压缩结果数据流 按照原始数据大小以 8K为单位申请 4 倍内存空间
gzip_comp_level 3; # 压缩级别,1 压缩比最小处理速度最快,9 压缩比最大但处理最慢,同时也最消耗CPU,⼀一般设置为 3 就可以了
gzip_types text/plain text/css application/x-javascript application/javascript application/xml; # 什么类型的页面或文档启用压缩
客户端缓存
语法: expires [time|epoch|max|off]
默认值: expires off
作用域: http, server, location
location ~.*\.(js|css)?${
expires 1h;
}