nginx的编译安装、添加模块、yum安装、简单配置、默认目录作用和静态页面配置。
0、编译安装nginx
0.1 准备工作
这里我们使用nginx的mainline版本的1.17.9来进行编译安装,nginx各版本的官网下载地址:http://nginx.org/en/download.html
首先我们下载并解压nginx源码
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来进行安装:
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的目录,输入下面的指令可以查看各类的编译参数,或者在官网也可以看到:
./configure --help
我们这里使用的参数是:
./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安装:
make
make install
如无意外此时应该已经正常安装好了,我们到前面指定的安装目录看一下
注意这个时候我们如果需要使用nginx需要指定这个安装目录,想要全局使用我们可以创建一个软链接:
ln -s /usr/local/nginx/nginx /usr/sbin/nginx
0.3 添加模块
同时,如果之后有需要用到的模块而在编译安装的时候忘了安装也没关系,我们可以继续编译添加新模块
首先我们需要查看已经编译的参数:
[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:
这一栏里面我们就可以看到之前编译的时候的参数,对比上面的记录我们可以看到是一模一样的,然后我们会到之前下载的源码目录,注意是源码的目录不是安装的目录,然后添加上之前的编译参数,再添加新的模块,
./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_v2
、mail
、mail_ssl
三个模块
如果想要添加第三方模块的话,只需要使用--add-module=
然后加上第三方模块的路径即可。
--add-module=/home/echo-nginx-module-0.61
最后我们的编译参数是:
./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
了
make
make install
最后我们再确定一下是否安装成功:
1、yum安装nginx
1.1 yum仓库建立和安装配置
centos自带的repo中就有nginx,可以直接安装,但是版本比较旧,想要使用yum进行安装最新的稳定版本,我们需要自行配置yum仓库。
[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。
yum install yum-utils
yum-config-manager --enable nginx-mainline
yum clean all
yum repolist
yum install nginx
安装的时候需要注意这个列出信息中的repo应该是我们刚刚新建的repo。
安装完成之后需要设置开机启动和防火墙放行80端口,如果使用https还需要放行443端口。
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
接下来我们可以测试一下安装和启动是否成功。
nginx -v
curl 127.0.0.1
1.2 master和worker进程
使用ps命令查看进程,我们可以看到有一个master进程和一个worker进程,默认情况下,worker的进程数量为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.log
和error.log
两个文件,前者负责记录每一个被访问的记录,后者负责记录访问中出现的错误。
2.2 nginx命令
输入nginx -h
即可查看所有指令,不需要特意去记忆,用多了就自然记住了。
3、nginx.conf文件
我们把整个全局配置文件拿出来分析一下:
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
是日志的存放位置和输出等级,等级的取值范围是debug
、info
、notice
、warn
、error
、crit
、alert
、emerg
,从左至右级别依次增大。当设定为一个级别时,大于或等于该级别的日志都会被输出到记录文件中,小于该级别的日志则不会输出。这里默认设定的是warn级别,则warn
、error
、crit
、alert
、emerg
级别的日志都会输出。
如果设定的日志级别是
debug
,则会输出所有的日志,这样数据量会很大,要确保存放日志的硬盘有足够的空间,同时,如果需要开启日志的debug
功能,需要在编译安装的时候在configure
时加入--with-debug
配置项,如果不确定是否开启了debug
功能,可以输入nginx -V
查看所有的configure arguments
。
3.4 pid
pid
是nginx
的master
进程的pid
文件,理论上应该和查找的nginx
进程中master
进程的PID
以及worker
进程的PPID
一致。
3.5 块配置
接下来的events
和http
都是属于模块或者块。最基本的配置项语法格式为配置项名 配置项值1 配置项值2 … ;
- 一个配置项以英文分号
;
结束,中间的值使用空格隔开 - 块配置项由一个块配置项名和一对大括号组成。
- 块配置项可以嵌套,内层块直接继承外层块。
- 当内外层块中的配置发生冲突时,究竟是以内层块还是外层块的配置为准,取决于解析这个配置项的模块。
- 注释部分使用井号
#
比如上面的log_format
这个配置项,变量需要在前面加上美刀符号$
,如果变量之间有空格,需要使用单引号或者双引号避免语法错误,同时引号可以嵌套使用。同时需要注意的是,并不是所有的模块都支持使用变量。
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
[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块的默认语法如下,官网文档点这里。
Syntax: location [ = | ~ | ~* | ^~ ] uri { ... }
location @name { ... }
Default: —
Context: server, location
主要作用是根据请求URI设置配置,location可以由前缀字符串或正则表达式定义。
- 正则表达式由前面的
~*
修饰符(不区分大小写)或~
修饰符(不区分大小写)指定。 - 优先顺序是,nginx首先检查使用前缀字符串定义的位置(前缀位置),其中,将选择并记住具有最长匹配前缀的位置。
- 然后按照在配置文件中出现的顺序检查正则表达式。
- 正则表达式的搜索在第一个匹配项上终止,并使用相应的配置。
- 如果未找到与正则表达式匹配的内容,则使用前面记住的前缀位置的配置。
我们来看一下实例:
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
块中的目录中查找。