不敢相信,Nginx 还能这么玩?

大家好,我是程序员鱼皮。今天来聊聊 Nginx 技术,这是一个企业项目必用,但是却经常被程序员忽略的技术。学好 Nginx,可以助你在求职中脱颖而出。

或许你会想:“Nginx 不就是用来部署网站的服务器嘛?这有何难?”

但其实这不过是九牛一毛罢了,Nginx 的实用操作和使用技巧还多着呢,下面这篇文章,就带大家轻松入门 Nginx、并且循序渐进地学习 Nginx 真正的用法!

推荐观看本文对应的视频版本,有更多操作演示哦:https://bilibili.com/video/BV1TW1LYkE59

 

一、Nginx 入门 - 牛刀小试

首先要了解什么是 Nginx?注意读音,是 Engine X,而不是恩静因克斯。

根据官方定义,它是世界上最受欢迎的 Web 服务器、高性能负载均衡器、反向代理、API 网关和内容缓存。

虽然听不懂,但是感觉很厉害的样子。

不敢相信,Nginx 还能这么玩?

简单来说,Nginx 不仅能部署网站,而且相比其他的 Web 服务器,它能够用更少的资源,同时处理更多用户的请求,让网站速度更快更稳定,这也是企业选择 Nginx 的原因。

下面我们就牛刀小试,用 Nginx 启动一个网站!

 

1、Nginx 安装

首先我们需要安装 Nginx ,先到官网中根据操作系统下载一个稳定版本的压缩包,下载完成之后解压一下。

不敢相信,Nginx 还能这么玩?

如果是 Windows 系统,双击 exe 文件启动即可;如果是 Mac 或 Linux 系统,可以打开终端并进入该目录,手动编译安装后执行 Nginx 命令启动。

不敢相信,Nginx 还能这么玩?

当然也可以使用第三方的包管理工具,比如 Chocolatey(Windows)、Homebrew(Mac)、Yum(Linux)。

或者使用现成的服务器运维面板,比如宝塔 Linux,可以傻瓜式一键安装:

不敢相信,Nginx 还能这么玩?

 

2、修改网页文件

启动成功后,我们访问本机域名 localhost:80 (80 为默认端口,可以省略),就可以看到 Nginx 为我们提供的默认网站了。

不敢相信,Nginx 还能这么玩?

那如果想自己修改网页内容,怎么办呢?

我们要找到 Nginx 的大脑,也就是配置文件。进入配置目录 conf ,就可以看到配置文件 nginx.conf 了。配置文件由块和指令组成,可以通过修改配置实现各种功能,比如通过 location 块和 root 指令配置网站文件的根路径:

不敢相信,Nginx 还能这么玩?

我们找到这个 index.html 文件,修改网页的内容并保存:

不敢相信,Nginx 还能这么玩?

重新访问就可以看到效果啦!

不敢相信,Nginx 还能这么玩?

看到这里,恭喜你,已经超过 30% 的程序员了!

 

二、Nginx 常用操作 - 明劲

下面,我们要成为 Nginx 明劲武者。所谓明劲,就是要熟悉 Nginx 的基本配置和常用操作,能够满足企业开发中的大多数需求,如果你的目标是开发岗,那么学完下面这些就足够找工作了。

1、静态文件服务

我们开发好的网站,通常包含像 HTML、CSS、JavaScript、图片等文件,由于这些文件的内容在存储时是固定的,被称为静态文件。

如果你要让别人访问到开发好的网站,只把网站文件放到服务器上还是不够的,还需要一个 Web 服务器,能够接受用户的访问请求,并找到对应位置的文件进行响应。

Nginx 最基本的功能,就是作为 Web 服务器提供静态文件服务。

打开 Nginx 的配置文件 nginx.conf ,添加 location 块,用于根据请求地址处理请求。比如我们通过 root 指令定义静态文件根目录,通过 index 指令定义默认首页文件:

server {
 listen       80;
 server_name localhost;

 location / {
   root /tmp/nginx/html;  # 指定静态文件根目录
   index index.html;  # 默认首页
}
}

保存配置,然后执行 nginx -s reload 命令来重载配置,再次访问网站时就会返回刚配置的目录下的首页文件。

不敢相信,Nginx 还能这么玩?

企业项目中,需要为特定路径定义不同的处理规则,location 块的配置会更复杂。支持根据请求路径的特定部分、正则表达式等进行匹配,比如到特定目录去寻找图片:

server {
 listen 80;                          # 监听 80 端口
 server_name example.com;            # 指定域名

 # 根路径的配置,返回静态文件
 location / {
   root /var/www/html;             # 指向静态文件的根目录
   index index.html;               # 默认首页文件
   try_files $uri $uri/ =404;     # 如果文件不存在,则返回 404
}

 # 处理以 /images/ 开头的请求
 location /images/ {
   root /var/www/assets/images/;  # 指向图片目录
}

 # 正则匹配,处理以 .php 结尾的请求
 location .php$ {
   include fastcgi_params;          # 包含 FastCGI 参数
   fastcgi_pass 127.0.0.1:9000;    # 将请求转发到 FastCGI 处理程序
   fastcgi_index index.php;         # 设置 FastCGI 的默认索引文件
   fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;  # 定义脚本文件名
}
}

 

2、反向代理

Nginx 的另一个常用功能是用作反向代理服务器。什么是反向代理呢?一句话:Nginx 作为中介,帮后端服务器接受请求。

不敢相信,Nginx 还能这么玩?

反向代理有什么作用呢?

首先是请求转发和解决跨域。比如在 location 块中添加 proxy_pass 配置,可以将 Nginx 在 80 端口收到的 /api 路径的请求转发到本地 8080 端口的后端服务。

server {
   listen 80;  # 监听 80 端口
   server_name localhost;  # 替换为你的域名或 IP 地址

   location /api {
       proxy_pass http://localhost:8080;  # 代理到本地的 8080 端口
  }
}

这样就隐藏了后端服务器的 IP 地址,让客户端完全感知不到后端服务器的存在,更加安全。

不敢相信,Nginx 还能这么玩?

而且还能让前端和后端的域名统一,解决了跨域问题。

不敢相信,Nginx 还能这么玩?

反向代理还可以用于实现负载均衡。由于企业项目的流量巨大,通常需要有多台后端服务器。Nginx 可以作为高性能网关,统一接收请求,并将请求按照特定规则转发到不同的后端服务器进行处理,从而分散了请求压力,避免单一服务器过载。

不敢相信,Nginx 还能这么玩?

在 Nginx 中实现负载均衡非常简单,首先通过 upstream 块定义了一个名为 backend 的服务器组,其中包含两个后端服务器,然后通过反向代理配置将请求转发到这个服务器组即可:

upstream backend {
 server localhost:8080;  # 第一个后端服务器
 server localhost:8081;  # 第二个后端服务器
}

server {
 listen 80;
 server_name localhost;

 location /api {
   proxy_pass http://backend;  # 代理到负载均衡的后端服务器
}
}

这样每次都访问同一个地址,会交替返回两种不同的内容,这是因为 Nginx 的默认负载均衡算法是轮询,请求会被平均转发到两个不同的服务进行处理。

反向代理还有更多的作用,比如缓存常见请求的响应、减少后端负担,集中处理 SSL 加密、认证和日志记录等功能,后面会依次讲解。

 

3、改写请求和响应

第三个 Nginx 的常用功能是改写请求和响应。在请求到达服务器或响应返回给客户端之前,Nginx 可以对其进行修改。

改写请求与响应有什么作用呢?有几个比较典型的场景:

1)控制浏览器缓存

首先,设置响应头 可以帮助我们控制浏览器缓存。通过 Nginx 的 add_header 指令,可以为响应添加自定义的 HTTP 头部,从而指导浏览器如何处理缓存。比如设置缓存有效期为 30 天:

location /images/ {
   root /tmp/nginx/html;
   expires 30d;  # 设置缓存有效期为 30 天
   add_header Cache-Control "public";  # 设置缓存头
}

这样,当用户访问图片时,浏览器会在本地缓存这些图片,下次访问时就不用访问服务器了,提高速度并减少对服务器的请求。

不敢相信,Nginx 还能这么玩?

 

2)重定向

请求重定向允许我们将请求从一个地址自动引导到另一个地址,常见的应用场景包括将 HTTP 请求重定向到 HTTPS,或者将旧地址重定向到新地址。

在 Nginx 中,可以使用 return 指令 + 302 状态码配置重定向:

location /old-page {
   return 302 https://codefather.cn  # 重定向到新页面
}

当用户访问某个过期页面时,会被重定向自动跳转到新网站。

 

3)URI 重写

比重定向更高级一些,Nginx 提供了 rewrite 指令,支持正则表达式,可以非常灵活地将请求重写为不同的路径或网站。比如将 /api/v1/users 的请求重写为 /api/users

