Nginx 常见面试题

最近面试被问到了 Nginx ,之前做项目的时候也用到了这个模块,花了点时间整理了一下常见的面试题。

Nginx 是一种高性能的 HTTP 和反向代理服务器,也是一个 IMAP/POP3/SMTP 代理服务器。

Nginx 的使用场景有哪些?

在软件架构中,Nginx 通常被用作负载均衡器和反向代理服务器。

以下是 Nginx 在软件中所处的位置和具体的使用场景:

  1. 作为 Web 服务器:Nginx 可以直接处理 HTTP 请求,返回静态资源(如 HTML、CSS、JavaScript 文件或者图片等)。在这种情况下,Nginx 直接与客户端进行交互,处理并响应客户端的请求。

  2. 作为反向代理服务器:在这种场景下,Nginx 接收到客户端的请求后,会将请求转发到后端的应用服务器(如 Node.js、Python 的 Flask 或 Django、JavaSpring Boot 等)。应用服务器处理完请求后,将响应返回给 Nginx,然后 Nginx 再将响应返回给客户端。这种方式可以隐藏真实的服务器地址,提高安全性,同时也可以利用 Nginx 的高并发特性,提高系统的处理能力。

  3. 作为负载均衡器:当后端有多个应用服务器时,Nginx 可以根据特定的算法(如轮询、最少连接等)将请求分发到不同的服务器,这可以有效地分摊服务器的压力,提高系统的可用性和响应速度。

  4. 作为静态内容缓存:Nginx 可以将后端服务器的响应结果(通常是动态内容)缓存下来,当下次收到相同的请求时,Nginx 可以直接返回缓存的结果,而不需要再次请求后端服务器。这可以大大提高响应速度,减轻后端服务器的压力。

  5. 作为 SSL 终端:Nginx 可以处理 SSL 握手和解密,将解密后的流量发送到后端服务器。这样可以将 CPU 密集的解密操作从后端服务器移除,提高后端服务器的处理能力。

以上就是 Nginx 在软件中所处的位置和具体的使用场景。

Nginx 的发展历史

Nginx 是由 Igor Sysoev 为俄罗斯访问量第二的 Rambler.ru 站点(俄罗斯的雅虎)开发的,第一个公开版本0.1.0发布于2004年10月4日。

2006年,Nginx 为了解决 C10K 问题,即同时连接 10000 个客户端的问题,开始流行起来。Nginx 采用了事件驱动的设计,使其在高并发下依然保持低资源消耗、高性能。

2009年,Nginx 0.7.44 版本开始,加入了负载均衡和反向代理缓存等高级功能,使得 Nginx 逐渐成为一个功能强大的 HTTP 中间件。

2011年,Nginx 1.0.0 版本发布,标志着 Nginx 进入了稳定版本的阶段。

2012年,Nginx 开始提供商业支持,并成立了 Nginx, Inc. 公司。

2013年,Nginx 为了满足企业级用户的需求,推出了 Nginx Plus,这是一个基于 Nginx 的增强版,提供了更多的功能,如高级负载均衡、健康检查、活动监控、高级视频流等。

2015年,Nginx 发布了官方的 Docker 镜像,使得 Nginx 可以更方便地在 Docker 环境中运行。

2019年,Nginx 被 F5 Networks 公司收购,但 Nginx 仍然保持开源,并继续由社区进行开发和维护。

至今,Nginx 已经成为世界上使用最广泛的 Web 服务器之一,被许多大型网站如 Netflix、Pinterest、Instagram 等采用,也是 Docker、Kubernetes 等开源项目的重要组成部分。

Nginx 没有出现之前存在什么问题?

在 Nginx 出现之前,Web 服务器主要使用的是 Apache HTTP Server。Apache 是一款优秀的 Web 服务器,但在处理高并发请求时存在一些问题。这主要是因为 Apache 为每个请求创建一个新的进程或线程,当并发请求量大时,会消耗大量的系统资源,导致服务器负载过高,响应速度下降。

这个问题被称为 C10K 问题,即如何在一台普通的硬件服务器上同时处理上万个网络连接。

