浅谈Nginx原理及其相关知识点

243 阅读4分钟

前言:

目录:

一、Nginx是什么
二、Nginx的反向代理
三、Nginx的负载均衡
四、Nginx的常用命令
五、一些常见问题

一、Nginx是什么

1.1Nginx是一个高性能的开源Web服务器和反向代理服务器,也可以用作负载均衡器、HTTP缓存服务器和邮件代理服务器。

1.2其采用了事件驱动和异步非阻塞的方式,能高效处理大量并发连接。

1.3其代码量小,内存占用低。能在低配置的硬件上高效运行。

1.4基于稳定的事件驱动架构开发,能够有效避免由于代码错误或者第三方库问题导致的崩溃。高可靠性。

1.5提供了丰富的模块,包括http模块,SSL/TLS加密模块,负载均衡模块等,用户可以根据需求灵活启用或禁用模块。

1.6其配置文件采用类似c语言的语法,灵活。

1.7其支持在不停止服务的情况下重新加载配置文件或者更新软件版本,实现零停机时间部署(热部署)。

1.8其支持在多种操作系统上运行,包括linux和windows

主要功能:

  • http服务器:作为静态和动态网页的http服务器,处理客户端的http请求。

  • 反向代理:将客户端的请求转发到后端的一个或多个服务器上,隐藏后端服务器的真正ip地址,提高安全性。

  • 负载均衡:在多个后端服务器之间分配请求,根据负载均衡算法(轮询、权重等)提高应用的可用性和扩展性。

  • http缓存:缓存静态内容和后端服务器的响应,减少后端服务器的负载,提高响应速度。

  • SSL/TSL终端代理:支持SSL/TLS协议,为客户端提供安全的https访问。

  • 静态内容服务:高效处理静态文件,如图片、视频、css和js文件。

  • 压缩:支持Gzip压缩,减少传数据的大小,加快页面加载速度。

  • 邮件代理:支持SMTP、POP3和IMAP协议,可以作为邮件代理服务器。

二、Nginx的反向代理

无代理:浏览器->服务区

正向代理:浏览器->代理->其他服务器(翻墙)

反向代理:浏览器->nginx->服务器

反向代理详解:当我们访问电商平台时,他们是多服务器的,但服务器之间的session不共享(而现在我们都是单点登录),nginx能够实现登录一次访问所有服务器,这就是反向代理。对外暴露的就是代理服务器地址,隐藏了真实服务器地址。

三、负载均衡

负载均衡的模式:

  1. 轮询(Round Robin) 描述: 默认算法,按顺序将请求分配到每个服务器。

配置示例:

upstream backend {
    server backend1.example.com;
    server backend2.example.com;
}
  1. 加权轮询(Weighted Round Robin) 描述: 在轮询的基础上,为每个服务器分配一个权重,权重越高,分配的请求越多。

配置示例:

upstream backend {
    server backend1.example.com weight=3;
    server backend2.example.com weight=2;
}
  1. IP 哈希(IP Hash) 描述: 根据客户端 IP 地址的哈希值分配请求,确保同一客户端的请求总是分配到同一服务器。

配置示例:

upstream backend {
    ip_hash;
    server backend1.example.com;
    server backend2.example.com;
}
  1. 最少连接(Least Connections) 描述: 将请求分配到当前连接数最少的服务器。

配置示例:

upstream backend {
    least_conn;
    server backend1.example.com;
    server backend2.example.com;
}
  1. 加权最少连接(Weighted Least Connections) 描述: 在最少连接的基础上,考虑服务器的权重。

配置示例:

upstream backend {
    least_conn;
    server backend1.example.com weight=3;
    server backend2.example.com weight=2;
}
  1. 随机(Random) 描述: 随机选择一个服务器处理请求。

配置示例:

upstream backend {
    random;
    server backend1.example.com;
    server backend2.example.com;
}
  1. 加权随机(Weighted Random) 描述: 在随机选择的基础上,考虑服务器的权重。

配置示例:

