nginx配置说明

314 阅读5分钟

目的

熟悉ngxin的配置文件结构和常规配置介绍,知道配置的优先级。最终让我们配置url映射的时候不迷茫。

nginx简介

Nginx功能丰富,可作为HTTP服务器,也可作为反向代理服务器,邮件服务器。支持FastCGI、SSL、Virtual Host、URL Rewrite、Gzip等功能。并且支持很多第三方的模块扩展。我们常用它来做反向代理服和负载均衡用。

官网:www.nginx.org/

配置文件结构

...              #全局块

events {         #events块
   ...
}

http      #http块
{
    ...   #http全局块
    server        #server块
    { 
        ...       #server全局块
        location [PATTERN]   #location块
        {
            ...
        }
        location [PATTERN] 
        {
            ...
        }
    }
    server
    {
      ...
    }
}
  • 全局块

    配置影响nginx全局的指令。

    • 配置运行nginx服务用户(组)
    • worker process数
    • Nginx进程PID存放路径
    • 错误日志的存放路径
    • 配置文件的引入
  • enents块

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

    • 设置网络连接的序列化
    • 是否允许同时接收多个网络连接
    • 事件驱动模型的选择
    • 最大连接数的配置
  • http块

    可以理解为一个网站。可以嵌套多个server,配置代理,缓存,日志定义等绝大多数功能和第三方模块的配置。

    • 定义MIMI-Type
    • 自定义服务日志
    • 允许sendfile方式传输文件
    • 连接超时时间
    • 单连接请求数上限
  • server块

    可以理解为一个具体的服务,与端口绑定。配置虚拟主机的相关参数,一个http中可以有多个server。

    • 配置网络监听
    • 基于名称的虚拟主机配置
    • 基于IP的虚拟主机配置
  • location块

    配置请求的路由,以及各种页面的处理情况。

    • location配置
    • 请求根目录配置
    • 更改location的URI
    • 网站默认首页配置

示例配置文件

########### 每个指令必须有分号结束。#################
#user administrator administrators;  #配置用户或者组,默认为nobody nobody。
#worker_processes 2;  #允许生成的进程数,默认为1
#pid /nginx/pid/nginx.pid;   #指定nginx进程运行文件存放地址
error_log log/error.log debug;  #制定日志路径,级别。这个设置可以放入全局块,http块,server块,级别以此为:debug|info|notice|warn|error|crit|alert|emerg
events {
    accept_mutex on;   #设置网路连接序列化,防止惊群现象发生,默认为on
    multi_accept on;  #设置一个进程是否同时接受多个网络连接,默认为off
    #use epoll;      #事件驱动模型,select|poll|kqueue|epoll|resig|/dev/poll|eventport
    worker_connections  1024;    #最大连接数,默认为512
}
http {
    include       mime.types;   #文件扩展名与文件类型映射表
    default_type  application/octet-stream; #默认文件类型,默认为text/plain
    #access_log off; #取消服务日志    
    log_format myFormat '$remote_addr–$remote_user [$time_local] $request $status $body_bytes_sent $http_referer $http_user_agent $http_x_forwarded_for'; #自定义格式
    access_log log/access.log myFormat;  #combined为日志格式的默认值
    sendfile on;   #允许sendfile方式传输文件,默认为off,可以在http块,server块,location块。
    sendfile_max_chunk 100k;  #每个进程每次调用传输数量不能大于设定的值,默认为0,即不设上限。
    keepalive_timeout 65;  #连接超时时间,默认为75s,可以在http,server,location块。

    upstream mysvr {   
      server 127.0.0.1:7878;
      server 192.168.10.121:3333 backup;  #热备
    }
    error_page 404 https://www.baidu.com; #错误页
    server {
        keepalive_requests 120; #单连接请求上限次数。
        listen       4545;   #监听端口
        server_name  127.0.0.1;   #监听地址       
        location  ~*^.+$ {       #请求的url过滤,正则匹配,~为区分大小写,~*为不区分大小写。
           #root path;  #根目录
           #index vv.txt;  #设置默认页
           proxy_pass  http://mysvr;  #请求转向mysvr 定义的服务器列表
           deny 127.0.0.1;  #拒绝的ip
           allow 172.18.5.54; #允许的ip           
        } 
    }
}