Nginx 的出现,解决了这个问题。Nginx 使用了事件驱动的架构,即每个请求不再需要一个独立的进程或线程来处理,而是由少量的工作进程处理所有的网络连接。这种架构使得 Nginx 在处理大量并发连接时,CPU 和内存资源的消耗非常低,从而大大提高了服务器的并发处理能力。

此外,Nginx 还提供了负载均衡、反向代理、静态文件服务、SSL 终端等功能,使其成为了一个功能强大的 Web 服务器和中间件。

Nginx 的优点?

Nginx 主要解决了以下问题:

  1. 并发连接处理:Nginx 使用事件驱动的异步非阻塞模型处理请求,这使得它在处理大量并发连接时非常高效。这对于现代 Web 应用程序来说非常重要,因为它们通常需要同时处理大量的并发连接。

  2. 负载均衡:Nginx 可以作为反向代理服务器,将接收到的请求分发到后端的多个服务器上,从而实现负载均衡。这可以提高应用程序的可用性和性能。

  3. 静态内容的快速服务:Nginx 可以直接从磁盘中提供静态内容,如 HTML、CSS、JavaScript 文件和图片等,而无需通过应用服务器。这可以大大提高静态内容的服务速度。

  4. 安全和访问控制:Nginx 提供了一系列的安全特性,包括 SSL/TLS 支持、访问控制、防止 DDoS 攻击等。

  5. 缓存:Nginx 可以缓存来自后端服务器的响应,从而减少对后端服务器的请求,提高应用程序的性能。

  6. URL 重写和重定向:Nginx 提供了强大的 URL 重写和重定向功能,这对于 SEO 和用户体验来说非常重要。

总的来说,Nginx 是一个功能强大、性能高效的服务器,可以解决现代 Web 应用程序面临的许多挑战。

正向代理和反向代理分别是什么?

正向代理和反向代理都是代理服务器的两种应用方式,它们在网络通信中扮演着不同的角色。下面我将通过具体的例子来解释它们。

正向代理:假设你在印度,你想访问一个在美国的网站,但是这个网站对印度的IP进行了屏蔽,你无法直接访问。这时,你可以设置一个位于美国的代理服务器,你的网络请求首先发送到这个代理服务器,然后由代理服务器转发给目标网站。对于目标网站来说,它看到的请求来源是美国的代理服务器,而不是你的印度IP,因此你就可以成功访问这个网站了。在这个过程中,代理服务器就扮演了正向代理的角色。

客户端(Client) ---> 代理服务器(Proxy Server) ---> 目标服务器(Target Server)

反向代理:假设你有一个网站,这个网站的流量非常大,一个服务器已经无法满足需求。这时,你可以设置一个反向代理服务器,所有的客户端请求都发送到这个反向代理服务器,然后由反向代理服务器根据一定的规则将请求分发到后端的多个服务器。对于客户端来说,它并不知道后端有多个服务器,它看到的只是反向代理服务器。在这个过程中,反向代理服务器就扮演了反向代理的角色。

客户端(Client) ---> 反向代理服务器(Reverse Proxy Server) ---> 目标服务器(Target Server)

总的来说,正向代理隐藏了客户端,而反向代理隐藏了服务器。Nginx就是一个常用的反向代理服务器。例如,你可以配置Nginx将接收到的HTTP请求分发到后端的多个Spring Boot应用服务器,从而实现负载均衡。

Nginx 限流问题

Nginx 限流是一种常见的流量控制技术,主要用于防止服务器过载。以下是一个具体的使用场景:

假设你有一个非常热门的网站,每秒钟有数千个请求。然而,你的服务器只能处理每秒钟1000个请求。如果超过这个数量,服务器可能会过载,导致服务中断。

在这种情况下,你可以使用 Nginx 的限流功能。你可以配置 Nginx,让它每秒钟只处理1000个请求。超过这个数量的请求,Nginx 会自动拒绝,返回一个 “503 Service Unavailable” 错误。

这样,即使有数千个请求,你的服务器也不会过载,因为 Nginx 会确保每秒钟只有1000个请求到达服务器。

Nginx 的限流功能可以通过 limit_req 模块实现。以下是一个简单的配置示例:

http {
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=1000r/s;

server {
location / {
limit_req zone=mylimit burst=2000;
...
}
}
}

在这个配置中,limit_req_zone 指令定义了一个名为 mylimit 的限流区域,限制每秒钟的请求速率为1000个。$binary_remote_addr 是一个变量,表示客户端的 IP 地址。10m 是这个区域的大小,可以存储大约 160,000 个状态。

location 块中,limit_req 指令应用了这个限流区域,并设置了 burst 参数为2000。这意味着,如果瞬间有大量的请求(超过每秒1000个),Nginx 会允许最多2000个请求排队等待处理,超过这个数量的请求会被立即拒绝。

这就是 Nginx 限流的一个具体使用场景和配置示例。通过合理的配置,你可以有效地控制服务器的负载,防止服务器过载。

Nginx 动静分离是什么?

Nginx 的动静分离是一种将动态请求和静态请求分开处理的策略。动态请求通常需要后端应用服务器进行处理,如 PHP、Java 等;静态请求则可以直接由 Nginx 服务器返回给客户端,如 HTML、CSS、JavaScript、图片等。

动静分离的主要优点是可以减轻后端应用服务器的压力,提高网站的响应速度和并发处理能力。

以下是一个 Nginx 动静分离的配置示例:

server {
listen 80;
server_name www.example.com;

location / {
root /var/www/html;
index index.html index.htm;
}

location ~ .(gif|jpg|png|css|js)$ {
root /var/www/static;
expires 30d;
}

location ~ .php$ {
proxy_pass http://backend;
}
}

在这个配置中,我们定义了三个 location 块:

  1. 第一个 location 块用于处理根 URL (“/”) 的请求,Nginx 会在 /var/www/html 目录下查找请求的文件,并返回给客户端。

  2. 第二个 location 块用于处理静态文件的请求,如 gif、jpg、png、css 和 js 文件。Nginx 会在 /var/www/static 目录下查找这些文件,并设置一个 30 天的过期时间(expires 指令)。

  3. 第三个 location 块用于处理 PHP 文件的请求,这些请求会被转发到后端的应用服务器(proxy_pass 指令)。

这只是 Nginx 动静分离的一个基本示例,实际使用中,可能需要根据具体的业务需求和系统负载情况来调整配置。

什么是负载均衡?

负载均衡(Load Balancing)是一种计算机技术,用于在多个计算机、网络链接、CPU、硬盘驱动器或其他资源中分配工作负载,以达到最优化资源使用、最大化吞吐量、最小化响应时间,同时避免过度使用任何一个资源。

在网络环境中,负载均衡通常用于将网络服务请求分发到多个服务器。这样做的目的是为了防止单个服务器的负载过重,同时提高网站或应用的可用性和性能。

负载均衡可以在硬件和软件中实现。硬件负载均衡通常是一个专用的设备,如负载均衡器,它可以根据预定义的规则(如轮询或最少连接)将网络流量分发到多个服务器。软件负载均衡可以在操作系统或应用程序中实现,例如使用Nginx或HAProxy等开源软件。

在云计算环境中,负载均衡也是一种常见的实践,它可以帮助分发到云服务的流量,以确保没有任何单一的资源因为处理过多的请求而变得过载。

Nginx 负载均衡的策略有哪些?

Nginx的负载均衡功能主要通过其内置的HTTP Upstream模块实现。该模块支持多种负载均衡算法,包括:

  1. 轮询(Round Robin):这是默认的负载均衡算法。每个请求按照顺序分配到不同的后端服务器,如果服务器列表的末端,则重新开始。

  2. 最少连接(Least Connections):将新的请求分配给当前活跃连接数最少的服务器。这种策略在处理请求时间差异较大的情况下比较有用。

  3. IP哈希(IP Hash):根据客户端的IP地址进行哈希计算,然后根据哈希值将请求分配给后端服务器。这种策略可以保证来自同一IP地址的客户端总是被分配到同一台服务器,有利于会话保持。

  4. 通用哈希(Generic Hash):基于某个或某些HTTP头,请求参数或者请求URI进行哈希,然后根据哈希值将请求分配给后端服务器。

  5. URL哈希(URL Hash):根据请求的URL进行哈希计算,然后根据哈希值将请求分配给后端服务器。这种策略有利于缓存,因为相同URL的请求总是被分配到同一台服务器。

