ginx是一个高性能的Web服务器,几乎所有的Web服务都需要使用Nginx。关于Nginx的功能特性这里不再赘述,让我们从0开始,了解Nginx的基本用法,学习它在Web服务中都有哪些应用。本文主要介绍Nginx的安装以及基础的控制命令。

# Nginx基本介绍

## Nginx(“engine x”)

Nginx是一个具有高性能的HTTP和反向代理的WEB服务器,同时也是一个邮件服务器(支持POP3/SMTP/IMAP协议)。

## Nginx由来

是由伊戈尔赛索耶夫(俄罗斯人)使用C语言编写的,Nginx的第一个版本是2004年10月4号发布的0.1.0版本。基于BSD许可证开源。

## 下载与安装

最新版下载:http://nginx.org/en/download.html

历史版本:http://nginx.org/download/

### Windows环境的安装

下载数据包,解压后直接使用,双击exe启动。在浏览器输出:http://localhost,即可看到欢迎页面。

### CentOS环境的安装

为了获得较好的学习环境,我们应该考虑安装在一个纯净的虚拟机或者云服务器上。同时,为了避免CentOS防火墙拦截端口上的数据,我们考虑将其关闭。

#### 关闭防火墙

```bash

systemctl stop firewalld

```

关闭运行的防火墙,系统重新启动后,防火墙将重新打开。

```bash

systemctl disable firewalld

```

永久关闭防火墙,系统重新启动后,防火墙依然关闭。

```bash

systemctl status firewalld

```

查看防火墙状态。

#### 防火墙控制

查询防火墙中指定的端口是否开放:

```bash

firewall-cmd --query-port=9001/tcp

```

开放一个指定的端口:

```bash

firewall-cmd --permanent --add-port=9002/tcp #参数"--permanent"表示永久开放,不加表示临时开放

```

批量添加开发端口:

```bash

firewall-cmd --permanent --add-port=9001-9003/tcp

```

SELinux(Security-Enhanced Linux)是美国安全局对于强制访问控制的实现,在6内核以后的版本中,SELinux已经成功成为内核中的一部分。要查看SELinux的状态,可以使用命令`sestatus`。如果需要关闭SELinux,可以直接编辑配置文件`/etc/selinux/config`,将其中的SELINUX行注释掉或将其值设置为disabled,然后重启系统。

接下来,我们需要安装GCC。原因在于Nginx是使用C语言编写的程序。可以通过命令`gcc --version`检查是否已经安装了GCC。如果没有安装,可以使用命令`yum install -y gcc`进行安装。

此外,我们还需要安装PCRE库。原因是Nginx在编译过程中需要使用到PCRE库(Perl Compatible Regular Expressions,兼容正则表达式库),因为在Nginx的Rewrite模块和http核心模块都会使用到PCRE正则表达式语法。可以通过命令`yum install -y pcre pcre-devel`进行安装,并通过命令`rpm -qa pcre pcre-devel`检查是否安装成功。

接下来,我们需要安装zlib库。zlib是一个提供开发人员的压缩算法的库,在Nginx的各个模块中需要使用gzip压缩,所以我们也需要提前安装其库及源代码zlib和zlib-devel。可以通过命令`yum install -y zlib zlib-devel`进行安装,并通过命令`rpm -qa zlib zlib-devel`检查是否安装成功。

最后,我们需要安装OpenSSL库。OpenSSL是一个开放源代码的软件库包,应用程序可以使用这个包进行安全通信,并且避免被窃听。SSL是Secure Sockets Layer安全套接协议的缩写,可以在Internet上提供秘密性传输,其目标是保证两个应用间通信的保密性和可靠性。在Nginx中,如果服务器需要提供安全网页时就需要用到OpenSSL库,所以我们需要对OpenSSL的库文件及它的开发安装包进行一个安装。可以通过命令`yum install -y openssl openssl-devel`进行安装,并通过命令`rpm -qa openssl openssl-devel`检查是否安装成功。

