Nginx篇01——基本安装配置和静态页面设置

nginx的编译安装、添加模块、yum安装、简单配置、默认目录作用和静态页面配置。

0、编译安装nginx

0.1 准备工作

这里我们使用nginx的mainline版本的1.17.9来进行编译安装,nginx各版本的官网下载地址:http://nginx.org/en/download.html

首先我们下载并解压nginx源码

1
2
wget http://nginx.org/download/nginx-1.17.9.tar.gz
tar -zxvf nginx-1.17.9.tar.gz

在编译安装之前我们还需要先安装几个别的软件:

  • GCC/G++编译器:GCC(GNU Compiler Collection)可用来编译C语言程序,如果你还需要使用C++来编写Nginx HTTP模块,这时还需要用到G++编译器了。

  • PCRE库:PCRE(Perl Compatible Regular Expressions,Perl兼容正则表达式)是由Philip Hazel开发的函数库,目前为很多软件所使用,该库支持正则表达式。实际上在nginx的很多高级配置中都会用到正则表达式,因此我们在编译Nginx时尽量先把PCRE库编译进Nginx。

  • zlib库:zlib库用于对HTTP包的内容做gzip格式的压缩,我们可以在nginx.conf里配置了gzip on,并指定对于某些类型(content-type)的HTTP响应使用gzip来进行压缩以减少网络传输量。

  • OpenSSL开发库:HTTPS必备,这个就不用解释了

    上面提到的库我们都可以使用yum来进行安装:

1
2
3
4
yum install gcc gcc-c++ pcre pcre-devel zlib zlib-devel openssl openssl-devel

# pcre-devel是使用PCRE做二次开发时所需要的开发库,包括头文件等,这也是编译Nginx所必须使用的。
# 同理,zlib是直接使用的库,zlib-devel是二次开发所需要的库。

Nginx是高度自由化的Web服务器,它的功能是由许多模块来支持的。而这些模块可根据我们的使用需求来定制,如果某些模块不需要使用则完全不必理会它。同样,如果使用了某个模块,而这个模块使用了一些类似zlib或OpenSSL等的第三方库,那么就必须先安装这些软件。

0.2 编译安装

我们进入nginx的目录,输入下面的指令可以查看各类的编译参数,或者在官网也可以看到:

1
./configure --help

我们这里使用的参数是:

1
./configure --sbin-path=/usr/local/nginx/nginx --conf-path=/usr/local/nginx/nginx.conf --pid-path=/usr/local/nginx/nginx.pid --with-http_ssl_module

这里我们可以看到,我们在参数里面并没有指定上面提到的几个库的目录,configure文件会默认系统已经安装的库版本和目录,当然我们也可以手动指定某个库的目录来指定版本。

接下来进行make安装:

1
2
make
make install

如无意外此时应该已经正常安装好了,我们到前面指定的安装目录看一下

注意这个时候我们如果需要使用nginx需要指定这个安装目录,想要全局使用我们可以创建一个软链接:

1
ln -s /usr/local/nginx/nginx /usr/sbin/nginx

0.3 添加模块

同时,如果之后有需要用到的模块而在编译安装的时候忘了安装也没关系,我们可以继续编译添加新模块

首先我们需要查看已经编译的参数:

1
2
3
4
5
6
7
[root@localhost ~]# nginx -V
nginx version: nginx/1.17.9
built by gcc 4.4.7 20120313 (Red Hat 4.4.7-23) (GCC)
built with OpenSSL 1.0.1e-fips 11 Feb 2013
TLS SNI support enabled
configure arguments: --sbin-path=/usr/local/nginx/nginx --conf-path=/usr/local/nginx/nginx.conf --pid-path=/usr/local/nginx/nginx.pid --with-http_ssl_module

需要注意上面的V是大写的V

configure arguments: 这一栏里面我们就可以看到之前编译的时候的参数,对比上面的记录我们可以看到是一模一样的,然后我们会到之前下载的源码目录,注意是源码的目录不是安装的目录,然后添加上之前的编译参数,再添加新的模块,

1
./configure --sbin-path=/usr/local/nginx/nginx --conf-path=/usr/local/nginx/nginx.conf --pid-path=/usr/local/nginx/nginx.pid --with-http_ssl_module --with-http_v2_module --with-mail --with-mail_ssl_module

比如这里我们添加了http_v2mailmail_ssl三个模块

如果想要添加第三方模块的话,只需要使用--add-module=然后加上第三方模块的路径即可。

1
--add-module=/home/echo-nginx-module-0.61

最后我们的编译参数是:

