2022 年学习 Nginx 及其基础知识
几周前,我必须对请求进行复杂的重定向,例如,如果到达的请求nginx
具有特定的查询参数或来自特定的主机,则内部重定向到不同的路径。
我已经完成了我的逻辑,并且确信它能起作用,但正如俗话所说——
除非通过所有边缘情况进行验证,否则您的软件最终将会失败。
但是,由于我们的系统依赖性,我无法将代码合并到暂存开发中进行测试,因为如果发生nginx
故障,它将阻止其他开发人员编写/测试他们的节点 API 或客户端代码。
因此,为了缓解这个问题,我在本地电脑上设置了它nginx
,并进行了彻底的测试。一旦本地测试无误,代码就可以推送到暂存区进行进一步测试。这样,我节省了大量时间,并且不会妨碍其他人的工作。
在本文中,我将介绍基础知识nginx
、安装和本地设置、设置日志以及其他一些内容。
让我们从的定义开始nginx
。
什么是 Nginx?
Nginx
engine x
是is an HTTP
and的缩写reverse proxy server
。它被广泛用作负载均衡器并提供静态文件,有时甚至提供完整的静态网站,例如托管在 Nginx 上的公司博客!
负载均衡器
简单来说,负载均衡器就像是位于相关方之间的中间人,例如假设 A 是客户端列表,B 是服务器列表,那么 -
案例 1:没有负载均衡器
所有传入的请求都会发送到一台服务器,在最坏的情况下,这会导致该服务器挂起或崩溃。你可能听说过这个术语,Node API or Service API is down
指的是处理该 API 请求的服务器或设备由于请求过载或内存不足等原因而挂起或崩溃。从而导致用户体验无响应。
案例 2:使用负载均衡器
所有传入的请求都必须经过负载均衡器。它负责维护路由表,并在任何设备或服务器发生故障时收到通知(通过轮询)。
它能够在服务器之间高效地分配网络请求。如果一台服务器宕机,它会将请求重定向到其他在线的服务器。从而保证服务器始终在线。
Nginx配置文件
该文件是一种tree-like
结构,包含规则/块形式的指令。
# main context (outside any other context i.e global context)
# event context
event {
worker_connections 1024;
}
#http context
http {
# server context
server {
# code goes here
}
server {
# another server context, code goes here
}
}
在我们开始创建自己的 Web 服务器之前,让我们Nginx
先来简单了解一下配置文件的结构 -
主要背景 —
是main context a.k.a. global context
最顶层的上下文,所有其他上下文都是它的一部分,例如Event context, HTTP context
。它用于配置在粒度级别上影响整个应用程序的细节。
事件背景 —
事件上下文包含在 中Main context
。它通常用于处理连接。此上下文中定义的所有指令都用于处理工作进程如何处理传入的连接。
HTTP 上下文 —
这是事件上下文的兄弟Event context
,与事件上下文并排书写,而不是嵌套。如果我们使用 Nginx 作为 Web 服务器或反向代理,此上下文将保存大部分配置。
笔记:-
Event context and HTTP context
配置中只能有一个nginx
。
在本文的后面,我们将看到另外两个上下文——服务器上下文和位置上下文。
如何在 macOS 中安装 Nginx?
如果你没有使用 brew,请先安装它。打开终端并执行以下操作:
安装 brew
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
安装 brew 后,执行
brew install nginx
一旦安装了 nginx,你可以通过以下方式验证
nginx -v
上面应该打印nginx version: nginx/<some version number>
e.g.
nginx version: nginx/1.21.0
一旦安装了 nginx,brew 将在以下位置创建 nginx 文件夹 -
/usr/local/etc/nginx
默认nginx.conf
设置如下:
events {
worker_connections 1024;
}
http {
server {
listen 8080;
server_name localhost;
location / {
root html;
index index.html index.htm;
}
}
}
要开始nginx services
执行以下操作 -
nginx
如果有任何错误,它将记录在终端中,要测试它是否提供默认的 HTML 文件,请点击 URL -
http://localhost:8080
并阻止它——
nginx -s stop
如何从不同位置提供文件?
让我们修改nginx.conf
文件以从其他位置读取 HTML 文件 -
index.html
首先,创建一个包含您想要提供的HTML 文件(包含以下内容)的文件夹,例如我nginx-poc
在下载文件夹中创建的文件夹。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>This is index html file from nginx-poc folder</h1>
</body>
</html>
复制此文件夹的完整路径,然后root
打开nginx.conf
以进行更新
使用 vim 编辑器或 nano 或您喜欢的任何其他方式打开文件(例如 nano)—
nano /usr/local/etc/nginx/nginx.conf
并更新根位置
events {
worker_connections 1024;
}
http {
server {
listen 8080;
server_name localhost;
location / {
root /Users/Download/nginx-poc;
index index.html index.htm;
}
}
}
现在停止nginx
并重新启动以查看更新的更改。访问 localhost URL 并使用端口8080
-
如何进行 URL 重定向?
有时,当现有资源移动到其他位置时,可能需要进行 URL 重定向。让我们看看如何实现这一点——
在 nginx-poc 文件夹中创建一个js
文件夹并在其中创建一些 js 文件 —
|-- nginx-poc
| |-- index.html
| |-- js
| | |-- a.js
| | |-- b.js
| | |-- c.js
| | |-- b-latest.js
console.log(<filename>)
每个 js 文件中只有一个简单的-
例如 a.js
console.log('serving a.js');
对于 b-latest.js
console.log('serving b-latest.js');
等等。
假设该文件b.js
不再有用,我们想用 来代替b-latest.js
它。当然,我们可以将锚链接指向的所有内容b.js
替换为b-latest.js
,但这有两个问题:
- 它很耗时,而且容易出错。
- 旧 URL 会导致 404 错误,我们应该努力减少这种情况。理想情况下,不应该有任何 404 重定向,应该尽可能减少。
nginx
一个简单的解决方案是通过内部重定向来实现-
events {
worker_connections 1024;
}
http {
server {
listen 8080;
server_name localhost;
root /Users/Download/nginx-poc;
location /js {
rewrite /js/b.js /js/b-latest.js break;
}
location / {
# root /Users/Download/nginx-poc;
index index.html index.htm;
}
}
}
让我逐一介绍一下每个变化,以便更清楚地了解——
-
位置 / 中注释掉的根目录 —这会移至服务器上下文。将根目录添加到服务器上下文后,该目录将适用于其中的所有位置上下文。
-
添加了位置上下文来处理 /js 请求——此请求将处理来自 的所有请求,
/js, /js/*
即 的请求/js/b.js
将落在此位置。我们正在内部重写请求 URL,从/js/b.js
到/js/b-latest.js
,然后我们添加了一个,break
这意味着不再需要解析任何其他重写!
笔记:-
-
是
server context
的子级HTTP context
。可以有多个服务器上下文,这与事件和 HTTP 上下文不同,后者只允许一次。 -
是
location context
的子级server context
。与服务器上下文类似,允许多个位置上下文。它们是实际处理传入请求的地方。
如何添加自定义日志?
日志非常重要,它们对于测试我们的逻辑至关重要。如果生产代码出现任何问题,我们可以通过查看日志轻松调试nginx logs
。让我向您展示如何在本地进行设置,以便我们可以在本地测试并查看完整的逻辑以及日志。
默认情况下,nginx
有两种类型的日志——access log and error log
访问日志 —
这会记录访问者的活动,例如请求的 URL、IP 地址、主机、引荐来源等。如果请求成功处理,它将记录在 access.log 文件中。
access_log <location of log file> log_format;
在中log_format
,我们可以添加我们想要记录的数据,但只是一个注释,这是一个可选的事情。
要记住的一点是 log_format 必须放在下面,HTTP context
否则会引发错误。
例如
Syntax -
log_format <log_format_name> string;
log_format custom '$remote_addr - $remote_user [$time_local] '
'"$request" "$uri" $status $body_bytes_sent ''"$http_referer" "$http_user_agent" "$gzip_ratio"';
错误日志 —
这会记录每个故障和系统日志,即如果请求未以任何方式得到满足,它将被记录在error.log
文件中。
Syntax -
error_log <location of error.log file> <error-severity-level>
error_log /usr/local/etc/nginx/logs/error.log notice;
添加日志后的配置文件——
events {
worker_connections 1024;
}
http {
log_format custom '$remote_addr - $remote_user [$time_local] '
'"$request" "$uri" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" "$gzip_ratio"';
server {
listen 80;
server_name localhost;
root /Users/Downloads/nginx-poc;
access_log /usr/local/etc/nginx/logs/acess.log custom;
error_log /usr/local/etc/nginx/logs/error.log notice;
rewrite_log on;
location /js {
rewrite /js/b.js /js/b-latest.js break;
}
location / {
index index.html index.htm;
}
}
}
应该rewrite_log
启用才能记录内部重定向。此外,严重级别意味着这只是一个通知,可以忽略,即没有什么严重问题。notice
如何处理查询参数?
有时我们可能会想根据查询参数内部重定向请求。让我们看看如何在nginx.conf
文件中实现以下 3 种情况——
events {
worker_connections 1024;
}
http {
log_format custom '$remote_addr - $remote_user [$time_local] '
'"$request" "$uri" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" "$gzip_ratio"';
server {
listen 80;
server_name localhost;
root /Users/Downloads/nginx-poc;
access_log /usr/local/etc/nginx/logs/acess.log custom;
error_log /usr/local/etc/nginx/logs/error.log notice;
rewrite_log on;
location /js {
if ($query_string ~* "latest=true") {
rewrite /js/b.js /js/b-latest.js break;
}
if ($query_string ~* "latest=false") {
rewrite /js/b.js /js/c.js break;
}
rewrite /js/b.js /js/a.js break;
}
location / {
index index.html index.htm;
}
}
}
案例 1 —
请求用于b.js
→ 服务b-latest.js
当且仅当查询参数有latest=true
案例 2 —
请求用于b.js
→ 服务c.js
当且仅当查询参数有latest=false
案例 3 —
请求是针对b.js
→服务a.js
默认
结论
Nginx 的功能远不止于此,一篇文章也无法涵盖。但我希望本文能帮助您了解更多。有了本地设置,当您想在nginx
本地测试逻辑并将其部署到暂存区或生产环境之前,它会变得非常方便。
我真心希望你喜欢这篇文章,如果喜欢,请关注我,如果可以的话,请我喝杯咖啡。本文最初发布在我的网站上,欢迎持续访问以获取定期更新。
谢谢!敬请期待更多文章。
文章来源:https://dev.to/ajayv1/learn-nginx-and-its-basics-in-2022-4ddb