全部安装完成后,可以通过Nginx源码进行下载和编译。首先下载nginx-1.22.0.tar.gz文件:

```bash

wget http://nginx.org/download/nginx-1.22.0.tar.gz

```

解压下载的文件:

```bash

tar -xzf nginx-1.22.0.tar.gz

```

进入解压后的nginx目录后,执行`./configure`命令进行配置。

ginx的安装和配置过程如下:

1. 编译:执行`make`命令

2. 安装:执行`make install`命令

3. 查看Nginx的默认安装位置:`whereis nginx`

Nginx的安装包目录说明:

- `auto`:存放的是编译相关的脚本

- `CHANGES`:版本变更记录

- `ru`:俄罗斯文的版本变更记录

- `conf`:nginx默认的配置文件

- `configure`:nginx软件的自动脚本程序,是一个比较重要的文件,作用如下:

- 检测环境及根据环境检测结果生成C代码

- 生成编译代码需要的Makefile文件

- `contrib`:存放的是几个特殊的脚本文件,其中README中对脚本有着详细的说明

- `html`:存放的是Nginx自带的两个html页面,访问Nginx的首页和错误页面

- `LICENSE`:许可证的相关描述文件

- `man`:nginx的man手册

- `README`:Nginx的阅读指南

- `src`:Nginx的源代码

`./configure`参数的作用是用来生成 Makefile,为下一步的编译做准备,可以通过在 configure 后加上参数来对安装进行控制。查看所有”./configure”时的额外参数可以使用`./configure --help`命令。

以下是一些常用的`./configure`参数类别及其说明:

- 基础配置:

- `--prefix=PATH`:指定安装根目录,默认是/usr/local/nginx。此设置会更改其他配置目录的相对路径。

- `--sbin-path=PATH`:可执行文件的路径,默认为/sbin/nginx。

- `--modules-path=PATH`:模块存储路径。

- `--conf-path=PATH`:配置文件的路径,默认为/conf/nginx.conf。

- `--pid-path=PATH`:pid文件的存放路径,默认存放在/logs/nginx.pid,是一个存放nginx的master进程ID的纯文本文件,刚安装的时候不会生成,nginx启动的时候会自动生成。

- `--lock-path=PATH`:指向Nginx锁文件的存放路径,默认值为/logs/nginx.lock。

以下是重构后的内容:

## Nginx 配置选项

### --with-ld-opt

当需要将第三方链接库链接到 Nginx 中时,可以使用 `--with-ld-opt` 参数指定目标库名和路径。编译后的 Nginx 可执行二进制文件是由编译后的目标文件和一些第三方库链接生成的。

```bash

./configure --prefix=/usr/local/nginx \n--sbin-path=/usr/local/nginx/sbin/nginx \n--modules-path=/usr/local/nginx/modules \n--conf-path=/usr/local/nginx/conf/nginx.conf \n--error-log-path=/usr/local/nginx/logs/error.log \n--http-log-path=/usr/local/nginx/logs/access.log \n--pid-path=/usr/local/nginx/logs/nginx.pid \n--lock-path=/usr/local/nginx/logs/nginx.lock \n--with-ld-opt=目标库名-目标库路径

```

### --with-debug

如果需要在 Nginx 中打印 debug 调试级别日志,可以使用 `--with-debug` 参数将相关代码编译进去。这样可以通过修改配置文件来打印调试日志,方便定位服务问题。

```bash

./configure --prefix=/usr/local/nginx \n--sbin-path=/usr/local/nginx/sbin/nginx \n--modules-path=/usr/local/nginx/modules \n--conf-path=/usr/local/nginx/conf/nginx.conf \n--error-log-path=/usr/local/nginx/logs/error.log \n--http-log-path=/usr/local/nginx/logs/access.log \n--pid-path=/usr/local/nginx/logs/nginx.pid \n--lock-path=/usr/local/nginx/logs/nginx.lock \n--with-debug

```

### 日志文件