1
2
3
4
5
6
7
8
9
./configure \
--sbin-path=/usr/local/nginx/nginx \
--conf-path=/usr/local/nginx/nginx.conf \
--pid-path=/usr/local/nginx/nginx.pid \
--with-http_ssl_module \
--with-http_v2_module \
--with-mail \
--with-mail_ssl_module \
--add-module=/home/echo-nginx-module-0.61

接着我们使用make安装,再查看目录会发现原来的文件已经被替换成*.default

1
2
make
make install

最后我们再确定一下是否安装成功:

1、yum安装nginx

1.1 yum仓库建立和安装配置

centos自带的repo中就有nginx,可以直接安装,但是版本比较旧,想要使用yum进行安装最新的稳定版本,我们需要自行配置yum仓库。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true

[nginx-mainline]
name=nginx mainline repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=1
enabled=0
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true

默认情况下mainline版本是不会启用的,因此我们如果需要安装mainline版本的nginx则需要手动启用这个repo。

1
2
3
4
5
yum install yum-utils
yum-config-manager --enable nginx-mainline
yum clean all
yum repolist
yum install nginx

安装的时候需要注意这个列出信息中的repo应该是我们刚刚新建的repo。

安装完成之后需要设置开机启动和防火墙放行80端口,如果使用https还需要放行443端口。

1
2
3
4
5
systemctl enable nginx 
systemctl start nginx
firewall-cmd --permanent --zone=public --add-port=80/tcp
firewall-cmd --permanent --zone=public --add-port=443/tcp
firewall-cmd --reload

接下来我们可以测试一下安装和启动是否成功。

1
2
nginx -v
curl 127.0.0.1

1.2 master和worker进程

使用ps命令查看进程,我们可以看到有一个master进程和一个worker进程,默认情况下,worker的进程数量为1,实际上我们可以根据具体需要对其进行修改。

1
ps -ef | grep nginx

在正式提供服务的产品环境下,部署Nginx时都是使用一个master进程来管理多个worker进程,一般情况下,worker进程的数量与服务器上的CPU核心数相等。每一个worker进程都是繁忙的,它们在真正地提供互联网服务,master进程则很“清闲”,只负责监控管理worker进程。worker进程之间通过共享内存、原子操作等一些进程间通信机制来实现各种功能。

2、nginx基本配置

2.1 nginx默认目录

/etc/nginx/

这个是nginx服务器的默认配置目录

/etc/nginx/nginx.conf

这个是nginx服务器的默认配置文件,我们可以在这里对nginx的所有全局配置进行修改,包括线程数端口号等等,同时在默认情况下它也包括了下述的/etc/nginx/conf.d/目录中的所有配置文件。

/etc/nginx/conf.d/

这个目录中包含的.conf配置文件主要用于单独定义某个http网页,从而使得整个配置目录文件的管理变得更加简洁而清晰。

/var/log/nginx

这个目录是默认的log日志目录,主要有acces.logerror.log两个文件,前者负责记录每一个被访问的记录,后者负责记录访问中出现的错误。

2.2 nginx命令

输入nginx -h即可查看所有指令,不需要特意去记忆,用多了就自然记住了。

3、nginx.conf文件

我们把整个全局配置文件拿出来分析一下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
user  nginx;
worker_processes 16;

error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;


events {
worker_connections 1024;
}


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 on;
#tcp_nopush on;

keepalive_timeout 65;

#gzip on;