说明 :

  1. 惊群现象:一个网路连接到来,多个睡眠的进程被同时叫醒,但只有一个进程能获得链接,这样会影响系统性能。
  2. 日志输入中的变量:
    • remoteaddrremote_addr 与 http_x_forwarded_for 用以记录客户端的ip地址;
    • $remote_user :用来记录客户端用户名称;
    • $time_local : 用来记录访问时间与时区;
    • $request : 用来记录请求的url与http协议;
    • $status : 用来记录请求状态;成功是200;
    • $body_bytes_s ent :记录发送给客户端文件主体内容大小;
    • $http_referer :用来记录从那个页面链接访问过来的;
    • $http_user_agent :记录客户端浏览器的相关信息;

location配置

1. 语法规则

首先匹配 =,其次匹配^~,其次是按文件中顺序的正则匹配,最后是交给 /通用匹配。当有匹配成功时候,停止匹配,按当前匹配规则处理请求。不管哪个优先级的规则,匹配按照最长字符【也就是最准确】能匹配到的为准。

符号含义
== 开头表示精确匹配,一旦匹配成功则停止
^~^~开头表示uri以某个常规字符串开头,可以理解为java中的startWith。
~~ 开头表示区分大小写的正则匹配
~*~* 开头表示不区分大小写的正则匹配
!和!*!和!*分别为区分大小写不匹配及不区分大小写不匹配的正则
/匹配所有以 / 开头的请求。但是如果有更长的表达式,则选择更长的表达式。

2. 优先级说明

优先级说明
第一优先级等号类型(=)的优先级最高。一旦匹配成功,则不再查找其他匹配项。
第二优先级^~类型表达式。一旦匹配成功,则不再查找其他匹配项。
第三优先级正则表达式类型(~ ~*)的优先级次之。
如果有多个location的正则能匹配的话,则使用正则表达式最长的那个。
第四优先级常规字符串匹配类型。按前缀匹配。

3. 匹配规则举例

###############################第一部分 全局配置############################
#user  nobody;                        指定启动进程的用户,默认不用指定即可。
#error_log  logs/error.log;           配置日志输出,虽然叫error_log但是可以定义输出的级别,默认不写是ERROR级别
#error_log  logs/error.log  notice;   
#error_log  logs/error.log  info;
#pid        logs/nginx.pid;           记录pid的文件,默认就是放到这个位置,可以修改。

# 只启动一个进程,nginx是多进程单线程模型,但是使用了epoll sendfile 非阻塞io
worker_processes  1;

###############################第二部分 event配置############################
#主要是网络连接相关的配置
events {
    # 每个worker能连接1024个链接
    worker_connections  1024;
    #use epoll; 事件驱动模型select|poll|kqueue|epoll|resig
}


###############################第三部分 http配置############################
http {
    include       mime.types;  #文件扩展名与文件类型映射表
    default_type  text/html;   #默认的返回类型,可以在server.location里面改
    sendfile        on;        #开启sendfile系统调用
    keepalive_timeout  65;     #连接超时时间65s
  
  
    server {
        listen       80;
        
        ############### demo1 展示location路径的不同写法优先级 ###############
        # =最高优先级 表示路径完全等于,可以匹配/demo1/a/b的请求
        location =/demo1/a/b {
            echo "=/demo1/a/b";
        } 
        # ^~第二高  表示startsWith,可以匹配/demo1/a/b/c和/demo1/acc请求
        location ^~/demo1/a {
            echo "^~/demo1/a";
        }
        # ^~第二高  表示startsWith,和上面的区别是如果/demo1/abc,则优先匹配该规则
        location ^~/demo1/ab {
            echo "^~/demo1/ab";
        }
        # ~等四个符号第三高  表示正则,如果要用{}是特殊符号,需要整个加引号,建议直接加双引号,防止出错,可以匹配/demo1/bcd
        # 其他三个:~*不区分大小写正则,!~正则不匹配的,!~*不分大小写的正则不匹配
        location "~/demo1/\w{3}$" {
            echo "regex";
        }
        # 最低 没有前置符号,也表示以什么开始 /demo1 /demo111 /demo1/b/c 不符合上面三种,就会匹配到这
        location /demo1{
            echo "/demo1";
        }
        # 也是最低。但是它和上面取字符最长的【也就是最精确的】进行匹配
        location /demo1_abc{
            echo "/demo1";
        }
    }
}