Nginx 默认会将访问日志和错误日志分别存储在 `/logs` 目录下的 `access.log` 和 `error.log` 文件中。其中,`` 是 Nginx 安装目录的前缀。

```bash

--error-log-path=PATH 错误日志文件存储位置,默认值为/logs/error.log

--http-log-path=PATH 指向访问日志文件的路径,默认值为/logs/access.log

```

### 加载额外模块

使用 `--with-select_module` 参数可以加载额外的模块。例如:

```bash

./configure --prefix=/usr/local/nginx \n--sbin-path=

CGI(Common Gateway Interface)通用网关【接口】,主要解决的问题是从客户端发送一个请求和数据,服务端获取到请求和数据后可以调用调用CGI【程序】处理及相应结果给客户端的一种标准规范。

以下是与CGI相关的配置文件:

- conf: fastcgi相关配置文件

- conf.default: fastcgi.conf的备份文件

- fastcgi_params: fastcgi的参数文件

- default: fastcgi的参数备份文件

- scgi_params: scgi的参数文件

- default: scgi的参数备份文件

- uwsgi_params: uwsgi的参数文件

- default: uwsgi的参数备份文件

- mime.types:记录的是HTTP协议中的Content-Type的值和文件后缀名的对应关系

- mime.types.default:mime.types的备份文件

- nginx.conf:这个是Nginx的核心配置文件,非常重要,也是我们即将要学习的重点

- nginx.conf.default:nginx.conf的备份文件

此外,还有与编码转换映射相关的三个配置文件:koi-utf、koi-win、win-utf,用来将一种编码转换成另一种编码。

在nginx安装目录下,还存放了两个静态的html页面,分别用于访问失败后的失败页面和成功访问的默认首页。同时,logs目录中会记录入门的文件,包括access.log、error.log和nginx.pid三个文件。

另外,sbin目录是存放执行程序文件nginx的地方,可以用来控制Nginx的启动和停止等相关命令。

如果需要卸载nginx,可以进入安装目录,通过“whereis nginx”获取进程号,然后使用“./nginx -s stop”关闭nginx进程。接着使用“rm -rf /usr/local/nginx”删除安装目录。最后回到之前执行make的目录,将安装包之前编译的环境清除掉:“make clean”。

对于基于源码安装的nginx,默认情况下是不能通过systemctl操作的。只能进入到其安装目录下的sbin子目录中的nginx二进制文件控制。如果想要整合systemctl,可以在`/usr/lib/systemd/system`目录下添加service文件。

以下是重构后的内容:

编辑文件内容:

```ini

[Unit] Description=nginx web service Documentation=http://nginx.org/en/docs/ After=network.target

[Service] Type=forking PIDFile=/usr/local/nginx/logs/nginx.pid ExecStartPre=/usr/local/nginx/sbin/nginx -t -c /usr/local/nginx/conf/nginx.conf ExecStart=/usr/local/nginx/sbin/nginx ExecReload=/usr/local/nginx/sbin/nginx -s reload ExecStop=/usr/local/nginx/sbin/nginx -s stop PrivateTmp=true

[Install] WantedBy=default.target

```

添加完成后,如果权限有问题需要进行权限设置:

```bash

chmod 755 /usr/lib/systemd/system/nginx.service

```

使用系统命令来操作nginx:

- 启动:`systemctl start nginx`

- 停止:`systemctl stop nginx`

- 重启:`systemctl restart nginx`

- 重新加载配置文件:`systemctl reload nginx`

- 查看nginx状态:`systemctl status nginx`

- 开机启动:`systemctl enable nginx`

添加到环境变量:

背景:每次执行nginx的二进制指令时,都要切换到其安装目录下的sbin目录,很麻烦。

解决方案:将其添加到环境变量中,让Linux自己去寻找指令所在位置。在`/etc/profile`文件中追加:

```bash

export PATH=$PATH:/usr/local/nginx/sbin

```

使之立即生效:

```bash

source /etc/profile

```

测试:

```bash

nginx -v