include /etc/nginx/conf.d/*.conf;
}

3.1 user

user指的是以哪个用户来创建nginx的worker进程,master进程一般都是使用root用户启动,权限较大。

3.2 worker_processes

worker_processes则是nginx的worker进程数量,一般与CPU的核心数量一致,这里我们设置为16。

3.3 error_log

error_log是日志的存放位置和输出等级,等级的取值范围是debuginfonoticewarnerrorcritalertemerg,从左至右级别依次增大。当设定为一个级别时,大于或等于该级别的日志都会被输出到记录文件中,小于该级别的日志则不会输出。这里默认设定的是warn级别,则warnerrorcritalertemerg级别的日志都会输出。

如果设定的日志级别是debug,则会输出所有的日志,这样数据量会很大,要确保存放日志的硬盘有足够的空间,同时,如果需要开启日志的debug功能,需要在编译安装的时候在configure时加入--with-debug配置项,如果不确定是否开启了debug功能,可以输入nginx -V查看所有的configure arguments

3.4 pid

pidnginxmaster进程的pid文件,理论上应该和查找的nginx进程中master进程的PID以及worker进程的PPID一致。

3.5 块配置

接下来的eventshttp都是属于模块或者块。最基本的配置项语法格式为配置项名 配置项值1 配置项值2 … ;

  • 一个配置项以英文分号;结束,中间的值使用空格隔开
  • 块配置项由一个块配置项名和一对大括号组成。
  • 块配置项可以嵌套,内层块直接继承外层块。
  • 当内外层块中的配置发生冲突时,究竟是以内层块还是外层块的配置为准,取决于解析这个配置项的模块。
  • 注释部分使用井号

比如上面的log_format这个配置项,变量需要在前面加上美刀符号$,如果变量之间有空格,需要使用单引号或者双引号避免语法错误,同时引号可以嵌套使用。同时需要注意的是,并不是所有的模块都支持使用变量。

1
2
3
log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';

3.6 单位

当指定空间大小时,可以使用的单位包括:

  • K或者k千字节(KiloByte,KB)
  • M或者m兆字节(MegaByte,MB)

当指定时间时,可以使用的单位包括:

  • ms(毫秒)
  • s(秒)
  • m(分钟)
  • h(小时)
  • d(天)
  • w(周,7天)
  • M(月,30天)
  • y(年,365天)

单位之间支持混合使用,如1h30m即为90m如果不指定后缀,那么默认使用s(秒)作为单位。

配置项后的值究竟是否可以使用这些单位,取决于解析该配置项的模块。如果这个模块使用了Nginx框架提供的相应解析配置项方法,那么配置项值才可以携带单位。

4、nginx配置静态页面

接下来我们尝试配置一个简单的静态页面,使用vim对/etc/nginx/conf.d/default.conf进行修改,需要注意的是默认情况下/etc/nginx/conf.d/下面的配置文件只要是.conf即可生效,前面的名称并没有特殊限制,所以最好根据文件的实际用途进行命名方便记忆和管理。

接下来我们在/etc/hosts中将 www.example.com www.example.org www.example.net example.com example.org example.net的DNS解析手动指定为本机IP地址,方便后面使用域名进行配置页面

4.1 default_server

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
[root@localhost conf.d]# ll
总用量 16
-rw-r--r-- 1 root root 1093 3月 4 00:20 default.conf.bak
-rw-r--r-- 1 root root 158 3月 18 00:08 example.com.conf
-rw-r--r-- 1 root root 158 3月 18 00:09 example.net.conf
-rw-r--r-- 1 root root 173 3月 18 00:11 example.org.conf
[root@localhost conf.d]# cat example.*
server {
listen 80;
server_name example.com www.example.com;

location / {
root /var/www/html;
index example.com.html;
}
}
server {
listen 80;
server_name example.net www.example.net;

location / {
root /var/www/html;
index example.net.html;
}
}
server {
listen 80 default_server;
server_name example.org www.example.org;

location / {
root /var/www/html;
index example.org.html;
}
}

这里我们可以看到上面配置了三个server块,分别对应三组域名,三组域名都是指向本机的IP地址,同样都是监听的80端口,其中我们在第三个server块中指定了default_server参数,此时我们访问本机IP,返回的页面就是我们指定了default_server参数的这个页面。

如果我们不指定default_server参数,返回的则是默认的第一个页面。

4.2 location

location块的默认语法如下,官网文档点这里

1
2
3
4
Syntax:	location [ = | ~ | ~* | ^~ ] uri { ... }
location @name { ... }
Default: —
Context: server, location

主要作用是根据请求URI设置配置,location可以由前缀字符串或正则表达式定义。

  • 正则表达式由前面的~*修饰符(不区分大小写)或~修饰符(不区分大小写)指定。
  • 优先顺序是,nginx首先检查使用前缀字符串定义的位置(前缀位置),其中,将选择并记住具有最长匹配前缀的位置。
  • 然后按照在配置文件中出现的顺序检查正则表达式。
  • 正则表达式的搜索在第一个匹配项上终止,并使用相应的配置。
  • 如果未找到与正则表达式匹配的内容,则使用前面记住的前缀位置的配置。

我们来看一下实例:

1
2
3
4
5
6
7
8
9
10
11
12
13
server {
listen 80;
server_name example.com www.example.com;

location / {
root /var/www/html;
index example.com.html;
}

location /images {
root /var/www;
}
}

我们先来看一个server块,这里我们可以看到里面包含了两个location块,在/var/www/html/var/www这两个目录下均有一个images文件夹,但是在www目录下的images文件夹没有images2.html这个文件。

接着我们尝试访问:

可以看到因为我们在www目录下的images文件夹没有images2.html这个文件,所以在执行curl example.com/images/images2.html的时候返回了404请求。

所以我们可以得到结论,当访问域名后面的目录(如这里的/images/),如果在server块里面单独定义了一个相关的location块,则只会在这个/images/目录相关location块定义的目录中去查找,不存在则返回404,并不会再去根目录/location块中的目录中查找。