初识 Nginx
FROM 黑马程序员Nginx教程,Java进阶从0到1学会Nginx分布式框架_哔哩哔哩_bilibili (opens new window)
# 1. Nginx 简介
# 1.1 背景介绍
Nginx(“engine x”)一个具有高性能的 HTTP 和反向代理的 Web 服务器,由伊戈尔·赛索耶夫用 C 语言编写,开源。
# 1.2 什么是反向代理?
没有使用代理前,客户端将请求发给服务端,服务端再将响应返回给客户端。
但有一种情况是服务端可能禁掉某一类客户端的访问,这时客户端就可以用一个代理来实现访问服务端【正向代理】:
反向代理则是,客户端将请求发给 proxy,然后 proxy 将其转发给某一个服务端:
正向代理主要服务的是 client,而反向代理则主要服务的是 server。
# 1.3 常见服务器对比
# 1)IIS
全称 Internet Information Services,即互联网信息服务,是由微软公司提供的基于 Windows 系统的互联网基本服务,但 Windows 不适合做服务器。
# 2)Tomcat
Tomcat 是一个运行 Servlet 和 JSP 的 Web 应用软件,深受 Java 爱好者的喜爱,较为流行,但是 Tomcat 天生是一个重量级的 Web 服务器,对静态文件和高并发的处理比较弱。
# 3)Apache
它出现的时间太久了,在其兴起的年代互联网产业规模远不如今天,它被设计成一个重量级的、不支持高并发的 Web 服务器。
# 4)Lighttpd
它和 Nginx 一样,都是轻量级、高性能的 Web 服务器,欧美的业界开发者比较钟爱 Lighttpd,而国内的公司更多的青睐 Nginx。
其他的服务器还有 Google Servers,Weblogic, Webshpere(IBM)...
# 5)Nginx 优点
- 速度快,并发高:Nginx 采用了多进程和 I/O 多路复用(epoll)的底层实现
- 配置简单,扩展性强
- 高可靠性:采用多进程模式运行,有一个 master 主进程和 N 多个 worker 进程
- 热部署:可以在 Nginx 不停止的情况下,对 Nginx 进行文件升级、更新配置和更换日志文件等功能
- 成本低,BSD 许可证
# 1.4 Nginx 功能特性
其基本功能服务从大体上归纳为"基本HTTP服务"、“高级HTTP服务”和"邮件服务"等三大类。
# 1.4.1 Nginx 常用的功能模块
- 静态资源部署
- Rewrite地址重写
- 反向代理
- 负载均衡:轮询、加权轮询、ip_hash、url_hash、fair
- Web 缓存
- 环境部署:高可用的环境
- 用户认证模块
这些模块需要重点学习
# 1.4.2 Nginx 核心组成
- nginx 二进制可执行文件
- nginx.conf 配置文件
- error.log 错误的日志记录
- access.log 访问日志记录
# 2. Nginx 环境准备
# 2.1 源码安装所需的环境
- gcc:
yum install -y gcc
- PCRE:正则表达式库,
yum install -y pcre pcre-devel
- zlib:提供了压缩算法,
yum install -y zlib zlib-devel
- OpenSSL:用于安全通信,
yum install -y openssl openssl-devel
建议关闭防火墙:
systemctl stop firewalld 关闭运行的防火墙,系统重新启动后,防火墙将重新打开
systemctl disable firewalld 永久关闭防火墙,,系统重新启动后,防火墙依然关闭
systemctl status firewalld 查看防火墙状态
2
3
确认停用 selinux:
虽然 selinux 会让系统跟安全,但学习 nginx 会有很多设置,关闭它可以防止趟坑。可以通过 sestatus
查看状态,如果不是 disabled 状态的话们可以设置 SELINUX=disabled
并重启:
vim /etc/selinux/config
# 2.2 Nginx 的源码简单安装
- 在官网找到某个版本的下载地址:
wget http://nginx.org/download/nginx-1.16.1.tar.gz
- 建议将下载的资源进行包管理
mkdir -p nginx/core
mv nginx-1.16.1.tar.gz nginx/core
2
- 解压缩
tar -xzf nginx-1.16.1.tar.gz
- 进入资源文件,发现 configure 并执行
./configure
- 编译并安装
make & make install
默认的安装地址是 /usr/local/nginx
,进入后有一个 sbin
文件夹,进入后启动里面的 nginx
:
./nginx
此时在浏览器中输入服务器的 URL 便可以看到 Nginx 的欢迎页面。如果看不到,看一下防火墙关了没。
# 2.3 yum 安装
这里不再介绍
# 2.4 Nginx 的源码复杂安装
与简单安装不同的地方在于第一步的 ./configure
,它可以手动加上编译参数来进行设置,这里讲一下有哪些参数可以进行设置
这些配置大致分成三大类:
- PATH,是和路径相关的配置信息
- with,是启动模块,通常用于添加第三方模块的支持,默认是关闭的
- without,是关闭模块,用于排除掉一些我们不想用的模块,默认是开启的
# 2.4.1 一些简单的路径配置
- –prefix=PATH:指向 Nginx 的安装目录,默认值为/usr/local/nginx
- --sbin-path=PATH:指向(执行)程序文件(nginx)的路径,默认值为
<prefix>/sbin/nginx
- --modules-path=PATH:指向 Nginx 动态模块安装目录,默认值为
<prefix>/modules
- --conf-path=PATH🔥:指向配置文件(nginx.conf)的路径,默认值为
<prefix>/conf/nginx.conf
- --error-log-path=PATH:指向错误日志文件的路径,默认值为
prefix>/logs/error.log
- --http-log-path=PATH:指向访问日志文件的路径,默认值为
<prefix>/logs/access.log
- --pid-path=PATH:指向 Nginx 启动后进行ID的文件路径,默认值为
<prefix>/logs/nginx.pid
- --lock-path=PATH:指向 Nginx 锁文件的存放路径,默认值为
<prefix>/logs/nginx.lock
要想使用可以通过如下命令:
./configure --prefix=/usr/local/nginx \
--sbin-path=/usr/local/nginx/sbin/nginx \
--modules-path=/usr/local/nginx/modules \
--conf-path=/usr/local/nginx/conf/nginx.conf \
--error-log-path=/usr/local/nginx/logs/error.log \
--http-log-path=/usr/local/nginx/logs/access.log \
--pid-path=/usr/local/nginx/logs/nginx.pid \
--lock-path=/usr/local/nginx/logs/nginx.lock
2
3
4
5
6
7
8
# 2.4.2 卸载之前安装的 nginx
- 将 nginx 进程关闭:
./nginx -s stop
- 将安装的 nginx 进行删除:
rm -rf /usr/local/nginx
- 将安装包之前编译的环境清除掉:
cd ~/nginx/core/nginx... # 回到解压的安装包里面
make clean
2
# 2.4.3 卸载后重新安装
与简单安装的过程一样,只是在运行 configure
步骤中加入 2.4.1 节的参数配置。
# 2.5 Nginx 目录结构分析
tree 工具可以方便查看 Centos 系统上的目录结构,可以通过
yum install -y tree
来安装。
tree /usr/local/nginx
查看目录结构:
- conf:存放 nginx 所有配置文件的目录
CGI
CGI(Common Gateway Interface)通用网关接口,主要解决的问题是从客户端发送一个请求和数据,服务端获取到请求和数据后可以调用调用 CGI 程序处理及相应结果给客户端的一种标准规范。CGI 程序实现了 CGI 接口。
由于 CGI 效率较低,因此又有了 fastcgi、uwcgi 等。在 conf 里面有很多以 .default
结尾的文件,它是不带 default 的文件的一个备份。
koi-utf、koi-win、win-utf 是与编码转换相关的配置文件,用于实现从一种编码转换到另一种编码
mime.types:记录的是 HTTP 协议中的 Content-Type 的值和文件后缀名的对应关系
nginx.conf:Nginx 的核心配置文件,非常重要,也是学习重点。
html 里面有自带的两个静态的 html 页面,index.html 是成功访问的默认首页,50x.html 是访问失败后的失败页面。
logs 目录:
- access.log:访问日志
- error.log:错误日志
- nginx.pid:nginx 进程的 PID
sbin:存放执行程序文件 nginx,他可以用来控制 nginx 的启动和停止等相关的命令。
# 2.6 Nginx 服务器启停命令
接下来我们要学习的是如何启动、重启和停止 Nginx 的服务。有多种方式,我们只学习两种:
- Nginx 服务的信号控制
- Nginx 的命令行控制【日常开发常用】
# 2.6.1 Nginx 服务的信号控制
Nginx 默认采用的是多进程的方式来工作的,可以通过 ps -ef | grep nginx
来查看它的进程:
可以看到 nginx 进程包含一个 master 进程与多个 worker 进程:
- master 进程主要用来管理worker进程,包含接收外界的信息,并将接收到的信号发送给各个worker进程,监控worker进程的状态,当worker进程出现异常退出后,会自动重新启动新的worker进程。
- worker进程则是专门用来处理用户请求的,各个worker进程之间是平等的并且相互独立,处理请求的机会也是一样的。
我们作为管理员,只需给 master 发送信号就能控制 nginx。这需要 master 的进程 pid 和信号。
# 如何得知 master 的 pid?
- 方式 1:
ps -ef | grep nginx
- 方式 2:查看 nginx 目录下的 nginx.pid 文件
# 有哪些信号?
信号 | 作用 |
---|---|
TERM/INT | 立即关闭整个服务 |
QUIT | "优雅"地关闭整个服务 |
HUP | 重读配置文件并使用服务对新配置项生效 |
USR1 | 重新打开日志文件,可以用来进行日志切割 |
USR2 | 平滑升级到最新版的 nginx,会重启 master 和 worker。用于在保持 nginx 服务器不重新启动的情况下升级 nginx。 |
WINCH | 让所有 work 进程不再接收处理新连接,相当于给 work 进程发送 QUIT 指令。注意 master 不会被关掉。 |
调用命令为 kill -signal PID
# 2.6.2 Nginx 的命令行控制
此方式是通过 sbin
下的可执行文件 nginx
来进行 Nginx 状态的控制。我们可以通过 nginx -h
来查看都有哪些参数可以用:
[root@hspEdu01 sbin]# ./nginx -h
nginx version: nginx/1.16.1
Usage: nginx [-?hvVtTq] [-s signal] [-c filename] [-p prefix] [-g directives]
Options:
-?,-h : this help
-v : show version and exit
-V : show version and configure options then exit
-t : test configuration and exit
-T : test configuration, dump it and exit
-q : suppress non-error messages during configuration testing
-s signal : send signal to a master process: stop, quit, reopen, reload
-p prefix : set prefix path (default: /usr/local/nginx/)
-c filename : set configuration file (default: /usr/local/nginx/conf/nginx.conf)
-g directives : set global directives out of configuration file
2
3
4
5
6
7
8
9
10
11
12
13
14
15
- -s:signal 信号,后面可以跟:
- stop:快速关闭,类似于 TERM/INT 信号的作用
- quit:优雅的关闭,类似于 QUIT 信号的作用
- reopen:重新打开日志文件类似于 USR1 信号的作用
- reload:类似于HUP信号的作用
- -t:测试 nginx 的配置文件语法是否正确并退出
# 2.7 Nginx 服务器版本升级和新增模块
最简单的做法是停掉当前 nginx 服务,然后开一个新的。但这样会导致一段时间内用户无法访问服务器。因此我们需要用到 nginx 服务器提供的平滑升级功能。
需求:Nginx 的版本最开始使用的是 Nginx-1.14.2,由于服务升级,需要将 Nginx 的版本升级到 Nginx-1.16.1,要求 Nginx 不能中断提供服务。
有两种升级方式:使用 nginx 服务信号完成 nginx 升级;使用 nginx 安装目录的 make 命令完成升级。这里不再详细介绍。
# 3. Nginx 核心配置文件结构
默认在 /usr/local/nginx/conf/nginx.conf
,这一节我们学习一下 nginx.conf 的内容和基本配置方法。我们看一下它里面的内容(删掉了注释信息):
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
location / {
root html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
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
- 格式大都是
指令名 指令值
- 最外层是全局块,主要设置 Nginx 服务器整体运行的配置指令
- events 块,用于配置与用户的网络连接,这一部分对 Nginx 服务器的性能影响较大
- http 块,是 Nginx 服务器配置中的重要部分。里面可以配置多个 server 块,它是 Nginx 配置和虚拟主机相关的内容。
- server 块,有一个
listen
和server_name
指令,表示这个 server 块所要拦截的请求。当请求过来后,处理是看 location 块。 - location 块,基于 Nginx 服务器接收请求字符串与 location 后面的值进行匹配,对特定请求进行处理。
nginx.conf 小结
- nginx.conf 配置文件中默认有三大块:全局块、events 块、http 块
- http 块中可以配置多个 server 块,每个 server 块又可以配置多个 location 块
# 3.1 全局块
# 1)user 指令
用于配置运行 Nginx 服务器的 worker 进程的用户和用户组。
语法 | user user [group] |
---|---|
默认值 | nobody |
位置 | 全局块 |
该属性也可以在编译的时候指定,语法如下
./configure --user=user --group=group
,如果两个地方都进行了设置,最终生效的是配置文件中的配置。
指令的使用步骤:
先通过 useradd www
新加一个名为 www 的用户,然后在 nginx.conf 中加上:
user www
完成之后在 ./nginx -t
检查一下,成功后可以 ./nginx -s reload
重新加载。
使用 user 指令可以指定启动运行工作进程的用户及用户组,这样对于系统的权限访问控制的更加精细,也更加安全。比如 www 的 nginx 工作进程无法访问 root 的文件。
# 2)work process 指令
master_process 指令用来指定是否开启工作进程,指令值为 on/off,默认 on。这个指令修改后需要重新启动。
worker_processes 指令用于配置 Nginx 生成工作进程的数量,这个是 Nginx 服务器实现并发处理服务的关键所在。
理论上来说 workder process 的值越大,可以支持的并发处理量也越多,但事实上这个值的设定是需要受到来自服务器自身的限制,建议将该值和服务器 CPU 的内核数保存一致。
语法 | worker_processes num/auto; |
---|---|
默认值 | 1 |
位置 | 全局块 |
# 3)其他指令
🖊 daemon:设定 Nginx 是否以守护进程的方式启动。
语法 | daemon on|off; |
---|---|
默认值 | daemon on; |
位置 | 全局块 |
守护式进程是linux后台执行的一种服务进程,特点是独立于控制终端,不会随着终端关闭而停止。
🖊 pid:用来配置 Nginx 当前 master 进程的 pid 存储的文件路径。
语法 | pid file; |
---|---|
默认值 | 默认为 /usr/local/nginx/logs/nginx.pid |
位置 | 全局块 |
该属性可以通过 ./configure --pid-path=PATH
来指定
🖊 error_log:用来配置 Nginx 的错误日志存放路径
语法 | error_log file [日志级别]; |
---|---|
默认值 | error_log logs/error.log error; |
位置 | 全局块、http、server、location |
该属性可以通过 ./configure --error-log-path=PATH
来指定。
其中日志级别的值有 debug|info|notice|warn|error|crit|alert|emerg,建议大家设置的时候不要设置成 info 以下的等级,否则会带来大量的磁盘 I/O 消耗。
🖊 include:用来引入其他配置文件,使 Nginx 的配置更加灵活
语法 | include file; |
---|---|
默认值 | 无 |
位置 | any |
# 3.2 events 块
# 1)accept_mutex
用来设置 Nginx 网络连接序列化
语法 | accept_mutex on|off; |
---|---|
默认值 | accept_mutex on; |
位置 | events |
这个配置主要可以用来解决常说的"惊群"问题。大致是说,如果设置为 off,当客户端发来一个请求,那所有 worker 同时被惊醒并竞争,最终只会有一个进程可以获取到连接,如果每次唤醒的进程数目太多,就会影响到 nginx 的整体性能。如果设置为 on,将会对多个 nginx 进程接收连接进行序列号,一个个来唤醒接收,防止了多个进程对连接的争抢。
具体选 on 还是 off 取决于具体的生产环境,当多个骨头丢过来时,设置为 off 从而同时惊醒所有狗来竞争反而效率会高。
# 2)multi_accept
用来设置是否允许同时接收多个网络连接
语法 | multi_accept on|off; |
---|---|
默认值 | multi_accept off; |
位置 | events |
如果 multi_accept 被禁止了,nginx 一个工作进程只能同时接受一个新的连接。否则,一个工作进程可以同时接受所有的新连接。建议设为 on。
# 3)worker_connections
用来配置单个 worker 进程最大的连接数
语法 | worker_connections number; |
---|---|
默认值 | worker_commections 512; |
位置 | events |
这里的连接数不仅仅包括和前端用户建立的连接数,而是包括所有可能的连接数。另外,number 值不能大于操作系统支持打开的最大文件句柄数量。
# 4)use
设置 Nginx 选择哪种事件驱动来处理网络消息
语法 | use method; |
---|---|
默认值 | 根据操作系统定 |
位置 | events |
注意:此处所选择事件处理模型是 Nginx 优化部分的一个重要内容,method的可选值有 select/poll/epoll/kqueue 等。建议设置为 epoll。
Linux kernel 在 2.6 以上才支持 epoll 函数。
# 5)events 块配置实例
在 nginx.conf 中配置:
events {
accept_mutex on;
multi_accept on;
worker_commections 1024;
use epoll;
}
2
3
4
5
6
启动测试:
./nginx -t
./nginx -s reload
2
# 3.3 http 块
# 1)定义 MIME-Type
浏览器中可以显示的内容有 HTML、XML、GIF 等种类繁多的文件、媒体等资源,浏览器为了区分这些资源,就需要使用 MIME Type。所以说 MIME Type 是网络资源的媒体类型。Nginx 作为web服务器,也需要能够识别前端请求的资源类型。
在 Nginx 的配置文件中,默认有两行配置:
include mime.types;
default_type application/octet-stream;
2
- mime.types 文件记录了不同的 MIME Type 和文件类型的对应关系
- default_type 指令用来配置 Nginx 响应前端请求默认的 MIME 类型:
语法 | default_type mime-type; |
---|---|
默认值 | default_type text/plain; |
位置 | http、server、location |
示例:有些时候请求某些接口需要返回指定的文本字符串,如果逻辑非常简单或者固定的字符串,那么可以使用 nginx 快速实现,这样就不用编写程序响应请求了:
location /get_text {
#这里也可以设置成 text/plain
default_type text/html;
return 200 "This is nginx's text";
}
location /get_json {
default_type application/json;
return 200 '{"name":"TOM","age":18}';
}
2
3
4
5
6
7
8
9
10
# 2)自定义服务日志
Nginx 中日志的类型分 access.log、error.log
- access.log:用来记录用户所有的访问请求
- error.log:记录 nginx 本身运行时的错误信息,不会记录用户的访问请求
Nginx 服务器支持对服务日志的格式、大小、输出等进行设置,需要使用到两个指令,分别是 access_log 和 log_format 指令。
🖊 access_log 指令用来设置用户访问日志的相关属性
语法 | access_log path[format[buffer=size]] |
---|---|
默认值 | access_log logs/access.log combined; |
位置 | http , server , location |
🖊 log_format 指令用来指定日志的输出格式
语法 | log_format name [escape=default|json|none] string....; |
---|---|
默认值 | log_format combined "..."; |
位置 | http |
# 3)其他配置指令
🖊 sendfile:设置 Nginx 服务器是否使用 Linux 函数 sendfile()
传输文件,该属性可以大大提高 Nginx 处理静态资源的性能,建议为 on
语法 | sendfile on|off; |
---|---|
默认值 | sendfile off; |
位置 | http、server、location |
🖊 keepalive_timeout:设置长连接的超时时间
语法 | keepalive_timeout time; |
---|---|
默认值 | keepalive_timeout 75s; |
位置 | http、server、location |
为什么要使用 keepalive?
我们都知道 HTTP 是一种无状态协议,客户端向服务端发送一个 TCP 请求,服务端响应完毕后断开连接。
如何客户端向服务端发送多个请求,每个请求都需要重新创建一次连接,效率相对来说比较多,使用 keepalive 模式,可以告诉服务器端在处理完一个请求后保持这个 TCP 连接的打开状态,若接收到来自这个客户端的其他请求,服务端就会利用这个未被关闭的连接,而不需要重新创建一个新连接,提升效率,但是这个连接也不能一直保持,这样的话,连接如果过多,也会是服务端的性能下降,这个时候就需要我们进行设置其的超时时间。
🖊 keepalive_requests:设置一个 keep-alive 连接使用的次数
语法 | keepalive_requests number; |
---|---|
默认值 | keepalive_requests 100; |
位置 | http、server、location |
# 3.4 server 块和 location 块
这部分会在后面对 Nginx 的功能进行详细讲解时会继续学习。本节我们主要来认识下 Nginx 默认的 nginx.conf 中的相关内容,以及 server 块与 location 块在使用的时候需要注意的一些内容。
server {
listen 80;
server_name localhost;
location / {
root html;
index index.html index.htm;
}
error_page 500 502 503 504 404 /50x.html;
location = /50x.html {
root html;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
- location 下面的
root
指令代表资源所在的目录,index
指令可以设置多个值,它会从前往后直到找到一个为止。