# 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>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://jun-wang.gitbook.io/learnjava/ji-shu-xue-xi/web-zhong-jian-jian-xue-xi/nginx-jie-shao.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
