> For the complete documentation index, see [llms.txt](https://yangsx95.gitbook.io/notes/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://yangsx95.gitbook.io/notes/distributed/web-fu-wu-qi/nginx/nginx-de-ji-ben-pei-zhi.md).

# Nginx的基本配置

## 默认的Nginx配置文件

核心配置文件: `${JAVA_HOME}/conf/nginx.conf`，如果使用yum安装，则位于`/etc/nginx/nginx.conf`，下面是nginx默认的配置文件：

```nginx
# 全局块
user  nginx; # 设置用户以及用户组
worker_processes  1; # 工作进程的数量

error_log  /var/log/nginx/error.log warn; # 错误日志
pid        /var/run/nginx.pid; # pid文件位置

# events块
events {
    worker_connections  1024; # 每个进程允许的最大连接数
}

# http块
http {
    include       /etc/nginx/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  /var/log/nginx/access.log  main;

    # sendfile 零拷贝机制开关
    sendfile        on;
    #tcp_nopush     on;
	# 客户端与服务端的超时时间，单位s
    keepalive_timeout  65;

    #gzip  on;
    
 	# 这里，导入了conf.d中所有的配置, 默认包含一个default.conf文件
    include /etc/nginx/conf.d/*.conf;
}
```

```nginx
# default.conf
server {
    # 虚拟主机监听的端口
    listen       80;
    # 虚拟主机名称，可用于配置域名
    server_name  localhost;

    #charset koi8-r;
    #access_log  /var/log/nginx/host.access.log  main;
	# 路径匹配
    location / {
        # 此路径代表静态文件的根路径
        root   /usr/share/nginx/html;
        # 默认的index页面
        index  index.html index.htm;
    }
	# 当出现状态404时，跳转到指定的页面页面
    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    # 当发生500 502 503 504 状态时，重定向到/50x.html页面
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    # proxy the PHP scripts to Apache listening on 127.0.0.1:80
    #
    #location ~ \.php$ {
    #    proxy_pass   http://127.0.0.1;
    #}

    # 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
    #
    #location ~ /\.ht {
    #    deny  all;
    #}
}
```

## 配置块说明

Nginx的配置文件分为多个块组成，主要由三个大块组成：

* 全局快
* events
* http块

```nginx
...              #全局块

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

**各个块的作用如下：**

* **全局块**：配置nginx全局指令。一般有运行nginx服务器的用户组，nginx进程pid存放路径，日志存放路径，配置文件引入，允许生成worker process数等。
* **events块**：配置影响nginx服务器或与用户的网络连接。有每个进程的最大连接数，选取哪种事件驱动模型处理连接请求，是否允许同时接受多个网路连接，开启多个网络连接序列化等。
* **http块**：可以嵌套多个server，配置代理，缓存，日志定义等绝大多数功能和第三方模块的配置。如文件引入，mime-type定义，日志自定义，是否使用sendfile传输文件，连接超时时间，单连接请求数等。
* **server块**：配置虚拟主机的相关参数，一个http中可以有多个server， 比如tomcat服务就是一个server。
* **location块**：配置请求的路由，以及各种页面的处理情况。

## 日志配置

注意，Nginx有两个日志文件，一个为`error_log`，另一个为`access_log`。前者用于记录服务器**错误日志**（启动时发现配置文件出错），而后者则是记录**访问日志**（包含访问地址、响应状态等，可配置）。

```nginx
# 配置全局日志文件位置, 位于全局块中
# 指定日志路径，级别。这个设置可以放入全局块，http块，server块，级别有：debug|info|notice|warn|error|crit|alert|emerg
error_log log/all.log;
error_log log/debug.log debug;
error_log log/error.log error;

http {
    include       mime.types;
    default_type  application/octet-stream;
    # nginx中记录了很多信息，每个信息就是一个变量，log_format就是将变量组织到一起记录到access_log中
    # 配置日志格式，声明一个main格式，其中$xx代表nginx变量，变量参见附录一
    # 注意，只可以配置到这里，如果需要不同的server进行不同日志格式，可以定义多个格式，并指定
    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指定访问日志的路径，并指定main格式
    access_log  logs/access.log  main;
    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;
        }
    }
}
```

### 日志切割

```shell
mv access.log access.log.20180101
kill -USR1 Nginx 主进程号 # 让nginx重新生成一个日志文件
# 可以写一个定时执行的脚本，进行每日的日志切割
```

## 虚拟主机配置

**什么是虚拟主机？**

虚拟主机是使用特殊的软硬技术，将一台计算机主机分成一台台“虚拟”的主机。每一台虚拟主机都具有的独立的域名和IP地址（或者共享ip地址），并具有完整的Internet服务器功能。虚拟主机完全独立，在外界看来，每台虚拟主机和一台独主机的表现完全相同。

```nginx
#user  nobody;
worker_processes  1;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;
    
    # 配置一台虚拟主机，所有www.test.com:80的请求都会被此虚拟机处理（可以通过修改host文件模拟）
    server {
        # 监听端口
        listen 80;
        # 配置域名
        server_name www.test.com;
        # 路径匹配
        location / {
            # 根路径
            root html;
            index index.html index.htm;
        }
    }
    
    # 针对8080端口监听的虚拟主机，所有localhost:8080的请求都会被此虚拟主机处理
    server {
        listen 8080;
        server_name localhost;
        location /{
            root html/port;
            index index.html;
        }
    }
}
```

### location匹配规则

location就是对请求URL路径的匹配，他共有以下几种匹配规则：

| 匹配符号  | 含义                                                                                                               |
| ----- | ---------------------------------------------------------------------------------------------------------------- |
| `=`   | 精准匹配                                                                                                             |
| `^~`  | 表示 `uri` 以某个常规字符串开头，理解为匹配 `url` 路径即可。`nginx` 不对 `url` 做编码，因此请求为`/static/20%/aa`，可以被规则`^~ /static/ /aa`匹配到（注意是空格） |
| `~`   | 开头表示区分大小写的正则匹配                                                                                                   |
| `~`\* | 开头表示不区分大小写的正则匹配                                                                                                  |
| `/`   | 通用匹配，任何请求都会匹配到                                                                                                   |

**匹配规则**：

* 首先进行精准匹配：`=`
* 其次进行一般匹配： `^~`，如果有多个`url`符合，优先匹配较长的路径，比如`/po`与`/po/jo`，后者优先于前者
* 按照文件顺序进行正则匹配
* 最后交给`/`通用匹配
* 当匹配成功时，停止匹配，按照匹配的配置规则处理请求

```nginx
location = / {
   #规则A
}
location = /login {
   #规则B
}
location ^~ /static/ {
   #规则C
}
location ~ \.(gif|jpg|png|js|css)$ {
   #规则D
}
location ~* \.png$ {
   #规则E
}
location / {
   #规则F
}
```

```
访问根目录 /， 比如 http://localhost/ 将匹配规则 A 
访问 http://localhost/login 将匹配规则 B，http://localhost/register 则匹配规则 F
访问 http://localhost/static/a.html 将匹配规则 C
访问 http://localhost/a.gif, http://localhost/b.jpg 将匹配规则 D和规则 E，但是规则 D 顺序优先，规则 E不起作用，而 http://localhost/static/c.png则优先匹配到规则 C
访问 http://localhost/a.PNG 则匹配规则 E，而不会匹配规则 D，因为规则 E 不区分大小写
访问 http://localhost/category/id/1111 则最终匹配到规则 F，因为以上规则都不匹配，这个时候应该是 nginx 转发请求给后端应用服务器，比如 FastCGI（PHP），tomcat（jsp），nginx 作为反向代理服务器存在
```

### 常用的匹配规则

```nginx
# 静态资源文件文件夹匹配
location ^~ /static/ {
    root html/static;
}

