文章目录
一、前言
Nginx 配置文件你真的懂吗?当你安装完成后就可以访问到如下图测试页面,那它的实现流程又是怎样的呢?
接下来将从 0-1 来演示一下 Nginx 流程。
二、NGINX 指令与上下文
2.1 指令
去掉 Nginx 默认的其他部分,从最简单的指令语句开始解剖 nginx 配置文件的作用。
如下编写的几行代码,虽然看似简单,但却介绍了 NGINX 配置文件中两个最重要的术语。它们是指令和上下文。
如下 zhurs.tech 域名是一个虚拟域名,我们做实验时需要在你的 /etc/hosts
文件下做本地解析。
events {
}
http {
server {
listen 80;
server_name zhurs.tech;
return 200 "hello nginx!\n";
}
}
从技术上讲,NGINX 配置文件中的所有内容都是指令。指令有两种类型:
- 简单指令:一个简单的指令由指令名称和其参数组成(指令名称与其参数以空格分隔),且以分号结束。例如
listen
、return
。 - 块指令:
{ }
块指令类似于简单指令,不同之处在于它们不是以分号结尾,而是以一对包含附加指令的大括号结束。
2.2 上下文
能够在其内部包含其他指令的块指令称为上下文,即events
,http
依此类推。NGINX 中有四个核心上下文:
events { }
:events
上下文用于设置有关 NGINX 将如何在一般级别处理请求的全局配置。一个有效的配置文件中只能有一个events
上下文。http { }
:http
上下文用于定义有关服务器将如何处理 HTTP 和 HTTPS 请求的配置。一个有效的配置文件中只能有一个http
上下文。server { }
:server
上下文嵌套在http
上下文中,用于在单个主机中配置特定的虚拟服务器。server
上下文中可以有多个,每个server
上下文都被视为一个虚拟主机。main
:main
上下文是配置文件本身。在前面提到的三个上下文之外编写的任何内容都在main
上下文中。
一个 http { }
上下文可包含多个 server { }
上下文,那当请求到达服务器时,NGINX 如何处理哪一个 server { }
的上下文请求?具体实现如下:
events {
}
http {
server {
listen 80;
server_name zhurs.tech;
return 200 "nginx port 80!\n";
}
server {
listen 8080;
server_name zhurs.tech;
return 200 "nginx port 8080!\n";
}
}
流程:
- 当客户端向 http://zhurs.tech:80 发起请求时,那么将会收到来自
nginx port 80!
的响应; - 当客户端向 http://zhurs.tech:8080 发起请求时,那么将会收到来自
nginx port 8080!
的响应;
这两个 server {}
上下文就像两个拿着电话听筒的人,在请求到达其中一个号码时等待响应。它们的“号码(即端口)”
由listen
指令指定。除了listen
指令,还有server_name
指令。
events {
}
http {
server {
listen 80;
server_name zhurs.tech;
return 200 "nginx zhurs.tech!\n";
}
server {
listen 80;
server_name www.zhurs.tech;
return 200 "nginx www.zhurs.tech!\n";
}
}
流程:
- 当客户端向 http://zhurs.tech 发起请求时,那么将会收到来自
nginx zhurs.tech!
的响应; - 当客户端向 http://zhurs.tech 发起请求时,那么将会收到来自
nginx www.zhurs.tech!
的响应;
其实这是虚拟主机概念的一个基本示例,即在同一台服务器中以不同的服务器名称运行两个单独的应用程序。
其中 return
指令负责向用户返回有效响应。该指令有两个参数:状态代码和要返回的字符串消息。
三、NGINX 静态文件处理
以上的简单配置文件还不能提供有效的静态文件处理,需进一步修改配置文件。
3.1 静态文件配置
1、准备好静态文件
mkdir -p /data/nginx/html/test/static-demo
ll /data/nginx/html/test/static-demo
2、配置 nginx 配置文件
配置与上面案例几乎相同,只是将 return
指令替换为 root
指令。该指令用于声明站点根目录,即该目录就是用于存放静态文件的目录。
events {
}
http {
server {
listen 80;
server_name zhurs.tech;
root /usr/share/nginx/html/test/static-demo;
}
}
3、访问验证
CURL:http://139.xxx.xxx.50:81
注:我是 Docker 起的 Nginx
docker run -itd \ --name=nginx \ --privileged=true \ --restart=always \ -p 81:80 \ -v /data/nginx/conf/nginx.conf:/etc/nginx/nginx.conf \ -v /data/nginx/conf/conf.d:/etc/nginx/conf.d \ -v /data/nginx/html:/usr/share/nginx/html \ -v /data/nginx/logs:/var/log/nginx nginx:1.20.2
3.2 静态文件类型处理
尽管 NGINX 已正确提供 index.html 文件,但从三个导航链接的外观来看,CSS 代码似乎无法正常工作。对于这个问题,如果在生产环境中出现,我可先与开发人员确定是否文件有问题,若开发人员确定没问题就是我们 nginx 的配置文件配置有问题。
接下来就是要调试 CSS 文件请求:
curl -I zhurs.tech:81/mini.min.css
HTTP/1.1 200 OK
Server: nginx/1.20.2
Date: Sun, 04 Dec 2022 12:03:27 GMT
Content-Type: text/plain
Content-Length: 46887
Last-Modified: Tue, 16 Nov 2021 06:06:09 GMT
Connection: keep-alive
ETag: "61934a51-b727"
Accept-Ranges: bytes
可看到 Content-Type
类型为 text/plain 而不是 text/css,这意味着 NGINX 将此文件作为纯文本而不是作为样式表。
Nginx 处理请求时,默认找的是 index.html
文件,但在解释文件类型时却不能做到这样的智能。因此我们需要修改配置文件来解决这个问题(配置文件添加文件类型)。
events {
}
http {
types {
text/html html;
text/css css;
}
server {
listen 80;
server_name zhurs.tech;
root /usr/share/nginx/html/test/static-demo;
}
}
该配置文件中 typrs{}
指令块可使 Nginx 解析所有以 text/html
结尾的 html 文件,以及所有以 text/css
结尾的 css 文件。
再次请求 CSS 文件:
curl -I zhurs.tech:81/mini.min.css
此时文件已经被解析为 text/css 文件类型了:
HTTP/1.1 200 OK
Server: nginx/1.20.2
Date: Sun, 04 Dec 2022 12:24:38 GMT
Content-Type: text/css
Content-Length: 46887
Last-Modified: Tue, 16 Nov 2021 06:06:09 GMT
Connection: keep-alive
ETag: "61934a51-b727"
Accept-Ranges: bytes
本地浏览器请求进行验证:可看到 CSS 样式已经改变,比之前美观多了。
在types
上下文中映射文件类型可能适用于小型项目,但对于大型项目而言,它可能很麻烦且容易出错。
NGINX 为这个问题提供了解决方案。在 Nginx 默认安装目录中,你会看到一个名为 mime.types
的文件(默认路径 /etc/nginx/mime.types
)。
来看看这个文件的内容:
types {
text/html html htm shtml;
text/css css;
text/xml xml;
image/gif gif;
image/jpeg jpeg jpg;
application/javascript js;
application/atom+xml atom;
application/rss+xml rss;
text/mathml mml;
text/plain txt;
text/vnd.sun.j2me.app-descriptor jad;
text/vnd.wap.wml wml;
text/x-component htc;
image/png png;
image/svg+xml svg svgz;
image/tiff tif tiff;
image/vnd.wap.wbmp wbmp;
image/webp webp;
image/x-icon ico;
image/x-jng jng;
image/x-ms-bmp bmp;
font/woff woff;
font/woff2 woff2;
application/java-archive jar war ear;
application/json json;
application/mac-binhex40 hqx;
application/msword doc;
application/pdf pdf;
application/postscript ps eps ai;
application/rtf rtf;
application/vnd.apple.mpegurl m3u8;
application/vnd.google-earth.kml+xml kml;
application/vnd.google-earth.kmz kmz;
application/vnd.ms-excel xls;
application/vnd.ms-fontobject eot;
application/vnd.ms-powerpoint ppt;
application/vnd.oasis.opendocument.graphics odg;
application/vnd.oasis.opendocument.presentation odp;
application/vnd.oasis.opendocument.spreadsheet ods;
application/vnd.oasis.opendocument.text odt;</