这些负载均衡策略的实现主要是通过Nginx配置文件中的upstream模块来完成的。例如,以下是一个使用轮询策略的配置示例:

http {
upstream backend {
server backend1.example.com;
server backend2.example.com;
server backend3.example.com;
}

server {
listen 80;

location / {
proxy_pass http://backend;
}
}
}

在这个配置中,upstream模块定义了一个名为backend的服务器组,包含三个后端服务器。然后在server模块中,我们使用proxy_pass指令将所有请求转发到backend服务器组,Nginx会自动使用轮询策略将请求分配给这三个服务器。

如果你想使用其他负载均衡策略,可以在upstream模块中添加相应的指令。例如,以下是一个使用最少连接策略的配置示例:

http {
upstream backend {
least_conn;
server backend1.example.com;
server backend2.example.com;
server backend3.example.com;
}

server {
listen 80;

location / {
proxy_pass http://backend;
}
}
}

在这个配置中,我们添加了least_conn指令,这样Nginx就会使用最少连接策略来分配请求。

在实际项目中,选择哪种负载均衡策略主要取决于具体的业务需求和系统负载情况。例如,如果你的应用需要会话保持(session persistence),那么可能需要使用 IP 哈希或者通用哈希策略。如果你的后端服务器处理能力不均匀,那么可能需要使用最少连接策略。

Nginx 的默认负载均衡策略是轮询(Round Robin)。在这种策略下,Nginx 会将每个新的请求按照顺序分配给后端服务器列表中的服务器,当分配到列表的末尾时,Nginx 会重新开始从列表的开始处分配请求。这种策略简单有效,但在某些情况下可能不是最优的选择,例如,当后端服务器的处理能力不均匀,或者需要处理长连接(long-lived connections)时。

Nginx 多进程模型

Nginx使用一种称为”多进程模型”的架构来处理请求。这种模型的主要优点是其稳定性和可扩展性。在这种模型中,Nginx启动一个主进程和多个工作进程。主进程的主要职责是管理工作进程,而工作进程则负责处理实际的请求。

  主进程 (Master Process)
  │
  ├── 工作进程 1 (Worker Process 1)
  │
  ├── 工作进程 2 (Worker Process 2)
  │
  ├── 工作进程 3 (Worker Process 3)
  │
  └── ...

在这个模型中,主进程(Master Process)负责管理工作进程(Worker Processes)。每个工作进程都是独立的,它们各自处理接收到的请求。

  1. 主进程(Master Process):主进程主要负责读取和验证配置文件,管理工作进程,包括创建、终止和维护工作进程的数量等。

  2. 工作进程(Worker Process):工作进程实际处理请求。每个工作进程都独立地接受新的请求,处理请求并提供响应。Nginx可以配置为启动任意数量的工作进程,通常情况下,工作进程的数量设置为等于服务器的CPU核心数。

这种多进程模型的优点是每个工作进程都是独立的,如果一个工作进程出现问题,其他工作进程可以继续处理请求,不会影响到整个服务的运行。此外,多进程模型也使得Nginx可以充分利用多核CPU的优势,提高处理能力。

需要注意的是,Nginx的工作进程之间是相互独立的,它们不共享内存,也不进行线程间的通信。这意味着每个工作进程都有自己的连接池,缓存等,这也是为什么Nginx的内存占用会随着工作进程数量的增加而增加。

总的来说,Nginx的多进程模型提供了高度的稳定性和可扩展性,使其能够在处理大量并发请求时保持高性能。

为什么 Nginx 不使用多线程?

