Better

Ethan的博客,欢迎访问交流

Nginx深入学习系列-模块篇

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头信息校验

具体流程如下图所示 2.png

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 推出


留言