我正在参加「掘金·启航计划」
Hi~,我是一碗周,一个在舒适区垂死挣扎的前端,如果写的文章有幸可以得到你的青睐,万分有幸~~
🦋 写在前面
最近ChatGPT的热度一直不减,那就用ChatGPT来学一学Nginx,看看会有什么样的一个体验。
你问什么是ChatGPT?那就让它自己来告诉你:
🎉 什么是Nginx?
这个在官网中是什么说的:
NGINX是用于Web服务、反向代理、内容缓存、负载均衡、媒体流传输等场景的开源软件。它最初是一款专为实现最高性能和稳定性而设计的Web服务器。除了HTTP服务器功能以外,NGINX还可用作电子邮件(IMAP、POP3和SMTP)的代理服务器以及HTTP、TCP和UDP服务器的反向代理与负载均衡器。
ChatGPT是什么说的
讲真,说了这么多搞得迷迷糊糊,就记住了Nginx是可以做Web服务器以及反向代理的一个高性能低资源消耗的开源软件就够了。
🌻 优点
恩,这个ChatGPT非常强,也不知道在哪里找的数据,不过这也大大减少了自己的学习成本。
🐁 安装
在ChatGPT中问了好几次也没有问道我想要的安装方式,还是自己来吧~
这里我使用的是源代码编译安装,我的环境:
- Centos7.9
- Nginx1.23.3
首先安装用到的工具:
yum -y install gcc zlib zlib-devel pcre-devel openssl openssl-devel wget
然后执行下面这些命令:
cd /usr/local
mkdir nginx
cd nginx/ # 到目标目录
wget http://nginx.org/download/nginx-1.23.3.tar.gz # 下载指定版本
tar -xvf nginx-1.23.3.tar.gz
cd nginx-1.23.3/
./configure --with-http_stub_status_module --with-http_ssl_module # 添加常用模板
make # 编译
make install # 安装
然后查看版本,查看是否安装成功
$ /usr/local/nginx/sbin/nginx -v
# nginx version: nginx/1.23.3
安装成功之后创建软连接,保证直接可以使用名称访问:
ln -s /usr/local/nginx/sbin/nginx /usr/local/bin/nginx
到这为止就安装成功了,其他安装方式可以在Installing nginx中查看。
🥪 Nginx目录
安装完成之后我们先来看一下安装后的Nginx目录结果是个什么样子:
[root@ywanzhou nginx]$ pwd
/usr/local/nginx
[root@ywanzhou nginx]$ tree
.
├── client_body_temp
├── conf # 存放Nginx中配置文件的路径
│ ├── fastcgi.conf # fastcgi相关参数的配置文件
│ ├── fastcgi.conf.default # 以.default结尾的都是同名文件的备份文件
│ ├── fastcgi_params # fastcgi的参数文件
│ ├── fastcgi_params.default
│ ├── koi-utf # 编码转换映射文件,用于在输出内容到客户端时,将一种编码转换到另一种编码
│ ├── koi-win # 编码转换映射文件,用于在输出内容到客户端时,将一种编码转换到另一种编码
│ ├── mime.types # 设置http协议的Content-Type与扩展名对应关系
│ ├── mime.types.default
│ ├── nginx.conf # **核心配置文件**
│ ├── nginx.conf.default
│ ├── scgi_params # scgi相关参数文件
│ ├── scgi_params.default
│ ├── uwsgi_params # uwsgi相关参数文件
│ ├── uwsgi_params.default
│ └── win-utf # 编码转换映射文件,用于在输出内容到客户端时,将一种编码转换到另一种编码
├── fastcgi_temp # fastcgi临时数据目录
├── html # nginx中默认的站点目录
│ ├── 50x.html
│ └── index.html
├── logs # 日志存放目录
│ ├── access.log # 访问日志
│ ├── error.log # 错误日志
│ └── nginx.pid # nginx启动后,会将pid存入该文件
├── proxy_temp
├── sbin # nginx命令目录
│ └── nginx
├── scgi_temp
└── uwsgi_temp
9 directories, 21 files
上面就是对Nginx目录的一个解释。
现在可以尝试一下启动Nginx服务,看看是否有效果,你可以执行下面两个命令之中的一个来启动Nginx:
nginx
# 或者
systemctl start nginx.service
如果想要确定Nginx是否启动,可以通过下面这个命令查看:
[root@ywanzhou ~]$ ps aux | grep nginx # 查看nginx是否启动,如果启动返回结果与下面类似
root 19577 0.0 0.0 46004 1132 ? Ss Feb14 0:00 nginx: master process nginx
nobody 19578 0.0 0.1 48536 2228 ? S Feb14 0:00 nginx: worker process
root 32259 0.0 0.0 112812 980 pts/0 S+ 09:26 0:00 grep --color=auto nginx
OK子,应该就这么多,简答介绍一下目录,下面来介绍一下常用命令。
不对,忘记说了一点,如果想要访问方才启动的Nginx的页面,如果是自己的虚拟机直接把防火墙关了访问ip地址就可以,如果是购买的服务器需要开放80端口才可以访问,访问成功的页面如下:
🥑 Nginx的常用命令
现在我们来简单介绍一下Nginx中的常用指令,首先我们来问一下ChatGPT,得到的回复如下:
为了方便大家复制命令,我将上面的内容复制了一份。
以下是一些常用的Nginx指令:
nginx
:启动Nginx服务器。nginx -s stop
:停止正在运行的Nginx服务器。nginx -s quit
:优雅地停止Nginx服务器。nginx -s reload
:重新加载Nginx配置文件,无需停止服务器。nginx -t
:检查Nginx配置文件的语法是否正确。nginx -V
:显示Nginx版本和编译选项信息。nginx -h
:显示Nginx的命令行选项。sudo systemctl start nginx
:在Linux上使用systemd启动Nginx。sudo systemctl stop nginx
:在Linux上使用systemd停止Nginx。sudo systemctl restart nginx
:在Linux上使用systemd重新启动Nginx。
我这里简单的总结了一张图,如下所示:
🐬 Nginx配置文件
Nginx的配置文件这里通常指的的./conf/nginx.conf
文件,下面就是Nginx中的默认的配置文件:
#user nobody; # 指定用户使用nginx
worker_processes 1; # nginx工作进程数,一般与cpu核数相同
#error_log logs/error.log; # 日志存放目录
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid; # nginx的pid存放目录
events {
worker_connections 1024; # 每个进程允许的最大连接数
}
http {
include 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 logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
server {
# 一些配置文件
}
}
上面是Nginx配置文件中的一部分,想要学习Nginx配置文件,首先我们先来了解一下Nginx配置文件的语法:
🐋 配置文件语法
- 注释:在Nginx的配置文件中,注释以
#
开头; - 指令:说的是Nginx服务器如何处理请求的规则,每个指令都要以一个分号
;
结尾,它可以包含一个或者多个参数,例如:
指令和参数中间以空格分割,空格的数量没有要求。include mime.types; # 引入其他的配置文件 worker_processes 1; # nginx工作进程数,一般与cpu核数相同
- 指令块:类似于JavaScript中的代码块,由一对
{}
进行包裹,例如:events { worker_connections 1024; # 每个进程允许的最大连接数 } http { include mime.types; # 引入其他的配置文件 default_type application/octet-stream; }
- 变量:Nginx中的变量的格式为
$variable_name
,具体Nginx中包含什么变量,以及变量的具体含义后面在进行解释。
🦄 全局配置
首先我们先来说一下Nginx中的全局配置,也就是:user
、worker_processes
、error_log
、pid
这四个配置,这四个配置理解起来很容易,如下所示:
user
:用于设置Nginx服务所使用的用户;worker_processes
:用于设置Nginx服务器的进程数量,通常与CPU的核数一致,设置少了服务器的性能没有充分利用,设置多了造成没有必要的进程切换;error_log
:Nginx错误日志的存放路径;pid
:Nginx服务所启动时的pid。
🍞 events指令块
在Nginx中的配置文件中,events
指令块用来定义用来定义事件模型和每个进程的最大连接数量,例如默认的例子中:
events {
worker_connections 1024; # 每个进程允许的最大连接数
}
worker_connections
的指令就指定了每个进程允许连接的最大并发数量。
除此之外,events
指令块还具有以下的其他参数:
multi_accept
:允许每个worker进程一次性接收多个新连接,默认为off。accept_mutex
:允许多个worker进程争抢新连接,默认为on。accept_mutex_delay
:设置worker进程获取accept_mutex的超时时间,默认为500毫秒。use
:指定Nginx使用的事件模型,支持select
、poll
、epoll
和kqueue
等。默认值取决于操作系统类型和版本,建议让系统自行选择。
🥦 http指令块
http
指令块是Nginx配置文件中最重要的一个配置,它用于配置Nginx作为服务器的一些行为。
它的语法如下所示:
http {
include 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 logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
server {
# 一些 server 块的配置
}
}
http
指令块可以分为两个部分,一个是全局性的指令配置,另一个是server
指令块(可以包含多个),这里我们就先了解一下http
指令块中的全局性的指令配置,关于server
指令块我们在下一部分看。
在http
配置块中,还可以定义一些全局性的配置指令,如下所示:
include
: 包含其他的配置文件;types
:定义文件扩展名和对应的Content-Type;default_type
:定义默认的Content-Type类型,默认为default_type text/plain
;access_log
:指定Nginx的访问日志文件路径;sendfile
:指定Nginx是否启用sendfile
指令进行高效的文件传输,默认为on;tcp_nopush
:指定Nginx是否启用tcp_nopush
指令进行数据推送,默认为off;keepalive_timeout
:指定Nginx与客户端保持连接的超时时间,默认为75秒;gzip
:控制是否对响应内容进行gzip压缩;server
:定义一个HTTP服务器。
🐏 server指令块
server
指令块用于配置一个HTTP服务器,每一个HTTP服务器都表示一个虚拟主机,用于监听HTTP请求,并将接收的请求分发到**location
**指令块进行处理。
一个http
指令块可以包含多个server
指令块,一个server
指令块可以包含多个location
指令块,实例如下所示:
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
我们依次来看:
listen
:用于指定虚拟主机监听的IP地址和端口,它是支持多个的;server_name
:用于指定虚拟主机的域名/IP,支持通配符和正则表达式,可以配置多个,以空格分割;以下是一些例子:server_name www.ywanzhou.com; # 精确匹配 server_name *.ywanzhou.com; # 通配符 可以匹配 test.ywanzhou.com blog.ywanzhou.com等 server_name ^www\.(\w)\.com$; # 正则,可以匹配www.*.com的域名 # 匹配顺序是 精确 通配符 正则
charset
:字符集;access_log
:用于配置访问日志的文件路径。access_log logs/host.access.log main # 将访问日志存放进logs/host.access.log日志格式为 main ,也就是http指令块中log_format指令指定的格式
location
:指令块用于配置URL与资源的映射关系,它支持正则,非常的强大,这里就简单介绍一下,后面在详细的说。root
:用于指定虚拟主机的根目录,即请求的URL对应的文件在服务器中的存储路径。index
:用于指定默认访问的文件名,如果用户访问的URL路径不包含文件名,则会默认访问该指令设置的文件。
error_page
:该指令用于定义HTTP错误页面的处理方式,简单说就是当我们访问的页面不存在时,我们可以通过error_page
指令来指定错误页面,就拿下面这个例子来说:
其中的error_page 500 502 503 504 /50x.html;
500 502 503 504
表示状态码,如果出现这些跳转到对应的页面,而/50x.html
是指定的目标URL。
🌸 Nginx的执行流程
最后我们来了解一下Nginx接收到请求后的一个执行流程,从客户端发送请求到Nginx返回响应体大致为以下几个步骤:
- 解析请求:当Nginx接收到一个请求时,会首先解析该请求的头部信息,包括请求方法、请求URI、HTTP版本、请求头部等等;
- 确定
server
块:根据上一步解析的信息,确定该请求应该交给哪个server
块进行处理; - 确定
location
块:根据URL去寻找对应的location
块,如果没有找到则使用默认的location
块进行处理。 - 处理请求:根据选择的
location
块中的配置,对请求进行处理。可能的处理方式包括反向代理、重定向、文件读取、CGI脚本执行等等。 - 响应体处理:根据请求的内容去返回不同的内容:
- 如果是动态请求Nginx则会将请求进行转发;
- 如果是静态资源则会根据配置的静态资源目录进行查找;
- 如果缓存中存在则会从缓存中返回;
- 如果请求存在问题,则会返回对应的错误页面;
- 返回响应:Nginx将处理结果返回给客户端,包括响应头部、响应状态码、响应内容等信息。
💫 写在最后
这篇文章介绍的几乎都是Nginx中的概念问题,还是比较枯燥的,用了很大的篇幅来介绍Nginx中的配置文件,可以用作参考
这篇文章是《前端&运维那点事儿》专栏中Nginx系列的第一篇文章,后面还会有几篇文章继续来玩Nginx。
如果对这个专栏感兴趣可以点一个关注,会一直持续更新~