location /api/v1/ {
   rewrite ^/api/v1/(.*)$ /api/$1 break;  # 将 /api/v1/ 的请求重写为 /api/
}

这样一来,后端就不用再关注 /api/v1/ 的存在了,这种方法在网站迁移或者结构调整时非常有用。大家也不用去记忆改写的具体语法,随用随查就行。

 


 

看到这里,恭喜你,超过 60% 的程序员了。

 

三、Nginx 高级操作 - 暗劲

下面,我们要成为 Nginx 的暗劲高手。所谓暗劲,又分为 2 种境界。

  • 熟悉 Nginx 的各种特性和高级配置,能更快速地配置和管理 Nginx,为小圆满

  • 熟悉 Nginx 工具和模块生态,能够灵活运用 Nginx 进行架构设计、并巧妙地解决各种需求,为大圆满。

暗劲境界的高手,挑战大厂开发、架构师、高级系统管理员岗位,不成问题。

 

1、Nginx 高级配置

我们先挑战小圆满,Nginx 的配置项实在是太多了,这里我就挑选几个相对实用的来讲解。

1)日志记录

为了分析网站流量、用户行为和报错信息,我们可以开启 Nginx 日志功能。分为访问日志和错误日志。

访问日志会记录所有请求的信息,更全面,可以通过修改 access_log 指令调整日志存储路径:

http {
 log_format custom_format 'yupi $remote_addr - $remote_user [$time_local] "$request" '
                         '$status $body_bytes_sent "$http_referer" '
                         '"$http_user_agent" "$http_x_forwarded_for"';
 
 access_log /rap/access.log custom_format;  # 配置访问日志

 server {
   listen       80;
   server_name localhost;
 
   location / {
     root /tmp/nginx/html;  # 指定静态文件根目录
     index index.html;  # 默认首页
  }
}
}

而错误日志仅记录 Nginx 在处理请求时遇到的问题,错误又分为 8 个级别:

不敢相信,Nginx 还能这么玩?

可以为不同的级别指定不同的日志输出路径:

access_log /rap/access.log custom_format;  # 配置访问日志
error_log /rap/error.log error;  # 配置错误日志

开启日志功能后,就能直接在文件中查看日志了。

不敢相信,Nginx 还能这么玩?

 

2)访问控制

如果有恶意用户攻击我们的网站,怎么办?

莫慌,Nginx 提供了访问控制功能,可以使用 allowdeny 指令对 IP 访问进行限制,比如不让 127.0.0.1 这个 IP 访问:

server {
   listen 80;
   server_name localhost;

   location / {
       # 拒绝特定 IP 地址
       deny 127.0.0.1;
       # 除了写具体 ip 外,也可以写网段
       deny 192.168.1.0/24;
       # 允许所有其他 IP 地址
       allow all;
       proxy_pass http://localhost:8081;
   
  }
}

这样一来,攻击者就访问不了网站了!

不敢相信,Nginx 还能这么玩?

 

3)限流

为了保护网站,我们还可以使用 Nginx 的限流功能。比如下面这段配置,通过定义请求限流区域并应用于根路径,限制每个 IP 地址在一分钟内最多只能发送 2 个请求。

# 定义限流区域,使用客户端的二进制 IP 地址作为唯一标识
# zone=one:10m 表示创建一个名为 "one" 的内存区域,大小为 10MB
# rate=2r/m 表示每个 IP 地址每分钟最多允许 2 个请求
limit_req_zone $binary_remote_addr zone=one:10m rate=2r/m;

server {
 listen 80;  # 监听 80 端口,接收 HTTP 请求
 server_name localhost;  # 设置服务器名称为 localhost

 location / {  # 配置根路径的请求处理
   # 应用限流配置,使用之前定义的 "one" 区域
   # burst=10 表示可以允许最多 10 个额外请求超出正常限速
   # nodelay 表示在突发请求情况下,这 10 个请求将立即被处理,不会被延迟
   limit_req zone=one burst=10 nodelay;

   # 将请求转发到本地的 8080 端口
   proxy_pass http://localhost:8080;  # 反向代理请求到后端服务
}
}

这样后端服务就不被流量激增影响,能够提高系统的稳定性。

不敢相信,Nginx 还能这么玩?

4)虚拟主机