# 静态资源后缀名匹配
location ~* \.(gif|jpg|css)$ {
    root html/static;
}
```

## 配置文件详解

```nginx
########### 每个指令必须有分号结束。#################

###全局块开始###
# 配置用户或者组，默认为nobody nobody。
# user administrator administrators; 
# 指定nginx的工作进程的数量，nginx的进程分为master进程与worker进程
# worker_processes 2; 
# 指定nginx进程运行文件存放地址
# pid /nginx/pid/nginx.pid;   
# 指定日志路径，级别。这个设置可以放入全局块，http块，server块，级别以此为：debug|info|notice|warn|error|crit|alert|emerg
error_log log/error.log debug;
###全局块结束###
 
###event块开始###
events {
    # 设置使用的网络io模型
    use epoll;
    # 设置网路连接序列化，防止惊群现象发生，默认为on
    accept_mutex on; 
    # 设置一个进程是否同时接受多个网络连接，默认为off
    multi_accept on;  
    #事件驱动模型，select|poll|kqueue|epoll|resig|/dev/poll|eventport
    #use epoll;      
    # #最大连接数，默认为 512
    worker_connections  1024;    
}
###event块结束###
 
###http块开始###
http {
    #文件扩展名与文件类型映射表，minme.types是一个文件，与配置文件位于同一目录下
    include       mime.types;   
    # 默认文件类型，默认为text/plain
    default_type  application/octet-stream;  
    # 取消服务日志   
    # 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'; 
    #  设置日志格式，combined为日志格式的默认值
    access_log log/access.log myFormat; 
    # 允许sendfile方式传输文件，默认为off，可以在http块，server块，locati
    sendfile on; 
    # 每个进程每次调用传输数量不能大于设定的值，默认为0，即不设上限。
    sendfile_max_chunk 100k;
    # 连接超时时间，默认为75s，可以在http，server，location块。
    keepalive_timeout 65;  
    
    # 公开的服务
    upstream mysvr {   
      # 配置多态服务器，默认使用轮询负载均衡
      # 加上此句，则会使用ip_hash策略
      # ip_hash; 
      server 127.0.0.1:7878;  
      server 127.0.0.2:7878; 
      server 127.0.0.3: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;     
        # 请求的url过滤，正则匹配，~为区分大小写，~*为不区分大小写。
        # 如果设置为 / 则代表根路径
        location  ~*^.+$ {
            #根目录·
           # root path; 
           #设置默认页
           # index vv.txt;  
           # 请求转向mysvr 定义的服务器列表
           proxy_pass  http://mysvr;  
           # 拒绝的ip
           deny 127.0.0.1;   
           # 允许的ip   
           allow 172.18.5.54;          
        } 
    }
} 
###http块结束###
```