Nginx选择使用多进程模型而不是多线程模型主要有以下几个原因:

  1. 稳定性:在多进程模型中,每个进程都有自己的内存空间,如果一个进程崩溃,不会影响到其他进程,服务可以继续运行。而在多线程模型中,所有线程共享同一内存空间,一个线程的崩溃可能会导致整个进程崩溃。

  2. 性能:多进程模型可以更好地利用多核CPU。每个进程可以在一个单独的CPU核心上运行,而线程则需要操作系统进行调度,可能会引入额外的开销。

  3. 简单性:多进程模型在设计和实现上相对简单。进程间的隔离性使得开发者不需要处理复杂的线程同步问题,降低了开发和维护的复杂性。

  4. 兼容性:多进程模型在各种操作系统上都有良好的支持,而多线程模型在某些系统上可能会遇到问题。

以上这些原因使得Nginx选择了多进程模型。但这并不意味着多线程模型没有优点,例如,线程间的通信比进程间的通信要快,线程的创建和销毁比进程要快等。实际上,Nginx也支持多线程模式,但默认情况下是关闭的,需要在编译时通过参数开启。

Nginx 高可用性

Nginx的高可用性主要是指其能够在面对各种故障时仍能保持服务的可用性。这主要体现在以下几个方面:

  1. 故障转移(Failover):当某个后端服务器出现故障时,Nginx可以自动将请求转发到其他健康的服务器,从而保证服务的连续性。

  2. 负载均衡(Load Balancing):Nginx可以根据不同的策略(如轮询、最少连接、IP哈希等)将请求分发到多个后端服务器,从而避免单点压力过大导致服务不可用。

  3. 健康检查(Health Check):Nginx可以定期检查后端服务器的健康状态,当检测到服务器故障时,会自动将其从服务列表中移除,防止将请求发送到已经出现故障的服务器。

  4. 热部署(Hot Deployment):Nginx支持在不中断服务的情况下进行软件版本升级或配置更改,这对于需要24/7在线服务的场景非常重要。

具体使用场景举例:

假设你正在运行一个电商网站,该网站的流量非常大,单一的服务器无法承受。此时,你可以使用Nginx作为反向代理和负载均衡器,将用户的请求分发到多个后端服务器。当某个服务器出现故障时,Nginx会自动将流量转移到其他健康的服务器,从而保证用户的访问不会被中断。同时,你还可以在不停止服务的情况下更新网站的代码或者配置,这对于电商网站这种需要24/7在线的服务来说,是非常重要的。

Nginx 压缩

Nginx 压缩是一种通过减小文件大小来提高网络传输效率的技术。Nginx 使用 Gzip 进行压缩,可以显著减小 HTML、CSS、JavaScript 等文本文件的大小,从而减少网络传输的时间,提高网站的加载速度。

以下是一个 Nginx 开启 Gzip 压缩的配置示例:

http {
gzip on;
gzip_min_length 1k;
gzip_comp_level 6;
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
gzip_vary on;
}

在这个配置中:

  • gzip on; 开启 Gzip 压缩。
  • gzip_min_length 1k; 设置最小压缩文件大小,这里设置为1k。小于1k的文件不会被压缩。
  • gzip_comp_level 6; 设置压缩级别,1-9,数字越大压缩的越好,也越占用CPU时间。
  • gzip_types 设置需要压缩的文件类型。
  • gzip_vary on; 让代理服务器根据客户端的 Accept-Encoding 来缓存被压缩过的和未被压缩过的版本。

这只是 Nginx Gzip 压缩的一个基本示例,实际使用中,可能需要根据具体的业务需求和系统负载情况来调整配置。

总结

Nginx是一种高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP代理服务器。它可以作为Web服务器、反向代理服务器、负载均衡器、静态内容缓存和SSL终端。Nginx的出现解决了C10K问题,即如何在一台普通的硬件服务器上同时处理上万个网络连接。Nginx的优点包括并发连接处理、负载均衡、静态内容的快速服务、安全和访问控制、缓存以及URL重写和重定向。Nginx的负载均衡功能主要通过其内置的HTTP Upstream模块实现,支持多种负载均衡算法,包括轮询、最少连接、IP哈希、通用哈希和URL哈希。Nginx压缩是一种通过减小文件大小来提高网络传输效率的技术。Nginx使用Gzip进行压缩,可以显著减小HTML、CSS、JavaScript等文本文件的大小,从而减少网络传输的时间,提高网站的加载速度。


原文始发于微信公众号(everystep):Nginx 常见面试题

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/269631.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!