```

以下是重构后的内容:

Nginx的安装与配置:

1. 查看是否安装:执行命令`yum list | grep nginx`。

2. 安装:执行命令`yum install -y nginx`。

3. 查看安装:执行命令`whereis nginx`。

4. 启动Nginx:执行命令`systemctl start nginx`。

5. 查看nginx的安装位置:执行命令`whereis nginx`。

6. 编辑Nginx配置文件:`%nginx安装目录%/nginx.conf`,添加一个虚拟主机。

7. 访问:在浏览器中输入服务器IP地址或域名,获取Nginx欢迎主页。

8. 源码安装与yum安装的区别:源码安装将所有数据都放在一个文件夹内(默认/usr/local/nginx),而yum安装将数据分散在操作系统的不同位置,符合Linux数据分离的思想(日志文件放在/var/log/,配置文件放在/etc)。

9. 控制Nginx:Nginx默认采用的是多进程的方式来工作的。Nginx后台进程中包含一个master进程和多个worker进程,master进程主要用来管理worker进程,包含接收外界的信息,并将接收到的信号发送给各个worker进程,监控worker进程的状态,当worker进程出现异常退出后,会自动重新启动新的worker进程。worker进程则是专门用来处理用户请求的,各个worker进程之间是平等的并且相互独立,处理请求的机会也是一样的。

10. 查看Nginx开启的进程:执行命令`ps -ef | grep “nginx”`。

11. 控制nginx,实际上是在操作master进程:打开、关闭、重启。

12. 获取Nginx的PID:执行命令`ps aux | grep “nginx” | grep -v grep`。

获取Nginx进程号的方法有以下几种:

1. 使用`ps aux | grep nginx`命令,找到带有“master process”的进程PID。

2. 使用`ps -ef | grep nginx`命令,直接在结果中找到第二列的进程PID。

3. 通过Nginx的PID文件获取master的进程号。首先使用`find`命令全局查找pid文件:`find / -name nginx.pid`,然后将查找结果作为参数传递给`cat`命令:`cat `find / -name nginx.pid``。

4. 使用`find exec`命令:`find / -name nginx.pid -exec cat {} \;`,将查找结果作为参数传递给`cat`命令。

5. 使用反斜杠、飘号:`cat `find / -name nginx.pid`,将$( )的执行结果作为`cat`的参数。

6. 使用信号控制,如:

- `kill -TERM PID`:立即关闭整个服务。

- `kill -QUIT $(cat `find / -name nginx.pid`)`:优雅地关闭整个服务。

注意:在使用这些方法时,请确保您具有足够的权限来执行这些操作。

信号控制Nginx工作进程的方法如下:

1. 发送QUIT信号给master进程,该信号会控制所有的work进程不再接收新的请求。等待所有请求处理完毕后,关闭所有进程。命令如下:

```bash

kill -QUIT PID

kill -QUIT $(cat `find / -name nginx.pid`)

```

2. 发送HUP信号给master进程,该信号会让master进程把控制旧的work进程不再接收新的请求。等待请求处理完毕后,关闭旧的work进程,并根据nginx的配置文件重新启动新的work进程。命令如下:

```bash

kill -HUP PID / kill -HUP $(cat `find / -name nginx.pid`)

```

3. 发送USR1信号给master进程,该信号告诉Nginx重新开启日志文件。命令如下:

```bash

kill -USR1 PID / kill -USR1 $(cat `find / -name nginx.pid`)

```

4. 发送USR2信号给master进程,该信号告诉master进程要平滑升级。此时,会重新开启对应的master进程和work进程,整个系统中将会有两个master进程,并且新的master进程的PID会被记录在/run/nginx.pid。通过命令“find / -name nginx.pid”获取pid文件的位置。而之前的旧的master进程PID会被记录在/run/nginx.pid.oldbin文件中,接着再次发送QUIT信号给旧的master进程,让其处理完请求后再进行关闭。命令如下:

```bash

kill -USR2 PID / kill -USR2 $(cat `find / -name nginx.pid`)

kill -QUIT PID / kill -QUIT $(cat `find / -name nginx.pid.oldbin`)

```