说明:

本示例中的echo指令是需要单独安装echo模块的。是为了演示方便,正式环境中一般是没有这个模块的。

安装echo模块步骤:

1.下载echo模块

git clone https://github.com/openresty/echo-nginx-module.git

2.配置Nginx时加上该模块

./configure --prefix=/Users/mayuanfei/nginx  --add-module=/Users/mayuanfei/Downloads/nginx-1.22.1/echo-nginx-module

3.安装nginx

make && make install

4. 测试

  • 第一优先级:=/demo1/a/b

    image-20230504152938075
  • 第二优先级:^~/demo1/a

    image-20230504153251662
  • 第三优先级:"~/demo1/\w{3}$"

    image-20230504153852569
  • 第四优先级:/demo1 和 /demo1_abc

    image-20230504154259990

root和alias的区别

  • root

    root和alias都可以定义在location模块中,都是用来指定请求资源的真实路径,比如:

    location /demo/ {  
        root /data/w3;
    }
    

    请求 http:/localhost/demo/top.jpg 这个地址时,那么在服务器里面对应的真正的资源

    /data/w3/demo/top.gif文件

  • alias

    alias指定的路径是location的别名,不管location的值怎么写,资源的 真实路径都是 alias 指定的路径 ,比如:

    location /demo/ {  
      alias /data/w3/;
    }
    

    同样请求 http://foofish.net/demo/top.jpg 时,在服务器查找的资源路径是: /data/w3/top.jpg

  • 区别总结

    • alias 只能作用在location中,而root可以存在server、http和location中。
    • alias 后面必须要用 “/” 结束,否则会找不到文件,而 root 则对 ”/” 可有可无。
    • alias 找路径时使用alias路径替换location路径,而root找路径时会用root路径+location路径

proxy_pass配置规则

配置 proxy_pass 时,当在后面的 url 加上了 /,相当于是绝对路径,则 Nginx 不会把 location 中匹配的路径部分加入代理 uri;反之则会加上 location 中匹配的路径。举例:

############## demo4 反向代理 ###############
location /test_boss {
    proxy_intercept_errors on;
    proxy_pass      http://webapiservers/;
}

这里注意:http://webapiservers/这里结尾有/结尾,表示不会加上/test_boss 这部分地址。而我们后台springboot正好此时设置的context-path:

server:
  servlet:
    context-path: /test_boss

那么自然是会报404错误了。当然,如果context-path要是设置为"/",那么是能访问到的。不过非常不建议这么做。访问路径尽量和我们controller配置的路径一致。所以,proxy_pass指定的代理路径结尾不要加“/”

错误页面配置

后端返回错误时,Nginx 会根据配置拦截错误,处理后再返回给客户端。

############### demo2 展示serve静态文件夹 ###############
location / {
   root   html;                 # root就是根目录是当前html目录
   index  index.html index.htm; # index表示默认不写的时候转到的文件
}

############## demo3 指定错误文件 ###############
error_page   500 502 503 504  /50x.html;
location = /50x.html {
   root   html;
}
error_page   404  /404.html;
location = /404.html {
   root   html;
}

############## demo4 反向代理 ###############
location /mergather_boss {
    proxy_intercept_errors on;
    proxy_pass      http://webapiservers;
}