在企业开发中,我们为了节省成本,经常会在同一台服务器上部署多个网站项目,这时就需要使用 Nginx 的虚拟主机功能了。

每个网站通常就是一个虚拟主机,会有一个 server_name 名称对应访问网站的域名,比如我这里配置 2 台虚拟主机:

# 虚拟主机1
server {
   listen 80;                           # 监听 80 端口
   server_name localhost;               # 配置域名为 example.com

   root /tmp/nginx/html;            # 网站根目录
   index localhost.html;                # 默认首页
}

# 虚拟主机2
server {
   listen 80;                           # 监听 80 端口
   server_name 127.0.0.1;               # 配置域名为 another.com

   root /tmp/nginx/html;            # 网站根目录
   index 127.html;                      # 默认首页
}

配置虚拟主机后,Nginx 就能够根据请求的域名找到对应的网站配置,并处理请求。

不敢相信,Nginx 还能这么玩?

 

5)其他

除了上面这些,还有很多企业开发中可能会用到的 Nginx 高级配置和技巧。

比如可以:

  • 通过后端响应缓存配置,让 Nginx 直接从缓存中读取数据来响应请求,这样能够显著提升性能、减少服务器压力。

  • 通过正向代理的设置,Nginx 可以作为 “跳板机”,帮客户端发起请求,从而访问原本无法直接访问的资源。

  • 通过自定义错误页面,能够给用户提供更友好的错误提示信息。

此外,Nginx 支持 WebSocket、HTTPS 和 HTTP/2 等多种协议,还可以配置 Gzip 压缩来减少传输的数据量,进一步优化性能。

最后,Nginx 自身也支持一系列性能调优的配置,比如工作进程与连接数配置,可以从容应对高并发和大流量场景。

worker_processes auto; # 自动检测 CPU 核心数,设置工作进程数

events {
   worker_connections 2048; # 每个工作进程的最大连接数
}

 

2、Nginx 工具和模块生态

想成为 Nginx 大圆满高手,就要懂得利用工具和生态,比如可视化工具、模块和开源项目。

首先,Nginx 的配置和运维对初学者来说可能比较复杂,这时可以利用 Nginx 官方推出的 Nginx Amplify、轻量级的 Nginx-UI 或者宝塔 Linux 服务器管理面板等可视化工具,通过图形界面来更直观地查看配置、分析流量和性能指标,从而提高操作和运维效率。

不敢相信,Nginx 还能这么玩?

其次,Nginx 的功能并不是一成不变的,我们可以通过各种各样的模块来扩展它的能力,比如我们常用于健康检查的 nginx_upstream_check_module 模块、实现 JavaScript 语言扩展的 njs 模块。

但手动安装模块的过程是比较繁琐的,需要下载源码并进行编译。

这种情况下,我们就可以选择 OpenResty 这样一个基于 Nginx 的高性能 Web 平台,它集成了大量模块、依赖项和 Lua 脚本库,能够让你直接在 Nginx 里开发复杂的业务逻辑,充分利用 Nginx 的非阻塞 I/O 模型来提升应用的性能,适合超高并发的场景。

比如下图是网上的一个基于 OpenResty 实现的灰度发布架构:

不敢相信,Nginx 还能这么玩?

 

四、Nginx 原理 - 化劲

想要突破为化劲强者,你需要去理解 Nginx 的核心原理,甚至是去钻研那晦涩难懂的 C 语言源码。

当然,为了应对面试,现在很多程序员迫不得已朝着化劲强者进发。

原理的学习就不是几分钟的视频能搞定的了,但是我可以帮大家划划重点。

  • 负载均衡机制

  • 事件驱动模型

  • 请求处理流程

  • 多进程架构

  • 进程间通信机制

  • 限流机制

  • 缓存机制

  • 压缩机制

  • 资源复用

能搞懂这些,并且融会贯通,你就能够更自如地优化 Nginx 的性能和可用性等等,也就超过 99% 的程序员了。

当然,编程是学不完的,真正的 Nginx 绝世高手,可以给 Nginx 贡献代码,甚至是自立门户、手写 Nginx 的竞品。

我相信看到这里的小伙伴中肯定会出现绝世高手~

 

结尾

最后,我把这份 Nginx 学习路线文字版、以及常问的面试题都放到了自己的小博客,还有更多学习路线也可免费获取。

不敢相信,Nginx 还能这么玩?

希望对大家有帮助,学会的话也还请给本文一个点赞支持哦~

 

更多编程学习资源

发表评论

相关文章