> For the complete documentation index, see [llms.txt](https://jun-wang.gitbook.io/learnjava/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://jun-wang.gitbook.io/learnjava/ji-shu-xue-xi/web-zhong-jian-jian-xue-xi/nginx-jie-shao.md).

# Nginx介绍

## 一、介绍

Nginx是一个十分轻量级并且高性能HTTP和反向代理服务器，同样也是一个IMAP/POP3/SMTP代理服务器。

## 二、特性

* HTTP服务器
* 反向代理服务器
* 简单的负载均衡和容错
* 支持热部署

## 三、nginx模块

nginx模块一般分为三类：

* handler：负责处理客户端请求并产生待响应内容。
* filter：负责对输出的内容进行处理，可以对输出进行修改。
* upstream：实现反向代理功能，将真正的请求转发到后端服务器上，并从后端服务器上读取响应，发回客户端。upstream模块是一种特殊的handler，只不过响应内容不是真正由自己产生的，而是从后端服务器上读取的。

## 四、ubuntu安装nginx

```shell
sudo apt-get install nginx
```

这种方式安装的文件位置：

/usr/sbin/nginx：主程序

/etc/nginx：存放配置文件

/usr/share/nginx：存放静态文件

/var/log/nginx：存放日志

通过这种方式安装的，会自动创建服务，会自动在`/etc/init.d/nginx`新建服务脚本，然后就可以使用`sudo service nginx {start|stop|restart|reload|force-reload|status|configtest|rotate|upgrade}`的命令启动。

可以再`/var/log/nginx/`下查看日志，如果端口80被占用，就更改`/etc/nginx/sites-enabled/default`文件，将下面的两个80改成你想要的的端口，然后重新启动。

```shell
 19 
 20 server {
 21         listen 80 default_server;
 22         listen [::]:80 default_server ipv6only=on;
```

## 五、配置nginx作为http服务器

### 1. 配置项目的conf文件

在`/etc/nginx/nginx.conf`中可以看到自定义配置文件的路径：

```
 71         include /etc/nginx/conf.d/*.conf;
 72         include /etc/nginx/sites-enabled/*; 
 73 }
```

在conf.d目录下新建文件`timeline.conf`，写入配置内容

```shell
# HTTP Server

server {
	listen   8080;
	server_name  bonnenuit.vip www.bonnenuit.vip;

	location / {
		alias /home/wangjun/tomcat8/webapps/timeline/pages/;
		index index.html;
	}

}
```

启动nginx： `nginx`\
关闭nginx： `nginx -s stop`\
重启nginx： `nginx -s reload`

### 2. 通过浏览器访问node

<http://bonnenuit.vip:8080/> 如果显示正常，则说明配置成功。

### 3. 遇到的问题

**1. 报错"server" directive is not allowed here in /etc/nginx/myconf/timeline.conf:3**

出现这个错误的原因是`include /etc/nginx/xxx/*.conf;`没有写在http标签下，因为server只能出现在http下面。

**2. 访问url的时候报错403 forbidden**

查询`/var/log/nginx/error.log`，具体的报错日志为：

```
2019/07/03 10:21:25 [error] 1523#0: *1 open() "/home/wangjun/tomcat8/webapps/timeline/pages/timeline/pages/index.html" failed (13: Permission denied), client: 106.39.75.134, server: bonnenuit.vip, request: "GET /timeline/pages/index.html HTTP/1.1", host: "bonnenuit.vip:8080"
```

出现这个原因是因为nginx的worker进程无法访问静态资源文件，因为worker进程的用户和资源的所有者是不一样的，我们需要更改配置文件`nginx.conf`:

```shell
# user 用户 用户组
user wangjun wangjun;
```

然后重启nginx就可以解决。

## 六、配置nginx作为反向代理服务器

### 1. 配置conf文件

在conf.d目录下`timeline.conf`中，新增配置内容：

```shell
# HTTP Server

# 反向代理服务器+负载均衡
upstream test_reverse_proxy {
        server 120.25.245.241:8080 weight=1 max_fails=2 fail_timeout=10s;
        server 120.25.245.241:8080 weight=1 max_fails=2 fail_timeout=10s; #两台机器可以做负载均衡，目前只有一台机器，因此ip:port一样，一台模拟两台
        keepalive 16;
}


server {
        listen   8080;
        server_name  bonnenuit.vip www.bonnenuit.vip; #server_name是为了区别多个server时，匹配域名来决定进入哪个server，当都不匹配时，进入配置的第一个server

        location / {
                alias /home/wangjun/tomcat8/webapps/timeline/pages/;
                index index.html;
        }

        location ^~ /proxy/ {
                proxy_set_header Host $host;
                proxy_pass http://test_reverse_proxy/;
                proxy_http_version 1.1;
                proxy_set_header Connection "";
                proxy_redirect off;
                proxy_intercept_errors on;
                client_max_body_size 10m;
        }

}

```

### 2. 通过浏览器访问

<http://bonnenuit.vip:8080/proxy/> 如果显示正常，则说明配置成功。

## 七、配置nginx作为文件服务器

```shell
sudo vim /etc/nginx/conf.d/file_server.conf
cat /etc/nginx/conf.d/file_server.conf
server {
  listen 8084; 
  server_name 127.0.0.1; # 自己PC的ip或者服务器的域名
  root /home/wangjun/share; # 存放文件的目录 
  location / { 
    autoindex on; # 索引 
    autoindex_exact_size on; # 显示文件大小 
    autoindex_localtime on; # 显示文件时间 
  }
}

# 使配置生效
sudo service nginx reload
```

浏览器访问：

<http://127.0.0.1:8084>

![](/files/-M7h5f-H3Y5u6dY23uTg)

## 八、location匹配url规则

看下location的语法：

```
location [ = | ~ | ~* | ^~ ] uri { ... }
location @name { ... }
```

location 后面跟可选的修饰符，后面就是要匹配的字符，花括号是对应的配置。

修饰符含义：

| =    | 表示精确匹配，只有请求的url路径与后面的字符串完全相等时，才会命中。 |
| ---- | ----------------------------------- |
| \~   | 表示该规则是使用正则定义的，区分大小写                 |
| \~\* | 表示该规则是使用正则定义的，不区分大小写                |
| ^\~  | 表示如果该符号后面的字符是最佳匹配，采用该规则，不再进行后续的查找   |

具体的匹配过程如下：

* 首先先检查使用前缀字符定义的location，选择最长匹配的项并记录下来。
* 如果找到了精确匹配的location，也就是使用了`=`修饰符的location，结束查找，使用它的配置。
* 然后按顺序查找使用正则定义的location，如果匹配则停止查找，使用它定义的配置。
* 如果没有匹配的正则location，则使用前面记录的最长匹配前缀字符location。

基于以上的匹配过程，我们可以得到以下两点启示：

1. **使用正则定义的location在配置文件中出现的顺序很重要**。因为找到第一个匹配的正则后，查找就停止了，后面定义的正则就是再匹配也没有机会了。
2. **使用精确匹配可以提高查找的速度**。例如经常请求`/`的话，可以使用`=`来定义location。

例子：

```
location = / {
    [ configuration A ]
}

location / {
    [ configuration B ]
}

location /user/ {
    [ configuration C ]
}

location ^~ /images/ {
    [ configuration D ]
}

location ~* \.(gif|jpg|jpeg)$ {
    [ configuration E ]
}

请求/精准匹配A，不再往下查找。

请求/index.html匹配B。首先查找匹配的前缀字符，找到最长匹配是配置B，接着又按照顺序查找匹配的正则。结果没有找到，因此使用先前标记的最长匹配，即配置B。

请求/user/index.html匹配C。首先找到最长匹配C，由于后面没有匹配的正则，所以使用最长匹配C。
请求/user/1.jpg匹配E。首先进行前缀字符的查找，找到最长匹配项C，继续进行正则查找，找到匹配项E。因此使用E。

请求/images/1.jpg匹配D。首先进行前缀字符的查找，找到最长匹配D。但是，特殊的是它使用了^~修饰符，不再进行接下来的正则的匹配查找，因此使用D。这里，如果没有前面的修饰符，其实最终的匹配是E。大家可以想一想为什么。

请求/documents/about.html匹配B。因为B表示任何以/开头的URL都匹配。在上面的配置中，只有B能满足，所以匹配B。
```

> 参考：
>
> <https://www.cnblogs.com/EasonJim/p/7806879.html>
>
> <https://www.w3cschool.cn/nginx/nginx-d1aw28wa.html>
>
> <https://segmentfault.com/a/1190000013267839>
