Nginx在代理服务器中扮演着十分重要的位置,目前从事前端工作的我,使用的比较少,但是一直觉得这是一个利器,因此准备深入学习下,本篇是开篇-场景篇,主要介绍常用场景,比如静态资源WEB服务,代理服务,动态缓存服务,应用层负载均衡等。
静态资源WEB服务
静态资源类型:非服务器动态生成的文件
- 浏览器渲染:HTML/CSS/JS
- 图片:JEPG/GIF/PNG
- 视频:FLV/MPEG
- 文件:TXT等任意下载文件
配置语法
配置语法-文件读取
Syntax: sendfile on|off;
Default: sendfile off;
Context: http,server,location,if in location
--with-file-aio 异步文件读取
配置语法-tcp_nopush
Syntax: tcp_nopush on|off;
Default: tcp_nopush off;
Context: http,server,location
作用:sendfile开启的情况下,提高网络包的传输效率,多个包进行整合,一次性发送
配置语法-tcp_nodelay
Syntax: tcp_nodelay on|off;
Default: tcp_nodelay on;
Context: http,server,location
作用:和tcp_nopush相反,表示不要等待,即时发送
配置语法-压缩
Syntax: gzip on|off;
Default: gzip on;
Context: http,server,location,if in location
作用:压缩传输
压缩比配置
Syntax: gzip_comp_level level;
Default: gzip_comp_level 1;
Context: http,server,location
作用:根据实际情况,选择压缩的级别,因为压缩本身也需要时间
压缩协议版本
Syntax: gzip_http_version 1.0|1.1;
Default: gzip_http_version 1.1;
Context: http,server,location
扩展HTTP压缩模板
- http_gzip_static_module 预读gzip功能,先找同名gz文件,如果有直接返回
- http_gunzip_module 应用甚少,针对不支持gzip的浏览器
浏览器缓存机制
原理:依靠HTTP协议定义的缓存机制,如Expires;Cache-Control等
第一次无缓存请求步骤:浏览器请求 -> 无缓存 -> 请求Web服务 -> 请求响应(协商) -> 呈现
有缓存请求步骤:浏览器请求 -> 有缓存 -> 校验过期 -> 呈现
校验过期机制
- 检验是否过期(Expires;Cache-Control)
- 协议中Etag头信息校验
- Last-Modified头信息校验
具体流程如下图所示
nginx设置缓存
配置语法 - expires,作用添加Expires;Cache-Control头,具体语法
Syntax: expires [modified] time;
expires epoch | max | off;
Default: expires off;
Context: http,server,location,if in location
跨站访问
为什么浏览器默认禁止跨站访问:主要是因为安全问题,会容易出现CSRF攻击
但实际情况,由于实际业务需要,需要对一些资源打开跨站访问,在nginx中,具体语法
Syntax: add_header name value [always];
Default: --;
Context: http,server,location,if in location
主要头:Access-Control-Allow-Origin
防盗链
防止网站资源被盗用
首要任务:区别哪些请求是非正常的用户请求
基于http_refer防盗链配置模块
Syntax: valid_referers none | blocked | server_names | string ...;
Default: --;
Context: server,location
代理服务
客户端 <-> 代理 <-> 服务
代理的分类,按应用场景分类
- 正向代理
- 代理为客户端服务(翻墙)
- 代理请求DNS服务
- 反向代理
- 代理为服务端服务(负载均衡)
- 客户端请求DNS服务
可支持的代理协议:这就比较多了,HTTP/HTTPS/WebSocket/GRPC等等
常见的Nginx作为反向代理支持协议
- HTTP/HTTPS
- http_proxy (http server)
- fastcgi (php server)
- uwsgi (Python server)
- ws -> http_proxy(socket)
- grpc (grpc server)
反向代理模式与Nginx配置模块
- http,https,ws ngx_http_proxy_module
- fastcgi ngx_http_fastcgi_module
- uwsgi ngx_http_uwsgi_module
- grpc ngx_http_v2_module
正向代理:http协议 -> http_proxy模块,不支持https协议,应用不是很主流
配置语法
Syntax: proxy_pass URL;
Default: --;
Context: location, if in location, limit_except
其他配置语法
缓冲区,会增大内存的使用
Syntax: proxy_buffering on|off;
Default: proxy_buffering on;
Context: http, server, location
扩展:proxy_buffer_size、proxy_buffers、proxy_busy_buffers_size
跳转重定向,服务端301地址重定向修改
Syntax: proxy_redirect default;proxy_redirect off; proxy_redirect redirect replacement;
Default: proxy_redirect default;
Context: http, server, location
头信息
Syntax: proxy_set_header field value;
Default: proxy_set_header Host $proxy_host;
proxy_set_header Connection close;
Context: http, server, location
扩展:proxy_hide_header、proxy_set_body
超时
Syntax: proxy_connect_timeout time;
Default: proxy_connect_timeout 60s;
Context: http, server, location
扩展:proxy_read_timeout、proxy_send_timeout
缓存服务
缓存类型
- 服务端缓存(redis)
- 代理缓存
- 客户端缓存
代理缓存配置语法proxy_cache
# proxy_cache_path
Syntax: proxy_cache_path path [levels=levels]
[use_temp_path=on|off] keys_zone=name:size [inactive=time]
[manager_threshold=time] [loader_files=number]
[loader_sleep=time] [loader_threshold=time] [purger=on|off]
[purger_files=number][purger_sleep=time]
[purger_threshold=time]
Default: --;
Context: http
# proxy_cache
Syntax: proxy_cache zone|off;
Default: proxy_cache off;
Context: http, server, location
# 缓存过期时间
Syntax: proxy_cache_valid [code...] time;
Default: --;
Context: http, server, location
# 缓存维度
Syntax: proxy_cache_key string;
Default: proxy_cache_key $scheme$proxy_host$request_uri;
Context: http, server, location
如何清理指定缓存
- rm -rf 缓存目录
- 第三方扩展模块ngx_cache_purge
如何让部分页面不缓存
Syntax: proxy_no_cache string ...;
Default: --;
Context: http, server, location
缓存命中分析
- 通过设置response的头信息Nginx_Cache
- 通过设置log_format,打印日志分析
主要通过$upstream_cache_status,取值如下
- MISS:未命中,请求被传送到后台处理
- HIT:命中
- EXPIRED:缓存过期,请求被传送到后台
- UPDATING:正在更新缓存,将使用旧的应答
- STALE:后端得到过期的应答
缓存命中率:分析Nginx的Access日志
- 在指定的log_format中加入$upstream_cache_status"信息
- tail -f 日志文件路径,实时查看日志
- awk命令
awk '{if($NF=="\"HIT\""){hit++}}END{printf "%.2f",hit/NR}' /var/log/nginx/test_proxy.access.log
大文件分片请求
Syntax: slice size;
Default: slice 0;
Context: http, server, location
优势:每个子请求收到的数据都会形成一个独立文件,一旦请求断了,其他请求不受影响
缺点:当文件很大或者slice很小的时候,可能会导致文件描述符耗尽等情况
其他服务
websocket
websocket实现在HTTP连接的基础上,并通过HTTP中的Upgrade协议头将连接从HTTP升级到WebSocket,这样就可以实现多次双向通信,直到连接关闭。
应用场景
- 多人聊天场景
- APP信息推送
扩展:map配置选项,通过map进行变量中内容映射后赋值
Syntax: map string $variable {};
Default: --;
Context: http
fastcgi
cgi -> fastcgi,代理配置语法
Syntax: fastcgi_pass address;
Default: --;
Context: location, if in location
设置默认首页,结合fast_params使用
Syntax: fastcgi_index name;
Default: --;
Context: http, server, location
fastcgi缓存,和proxy_cache类似,由于工作中没有该使用场景,因此就不多记录了。
fastcgi_ignore_headers,忽略服务器的相关头信息
uwsgi
诞生顺序:CGI -> Fastcgi -> WSGI -> uwsgi
为什么使用uwsgi
- 安全
- 效率
Linux扩展
- 查看是否启动某进程
ps -ef|grep mysql
- 查看端口监听情况:
ss -luntp|grep port # 有些系统使用 netstat -luntp | grep port
- 如果已启动
kill -9 pid
负载均衡
负载均衡的目的
- 提升吞吐,提高并发量
- 容灾,避免单点故障,提高可用性
负载均衡按地域分类
- GSLB
- SLB
负载均衡按照模型分类
- 四层负载均衡(传输层)
- 七层负载均衡(应用层)
Nginx就是典型的七层负载均衡的SLB
实现原理:通过proxy_pass转发到一组服务池(upstream server)
upstream配置语法,默认是轮询访问。
Syntax: upstream name {};
Default: --;
Context: http
upstream配置项
- 指定ip和域名的写法
- 参数backup表示为备份节点
- 参数weight表示权重
后端服务器在负载均衡中的状态
- down:当前server暂时不接受负载均衡
- backup:预留的备份服务器
- max_fails:允许请求失败的次数
- fail_timeout:经过max_fails失败后,服务暂停的时间
- max_conns:限制最大的接收的连接数
Nginx调度算法
- 轮询:默认,按照时间顺序
- 加权轮询:weight越大,概率越高
- ip_hash:每个请求按照ip hash的结果分配,这样来自同一个IP固定访问一个后端服务器
- url_hash:按照访问的url hash的结果分配,使每个url定向到后端同一个服务器
- least_conn:最少连接数,连接数少就少发
- hash关键数值:hash自定义的key
url_hash
Syntax: hash key [consistent];
Default: --;
Context: upstream
# 1.7.2 推出