Nginx功能介绍

379 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第11天,点击查看活动详情

Nginx功能介绍

来自百科: Nginx是由伊戈尔·赛索耶夫为俄罗斯访问量第二的Rambler.ru站点(俄文:Рамблер)开发的,公开版本1.19.6发布于2020年12月15日。

Nginx功能丰富,可作为web应用服务器,也可作为反向代理服务器邮件服务器。 支持FastCGISSLVirtual HostURL RewriteGzip等功能, 并且支持很多第三方的模块扩展, 如之前文章中介绍的OpenResty

配置文件大致结构

  • 全局配置
    • events模块
    • http模块 ... http模块配置
      • upstream模块
      • server模块
        • location模块
    • stream模块(1.90版本后)

全局配置

配置影响Nginx全局的参数, 一般有日志存放路径, 配置文件引入, 允许生成worker process数等

#运行用户
user nobody;
# 启动进程,通常设置成和cpu的数量相等
worker_processes  4;
#全局错误日志及PID文件
#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;
#pid        logs/nginx.pid;
worker_rlimit_nofile 1024;
# 引入其他配置文件
include /etc/nginx/conf.d/*.conf;

events模块

配置影响nginx服务器或与用户的网络连接

events {
    # epoll是多路复用IO(I/O Multiplexing)中的一种方式,
    # 仅用于linux2.6以上内核,可以大大提高nginx的性能,配置指定了线程轮询的方法(如果是BSD如Mac请使用Kqueue)
    use   epoll; 
    # 单个后台worker process进程的最大并发链接数    
    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"';
    # 日志文件路径
    access_log  logs/access.log  main;
    # sendfile 指令指定 nginx 是否调用 sendfile 函数(zero copy 方式)来输出文件,
    # 对于普通应用,必须设为 on,
    # 如果用来进行下载等应用磁盘IO重负载应用,可设置为 off,
    # 以平衡磁盘与网络I/O处理速度,降低系统的uptime.
    sendfile     on;
    # 连接超时时间(秒)
    keepalive_timeout  300;
    # 接口响应超时时间
    # 不配置默认60s, 超时会404
    proxy_read_timeout 600;
    proxy_send_timeout 600;
    # Nginx使用该大小申请read_buf,即大小指定了 upstream header 最大长度,
    # 如果响应头超过了这个长度,Nginx会报upstream sent too big header错误,
    # 然后客户端收到的是502。
    proxy_buffer_size   4k;
    # 开启gzip
    gzip on;
    # 设置对数据启用压缩的最少字节数
    gzip_min_length 1000;
    # 设置数据的压缩等级
    # 这个等级可以是1-9之间的任意数值, 9是最慢但是压缩比最大的, 
    # 我们设置为4, 这是一个比较折中的设置
    gzip_comp_level  4;
    # 指定客户端禁用gzip功能, 要兼容恶心的ie浏览器
    gzip_disable  msie6; 
    # 设置需要压缩的数据格式
    gzip_types text/plain application/x-javascript text/css text/html application/xml; 
    # server模块配置
    server {
            # 监听80端口
            listen   80;
            # 指定ip地址或者域名,多个配置之间用空格分隔
            server_name localhost;
            # web资源根目录
            root  /html/test;
            # 默认首页
            index  index.html index.html;
            # 日志
            access_log  logs/access.log;
            error_log  logs/error.log;
            # location模块
            location / {
               # 设置请求头信息
               proxy_set_header   Host             $host;
               proxy_set_header   X-Real-IP        $remote_addr;
               proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
               # 反向代理
               proxy_pass  127.0.0.1:8080;
            }
	}
}

反向代理

  location / {
     proxy_pass  127.0.0.1:8080;
  }

负载均衡 upstream的5种负载方式:

  • 轮询(默认)
  • 权重
upstream test { 
    server 127.0.0.1:8080 weight=1; 
    server 127.0.0.1:8081 weight=2; 
    # backup 其它所有的非backup机器down或者忙的时候, 请求backup机器
    server 127.0.0.1:8082 backup; 
    server 127.0.0.1:8083; 
} 
  • ip_hash
upstream test { 
    ip_hash; 
    server 127.0.0.1:8080; 
    server 127.0.0.1:8081; 
} 
  • url_hash
upstream test { 
    server 127.0.0.1:8080; 
    server 127.0.0.1:8081; 
    hash $request_uri;
    # 指定hash算法
    hash_method crc32; 
} 
  • fair(服务器响应时间短的优先分配)
upstream test { 
    server 127.0.0.1:8080; 
    server 127.0.0.1:8081; 
    fair; 
} 

健康检查机制

upstream backend { 
    # max_fails=3 请求失败超过3次暂停服务
    # fail_timeout=30s 请求失败暂停30s之后重新发起请求
    server 127.0.0.1:8080  max_fails=3 fail_timeout=30s; 
    server 127.0.0.1:8081  max_fails=3 fail_timeout=30s; 
} 

https代理 查看nginx是否安装了ssl模块, 没有需要安装了ssl模块, 注意证书的有效期, 失效后不可用

server {
    listen  443  ssl;
    server_name  localhost;
    ssl_certificate      /opt/nginx/conf/nssl/xx.pem;
    ssl_certificate_key  /opt/nginx/conf/nssl/xx.key;
    ssl_session_timeout 5m;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;
}

流量复制 查看nginx是否安装了ngx_http_mirror_module模块, 没有需要安装ngx_http_mirror_module模块, 将生产环境的流量拷贝到预上线环境或测试环境

location / {
    mirror /mirror;
    proxy_pass http://prod;
}
location = /mirror {
    internal;    
    proxy_pass http://test$request_uri;
}

白名单

在http和stream模块下以及在server和location都可以 进行控制

http {
    # allow 允许访问的ip
    allow 10.0.0.0/8;
    allow 123.124.15.6;
    allow 123.45.67.128/28;
    # 其余的都不允许访问
    deny all;
}

访问频率控制

  • ip控制
limit_req_zone $binary_remote_addr zone=one:10m rate=100r/s;
  • server_name控制
limit_req_zone $server_name zone=serverrequestlimit:10m rate=500r/s;
upstream limit-server {
    server 127.0.0.1:8090;
    server 127.0.0.1:8091;
    server 127.0.0.1:8092;
}
server {
    listen       18090;
    server_name  limit-server;
    location / {
          limit_req zone=serverrequestlimit burst=1 nodelay;
          limit_req_log_level warn;
          limit_req_status 429;
          proxy_pass http://limit-server ;
    }
}

访问速度控制

# 是对每个连接限速100k, 而不是对IP限速
limit_rate 100k; 

跨域处理

server {
    listen 80;
    charset utf-8;
    location /api {
      if ($request_method = 'OPTIONS') {
        add_header Access-Control-Allow-Origin *;
        add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,OPTIONS;
            add_header Access-Control-Allow-Headers  'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
            return 204;
       }
       add_header Access-Control-Allow-Origin *;
       add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,OPTIONS;
       add_header Access-Control-Allow-Headers  'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
       proxy_pass http://127.0.0.1:8080; 
    }
 }

日志配置

 server {
    if ($time_iso8601 ~ "^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})") {
       set $year $1;
       set $month $2;
       set $day $3;
    }        
    listen       80;
    access_log   /data/logs/$year$month$day-app.access.log main;
    error_log    /data/logs/error.log    error;
}

location 语法 location [=|~|~*|^~] /uri/ {… }

nginx内置很多参数, 如$host , $remote_addr, $http_cookie 等等 如我们可以通过获取$http_cookie参数, 通过cookie区分不同环境实现灰度发布功能

location / {
    set $root_path "/home/web/prod";
    set $flag "";
    if ($http_cookie ~* "app-env=(.+?)(?=;|$)") {
            set $flag $1;
    }
    if ($flag = "env-gray"){
            set	$root_path "/home/web/gray";
    }
    root 	$root_path;
    index  index.html index.htm;
}

stream模块

nginx从1.9.0开始,新增加了一个stream模块,用来实现四层协议的转发、代理或者负载均衡等, 用法和http模块一样

# 使用stream反向代理mysql
stream {
    upstream mysql {
       server 192.168.1.100:3306 weight=5 max_fails=3 fail_timeout=60s;
       server 192.168.1.101:3306 weight=5 max_fails=3 fail_timeout=60s;
    }
    server {
       listen 3306;
       proxy_connect_timeout 60s;
       proxy_send_timeout 60s;
       proxy_read_timeout 60s;
       proxy_buffer_size 256k;
       proxy_pass mysql;
    }
}