5. 发送WINCH信号给master进程,该信号会让master进程控制不让所有的work进程在接收新的请求了。请求处理完后关闭work进程。注意master进程不会被关闭掉。命令如下:

```bash

kill -WINCH PID /kill -WINCH $(cat `find / -name nginx.pid`)

```

6. 通过Nginx安装目录下的sbin下的可执行文件nginx来进行Nginx状态的控制。

请根据以下步骤将Nginx从1.14.2升级到1.16.1,同时确保Nginx在升级过程中不中断提供服务:

1. 进入Nginx的sbin目录,执行以下命令启动Nginx:

```

./nginx

```

2. 查看帮助信息:

```

./nginx -h

```

3. 测试信号类型:

```

./nginx -s stop # 快速关闭,类似于TERM/INT信号的作用

./nginx -s quit # 优雅的关闭,类似于QUIT信号的作用

./nginx -s reopen # 重新打开日志文件类似于USR1信号的作用

./nginx -s reload # 类似于HUP信号的作用

```

4. 测试配置文件语法是否正确:

```

./nginx -t

```

如果配置文件语法正确,将不会有任何输出。如果有错误,将会显示错误信息。

5. 指定Nginx的前缀路径(默认为:/usr/local/nginx/):

```

./nginx -p prefix_path

```

6. 指定Nginx的配置文件路径(默认为:conf/nginx.conf):

```

./nginx -c config_file_path

```

7. 在Nginx配置文件中补充全局配置:

```

./nginx -g "global_configuration"

```

8. 将Nginx从1.14.2升级到1.16.1。首先编译高版本的Nginx,获取二进制文件。将高版本的Nginx像安装一样进行参数配置和编译,但不执行安装。编译后数据包文件夹中的objs目录下有nginx二进制文件。

9. 将高版本的nginx二进制文件替换原来低版本的文件。可以使用以下命令:

```

cp objs/* /usr/local/nginx/sbin/nginx/sbin/

```

10. 发送USR2信号给master进程,告诉master进程要平滑升级。这个时候,会重新开启对应的master进程和work进程,整个系统中将会有两个master进程,并且新的master进程的PID会被记录在/run/nginx.pid。而之前的旧的master进程PID会被记录在/run/nginx.pid.oldbin文件中。接着再次发送QUIT信号给旧的master进程,让其处理完请求后再进行关闭。使用以下命令:

```

kill -USR2 PID_of_old_master_process # 或者 kill -USR2 `cat /run/nginx.pid`

```

在升级Nginx之前,需要进行一些准备工作。首先,将Nginx 1.16.1进行参数配置和编译,不需要进行安装。然后进入数据包目录,执行`./configure`和`make`命令。

升级方案有两种:

1. 使用Nginx服务信号进行升级:

- 将14.2版本的sbin目录下的nginx进行备份:`cd /usr/local/nginx/sbin && mv nginx nginxold`

- 将16.1安装目录编译后的objs目录下的nginx文件,拷贝到原来/usr/local/nginx/sbin目录下:`cd ~/nginx/core/nginx-1.16.1/objs && cp nginx /usr/local/nginx/sbin`

- 发送信号USR2给Nginx的14.2版本对应的master进程:`kill -USR2 `cat /run/nginx.pid``

- 发送信号QUIT给Nginx的14.2版本对应的master进程:`kill -QUIT `more /run/nginx.pid.oldbin`

2. 使用Nginx安装目录的make命令:

- 将14.2版本的sbin目录下的nginx进行备份:`cd /usr/local/nginx/sbin && mv nginx nginxold`

- 将16.1安装目录编译后的objs目录下的nginx文件,拷贝到原来/usr/local/nginx/sbin目录下:`cd ~/nginx/core/nginx-1.16.1/objs && cp nginx /usr/local/nginx/sbin`

- 进入到安装目录,执行make upgrade命令

- 查看是否更新成功:`./nginx -v`