upstream backend {
    random;
    server backend1.example.com weight=3;
    server backend2.example.com weight=2;
}
  1. 基于响应时间的负载均衡(Least Time) 描述: 将请求分配到响应时间最短的服务器。

配置示例:

upstream backend {
    least_time header;
    server backend1.example.com;
    server backend2.example.com;
}
  1. 基于 URI 的哈希(URI Hash) 描述: 根据请求 URI 的哈希值分配请求,确保同一 URI 的请求总是分配到同一服务器。

配置示例:

upstream backend {
    hash $request_uri consistent;
    server backend1.example.com;
    server backend2.example.com;
}
  1. 基于 Cookie 的负载均衡(Sticky Cookie) 描述: 使用 Cookie 将客户端请求绑定到特定服务器。

配置示例:

upstream backend {
    sticky cookie srv_id expires=1h domain=.example.com path=/;
    server backend1.example.com;
    server backend2.example.com;
}

四、常用命令

./nginx  启动
./nginx -s stop  停止
./nginx -s quit  安全退出
./nginx -s reload  重新加载配置文件  如果我们修改了配置文件,就需要重新加载。
ps aux|grep nginx  查看nginx进程
nginx -t           检查 Nginx 配置文件的语法是否正确
whereis nginx     //寻找nginx
tail -500f /usr/local/nginx/logs/error.log   //nginx的运行时日志

五、一些常见问题

5.1、502 Bad Gateway根因分析

通常表示nginx作为反向代理时未能从后端服务器获得有效响应。

常见原因:

  • 后端服务器宕机或者未启动
  • 后端服务超时
  • 网络连接问题或配置错误(如端口错误、协议不匹配)
  • 后端服务崩溃或者资源不足

以上可以通过日志排查、配置检查超时设置是否过短。

5.2、连接数优化(worker_connections 调优)

首先,其表示每个worker进程可以同时打开的最大连接数,配合worker_processes决定服务器的并发能力

同时,worker_rlimit_nofile:进程打开文件描述符的上限,需保证大于 worker_connections 的总和。

优化:

  • 调整nginx配置,对worker_processes、worker_rlimit_nofile、worker_connections进行设置

  • 计算公式:并发公式=worker_processes*worker_connections

5.3、缓存策略配置误区

首先,nginx可以用来缓存静态资源、反向代理响应等,提高响应速度

误区:

1.缓存配置不当可能导致数据不一致

2.忽略缓存清理策略,造成磁盘空间耗尽

  • 区分静态内容和动态数据,避免对动态接口启用缓存

  • 配置自动清理策略

`max_size=1g` | 限制缓存占用的磁盘空间,达到 1GB 时会自动清理最近最少使用(LRU)的缓存文件。 |

`inactive=60m` | 如果缓存内容在 60 分钟内没有被访问,则自动清理该缓存。注意,这不是缓存的有效期,而是“未使用”时间。 |

`use_temp_path=off` | 禁止使用临时文件夹,缓存文件直接写入 `proxy_cache_path` 指定的目录,避免临时文件占用多余空间,提高性能。 |

5.4、日志

日志类型

  • access.log:记录所有访问请求的信息,包括请求时间、IP、状态码等

  • error.log:记录错误和异常信息,帮助定位问题原因

grep "502" /usr/local/nginx/logs/access.log
5.5、跨域问题

问题:浏览器同源策略,除了前端可以设置路由外,nginx也能配置跨域

location /api/ {
    # 允许所有域名访问(生产环境中建议指定具体域名)
    add_header Access-Control-Allow-Origin *;
    add_header Access-Control-Allow-Methods "GET, POST, OPTIONS, PUT, DELETE";
    add_header Access-Control-Allow-Headers "Authorization,Content-Type";
    
    # 针对 OPTIONS 请求快速返回
    if ($request_method = 'OPTIONS') {
        add_header Access-Control-Max-Age 1728000;
        add_header Content-Type "text/plain charset=UTF-8";
        add_header Content-Length 0;
        return 204;
    }
    
    proxy_pass http://backend_server;
}