Nginx是什么?
Nginx是一个高性能的 HTTP 和反向代理 web 服务器。同时也提供了IMAP/POP3/SMTP服务。Nginx是由伊戈尔·赛索耶夫为俄罗斯访问量第二的Rambler.ru站点(俄文:Рамблер)开发的,第一个公开版本0.1.0发布于2004年10月4日。其将源代码以类BSD许可证的形式发布,因它的稳定性、丰富的功能集、简单的配置文件和低系统资源的消耗而闻名。2011年6月1日,nginx 1.0.4发布。
其特点是: 占有内存少,并发能力强 ,事实上nginx的并发能力在同类型的网页服务器中表现较好,使用nginx网站有:百度、京东、新浪、网易、腾讯、淘宝等。
Nginx 是高性能的 HTTP 和反向代理的web服务器,处理高并发能力是十分强大的,能经受高负 载的考验,有报告表明能支持高达 50,000 个并发连接数。
Nginx支持 热部署 ,启动简单,可以做到 7*24 不间断运行。几个月都不需要重新启动。
Nginx的作用?
反向代理
正向代理
正向代理是一种介于客户端与目标服务器之间的代理服务器。为了从目标服务器获取内容,客户端先将请求发送给代理服务器并指定目标服务器,然后代理服务器再将请求转发给目标服务器。服务器将响应返回给代理服务器,再由代理服务器将请求返回给客户端。
一个典型的正向代理的应用场景就是,我们通过 VPN 访问外网。
我们想要访问某国外网站如谷歌,但是无法在国内直接访问,我们可以访问到一个位于香港的代理服务器,这个代理服务器可以访问到这个国外网站。这样呢,我们对该谷歌的访问就需要通过代理服务器来转发请求,并且该代理服务器也会将请求的响应再返回给用户。这个上网的过程就是用到了正向代理。
正向代理,代理的是"客户端",去和"目标服务器"进行交互。 就好比一个房产中介。由这个中介代表我们去和房东交涉。我们直接从中介获取想要的信息。
正向代理的特点:
- 隐藏客户端身份: 正向代理可以隐藏客户端的真实IP地址,保护客户端的隐私。
- 访问控制: 正向代理可以根据一定的规则限制或允许客户端的访问请求,实现访问控制功能。
- 缓存加速: 正向代理可以缓存经常访问的页面或资源,提高访问速度,减轻服务器负担。
反向代理
反向代理(reverse proxy):指的是以 代理服务器 来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从内部服务器上得到的结果返回给internet上请求连接的客户端,此时代理服务器对外就表现为一个反向代理服务器。
就好比我们现在在各大租房平台租房子,我们以为是直接和房东交流,其实是一堆中介二房东,并非房东本人。在这个过程中,平台及中介二房东这些就是一个反向代理服务器,他们掌握了租房资源。我们在平台上聊半天,其实是将所有请求发给了这个二房东代理服务器,由他们将符合我们要求的房源推荐给我们。
所以,反向代理,其实是"代理服务器"代理了"目标服务器",去和"客户端"进行交互。 通过反向代理服务器访问目标服务器时,客户端是不知道真正的目标服务器是谁的,甚至不知道自己访问的是一个代理。
反向代理的特点:
- 负载均衡: 反向代理可以根据后端服务器的负载情况,将请求分发到不同的服务器上,实现负载均衡,提高系统的整体性能。
- 安全性增强: 反向代理可以隐藏后端服务器的真实地址和端口,防止直接攻击(如DoS/DDoS)。同时,还可以实现SSL加密、访问控制等安全功能。
- 缓存优化: 反向代理可以缓存静态资源,减少后端服务器的负载,提高响应速度。
二者的区别
虽然正向代理服务器和反向代理服务器所处的位置都是客户端和真实服务器之间,所做的事情也都是把客户端的请求转发给服务器,再把服务器的响应转发给客户端,但是二者之间还是有一定的差异的。
1、正向代理其实是客户端的代理,帮助客户端访问其无法访问的服务器资源。反向代理则是服务器的代理,帮助服务器做负载均衡,安全防护等。
2、正向代理一般是客户端架设的,比如在自己的机器上安装一个代理软件。而反向代理一般是服务器架设的,比如在自己的机器集群中部署一个反向代理服务器。
3、正向代理中,服务器不知道真正的客户端到底是谁,以为访问自己的就是真实的客户端。而在反向代理中,客户端不知道真正的服务器是谁,以为自己访问的就是真实的服务器。
4、正向代理和反向代理的作用和目的不同。正向代理主要是用来解决访问限制问题。而反向代理则是提供负载均衡、安全防护等作用。二者均能提高访问速度。
负载均衡
nginx 提供的负载均衡策略分为两种,一种是内置策略,一种是扩展策略。内置策略有: 轮询,加权轮询,IP hash
轮询
加权轮询
IP hash
对客户端请求的ip进行 hash 操作,然后根据 hash 结果将同一客户端 IP 的请求发给同一服务器处理。
动静分离
在 web 开发中,有些东西需要后端处理,而有些东西不需要经过后台处理(如一些静态资源)。这些就是静态资源,我们按照一定的规则,把经常变化的和不变的资源区分开来。动静资源做好拆分后,我们可以根据静态资源的特点将其进行缓存,进而提高资源的响应速度。
nginx安装——macos
依赖安装:
brew install pcre
brew install zlib
brew install openssl
nginx下载安装
下载nginx
安装
解压 tar -zxvf nginx-1.26.2.tar.gz
编译:sudo ./configure,
安装:sudo make && make install
make install 报错:
sudo mkdir -p /usr/local/nginx
sudo chmod -R 777 /usr/local/nginx
sudo make && make install
启动:
cd /usr/local/nginx/sbin
./nginx
长久启动:
vi /etc/profile
export NGINX_HOME=/usr/local/nginx
export PATH=PATH:NGINX_HOME/sbin
source /etc/profile
配置后启动:
nginx
nginx常用命令
#启动
#1.直接启动
#进入nginx目录,执行启动命令
cd /usr/local/nginx/sbin
./nginx
# 或者直接
/usr/local/nginx/sbin/nginx
#2.指定配置文件方式启动
#进入nginx目录,执行启动命令
cd /usr/local/nginx/sbin
./nginx -c /usr/local/nginx/conf/nginx.conf
#或者
/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
# 检查 nginx 配置
#进入nginx目录
cd /usr/local/nginx/sbin
#检查配置文件是否有语法操作
./nginx -t
# 或者显示指定配置文件
./nginx -t -c /usr/local/nginx/conf/nginx.conf
#修改配置后重新加载
#进入nginx目录
cd /usr/local/nginx/sbin
#执行重载命令
./nginx -s reload
#关闭nginx
#进入nginx目录
cd /usr/local/nginx/sbin
# 快速停止nginx
./nginx -s stop
# 完整有序的停止nginx,这个命令会等待所有请求结束后再关闭nginx
./nginx -s quit
# 其他命令
# 查看进程号,下图 master的为主进程号
ps -ef | grep nginx
#从容停止Nginx
kill -QUIT 主进程号
#快速停止Nginx
kill -TERM 主进程号
#强制停止Nginx
pkill -9 nginx
#平滑重启nginx:
kill -HUP 主进程号
补充说明:
nginx工作中,包括一个master进程,多个worker进程。worker进程负责具体的http等相关工作,master进程主要是进行控制。 nginx -s reload 命令加载修改后的配置文件,命令下达后发生如下事件:
- Nginx的master进程检查配置文件的正确性,若是错误则返回错误信息,nginx继续采用原配置文件进行工作(因为worker未受到影响)
- Nginx启动新的worker进程,采用新的配置文件
- Nginx将新的请求分配新的worker进程
- Nginx等待以前的worker进程的全部请求已经都返回后,关闭相关worker进程
- 重复上面过程,直到全部旧的worker进程都被关闭掉。 所以,重启之后,master的进程号不变,worker的进程号会改变。
nginx配置
nginx默认配置文件:
/usr/local/nginx/conf/nginx.conf
默认配置文件配置如下( 去掉注释后 ):
#nginx进程数,建议设置为等于CPU总核心数。
worker_processes 1;
# 事件区块开始
events {
#单个进程最大连接数(最大连接数=连接数*进程数)
#根据硬件调整,和前面工作进程配合起来用,尽量大,但是别把cpu跑到100%就行。每个进程允许的最多连接数,理论上每台nginx服务器的最大连接数为。
worker_connections 1024;
}
#设定http服务器,利用它的反向代理功能提供负载均衡支持
http {
#include:导入外部文件mime.types,将所有types提取为文件,然后导入到nginx配置文件中
include mime.types;
#默认文件类型
default_type application/octet-stream;
#开启高效文件传输模式,sendfile指令指定nginx是否调用sendfile函数来输出文件,对于普通应用设为 on,如果用来进行下载等应用磁盘IO重负载应用,可设置为off,以平衡磁盘与网络I/O处理速度,降低系统的负载。注意:如果图片显示不正常把这个改成off。
#sendfile指令指定 nginx 是否调用sendfile 函数(zero copy 方式)来输出文件,对于普通应用,必须设为on。如果用来进行下载等应用磁盘IO重负载应用,可设置为off,以平衡磁盘与网络IO处理速度,降低系统uptime。
sendfile on;
#长连接超时时间,单位是秒
keepalive_timeout 65;
# 第一个Server区块开始,表示一个独立的虚拟主机站点
server {
# 提供服务的端口,默认80
listen 80;
# 提供服务的域名主机名
server_name localhost;
#对 "/" 启用反向代理,第一个location区块开始
location / {
root html; #服务默认启动目录
index index.html index.htm; # 默认的首页文件,多个用空格分开
}
# 错误页面路由
error_page 500 502 503 504 /50x.html; # 出现对应的http状态码时,使用50x.html回应客户
location = /50x.html { # location区块开始,访问50x.html
root html; # 指定对应的站点目录为html
}
}
}
其配置文件大致结构如下:
- 1、全局块:配置影响nginx全局的指令。一般有运行nginx服务器的用户组,nginx进程pid存放路径,日志存放路径,配置文件引入,允许生成worker process数等。
- 2、events块:配置影响nginx服务器或与用户的网络连接。有每个进程的最大连接数,选取哪种事件驱动模型处理连接请求,是否允许同时接受多个网路连接,开启多个网络连接序列化等。
- 3、http块:可以嵌套多个server,配置代理,缓存,日志定义等绝大多数功能和第三方模块的配置。如文件引入,mime-type定义,日志自定义,是否使用sendfile传输文件,连接超时时间,单连接请求数等。
- 4、server块:配置虚拟主机的相关参数,一个http中可以有多个server。
- 5、location块:配置请求的路由,以及各种页面的处理情况。
... #全局块
events { #events块
...
}
http #http块
{
... #http全局块
server #server块
{
... #server全局块
location [PATTERN] #location块
{
...
}
location [PATTERN]
{
...
}
}
server
{
...
}
... #http全局块
}
Nginx 如何配置负载均衡
基础配置格式
在 http 块中定义 upstream(上游服务器组),然后在 server 块中引用:
http {
# 定义负载均衡组
upstream backend_servers {
server 192.168.1.10:8080 weight=5;
server 192.168.1.11:8080 weight=3;
server 192.168.1.12:8080 backup; # 备用服务器
}
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://backend_servers;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
}
四种负载均衡策略详解
1. 轮询(Round Robin)- 默认
upstream backend {
server 192.168.1.10:8080;
server 192.168.1.11:8080;
server 192.168.1.12:8080;
}
特点:请求按时间顺序逐一分配到不同服务器,如果服务器宕机会自动剔除。
2. 加权轮询(Weighted Round Robin)
upstream backend {
server 192.168.1.10:8080 weight=5; # 权重高,处理更多请求
server 192.168.1.11:8080 weight=3;
server 192.168.1.12:8080 weight=1; # 权重低,处理较少请求
}
适用场景:服务器性能不均衡时,高性能机器分配更高权重。
3. IP Hash
upstream backend {
ip_hash; # 同一 IP 固定分配到同一服务器
server 192.168.1.10:8080;
server 192.168.1.11:8080;
}
适用场景:需要保持会话(Session)一致性的应用,如登录状态保持。
4. 最少连接(Least Connections)
upstream backend {
least_conn; # 将请求分配给当前连接数最少的服务器
server 192.168.1.10:8080;
server 192.168.1.11:8080;
}
适用场景:请求处理时间长短不一的服务,避免某些服务器过载。
高级参数配置
upstream backend {
server 192.168.1.10:8080 weight=5 max_fails=3 fail_timeout=30s;
server 192.168.1.11:8080 weight=3 max_fails=3 fail_timeout=30s;
server 192.168.1.12:8080 backup; # 仅当主服务器不可用时启用
server 192.168.1.13:8080 down; # 暂时不参与负载均衡
keepalive 32; # 长连接数,提高性能
}
参数说明:
max_fails=3:允许请求失败的次数,超过后标记为不可用fail_timeout=30s:失败后的暂停时间,30秒后再次尝试backup:备用服务器,主服务器全部不可用时启用down:标记服务器为离线状态,临时维护时使用
Nginx 如何配置反向代理
基础反向代理
将客户端请求转发到后端服务器,隐藏真实服务器信息:
server {
listen 80;
server_name www.example.com;
location / {
proxy_pass http://127.0.0.1:8080; # 转发到本地 Tomcat/Java 应用
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
常用代理参数详解
location /api/ {
proxy_pass http://backend_server;
# 基础头信息设置
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# 连接设置
proxy_connect_timeout 60s; # 连接超时时间
proxy_send_timeout 60s; # 发送超时时间
proxy_read_timeout 60s; # 读取响应超时时间
# 缓冲区设置
proxy_buffering on; # 启用缓冲
proxy_buffer_size 4k; # 响应头缓冲区
proxy_buffers 8 4k; # 响应体缓冲区数量和大小
# 错误处理
proxy_intercept_errors on; # 拦截后端错误
error_page 500 502 503 504 /50x.html;
}
多路径反向代理(API 网关场景)
server {
listen 80;
server_name gateway.example.com;
# 用户服务
location /api/user/ {
proxy_pass http://user-service-cluster/;
proxy_set_header Host $host;
}
# 订单服务
location /api/order/ {
proxy_pass http://order-service-cluster/;
proxy_set_header Host $host;
}
# 支付服务
location /api/pay/ {
proxy_pass http://pay-service-cluster/;
proxy_set_header Host $host;
}
# WebSocket 支持
location /ws/ {
proxy_pass http://websocket-server;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
反向代理 + SSL 终止(HTTPS 配置)
server {
listen 443 ssl http2;
server_name secure.example.com;
# SSL 证书配置
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
# 安全增强
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
proxy_pass http://internal-server:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
# 告诉后端这是 HTTPS 请求
proxy_set_header X-Forwarded-Proto https;
}
}
# HTTP 自动跳转 HTTPS
server {
listen 80;
server_name secure.example.com;
return 301 https://$server_name$request_uri;
}
Nginx 如何配置动静分离
核心思想
将 静态资源(图片、CSS、JS、HTML)与 动态请求(API、PHP、JSP)分开处理:
- 静态资源:Nginx 直接处理(高效、缓存友好)
- 动态请求:转发给后端应用服务器(Tomcat/Node/Python 等)
基础动静分离配置
server {
listen 80;
server_name www.example.com;
root /var/www/html; # 网站根目录
# 1. 静态资源 - Nginx 直接处理
location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff|woff2)$ {
expires 30d; # 缓存 30 天
access_log off; # 关闭日志,减少 IO
add_header Cache-Control "public, immutable";
# 可选:启用 gzip 压缩
gzip_static on;
}
# 2. HTML 文件 - 静态处理但较短缓存
location ~* \.html$ {
expires 1h;
add_header Cache-Control "public, must-revalidate";
}
# 3. 动态请求 - 转发到后端
location /api/ {
proxy_pass http://backend-server;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# 4. PHP 文件 - 转发到 PHP-FPM
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
# 5. 默认规则
location / {
try_files $uri $uri/ /index.html; # 前端路由支持
}
}
高级动静分离:独立静态资源服务器
生产环境推荐将静态资源部署到独立域名或 CDN:
# 主站 - 只处理动态请求
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://app-server-cluster;
}
}
# 静态资源服务器 - 专门处理静态文件
server {
listen 80;
server_name static.example.com;
root /var/www/static;
# 强缓存策略
location ~* \.(js|css)$ {
expires 1y;
add_header Cache-Control "public, immutable";
add_header Vary "Accept-Encoding";
# 跨域支持(如需字体文件跨域)
add_header Access-Control-Allow-Origin *;
}
# 图片资源
location ~* \.(jpg|png|gif|webp)$ {
expires 6M; # 6 个月
access_log off;
# 图片防盗链
valid_referers none blocked server_names *.example.com;
if ($invalid_referer) {
return 403;
}
}
# 大文件下载优化
location /downloads/ {
sendfile on; # 零拷贝传输
tcp_nopush on; # 优化网络包发送
limit_rate 500k; # 限速 500KB/s
}
}
前端项目部署最佳实践(React/Vue/Angular)
server {
listen 80;
server_name app.example.com;
root /var/www/frontend/dist; # 打包后的 dist 目录
index index.html;
# Gzip 压缩
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml;
# 静态资源 - 长期缓存(因为文件名有 hash)
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2)$ {
expires 1y;
add_header Cache-Control "public, immutable";
access_log off;
}
# 不缓存 HTML(确保获取最新版本)
location ~* \.html$ {
expires -1;
add_header Cache-Control "no-cache, no-store, must-revalidate";
add_header Pragma "no-cache";
}
# API 代理到后端
location /api/ {
proxy_pass http://backend-server;
proxy_set_header Host $host;
}
# 前端路由支持(单页应用必须)
location / {
try_files $uri $uri/ /index.html;
}
}
完整配置示例:综合实战
以下是一个生产环境的完整配置,整合负载均衡、反向代理、动静分离:
# /usr/local/nginx/conf/nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 4096;
use epoll; # Linux 高性能网络模型
multi_accept on; # 同时接受多个连接
}
http {
include mime.types;
default_type application/octet-stream;
# 日志格式
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" '
'rt=$request_time uct="$upstream_connect_time" '
'uht="$upstream_header_time" urt="$upstream_response_time"';
access_log /var/log/nginx/access.log main;
# 性能优化
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
client_max_body_size 50M;
# Gzip 压缩
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types text/plain text/css text/xml application/json application/javascript
application/rss+xml application/atom+xml image/svg+xml;
# 负载均衡组定义
upstream app_cluster {
least_conn;
server 192.168.1.10:8080 weight=5 max_fails=3 fail_timeout=30s;
server 192.168.1.11:8080 weight=5 max_fails=3 fail_timeout=30s;
server 192.168.1.12:8080 weight=3 backup;
keepalive 32;
}
# HTTP 重定向到 HTTPS
server {
listen 80;
server_name www.example.com example.com;
return 301 https://$server_name$request_uri;
}
# HTTPS 主站
server {
listen 443 ssl http2;
server_name www.example.com;
# SSL 配置
ssl_certificate /etc/nginx/ssl/cert.pem;
ssl_certificate_key /etc/nginx/ssl/key.pem;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_protocols TLSv1.2 TLSv1.3;
# 安全头
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
# 静态资源 - 长期缓存
location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff|woff2|ttf|eot)$ {
expires 6M;
access_log off;
add_header Cache-Control "public, immutable";
}
# 前端资源
location / {
root /var/www/frontend;
try_files $uri $uri/ /index.html;
expires 1h;
}
# API 请求 - 负载均衡
location /api/ {
proxy_pass http://app_cluster/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_connect_timeout 5s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
# 错误处理
proxy_intercept_errors on;
error_page 500 502 503 504 /50x.html;
}
# 错误页面
location = /50x.html {
root /var/www/error;
internal;
}
}
}
总结
| 功能 | 核心指令 | 应用场景 |
|---|---|---|
| 负载均衡 | upstream、proxy_pass | 高并发、高可用、横向扩展 |
| 反向代理 | proxy_pass、proxy_set_header | 隐藏后端、统一入口、SSL 终止 |
| 动静分离 | location、expires、root | 提升性能、降低后端压力、CDN 加速 |
最佳实践建议:
- 生产环境务必配置
max_fails和fail_timeout实现故障转移 - 静态资源使用强缓存(
expires 1y),HTML 使用协商缓存或禁止缓存 - HTTPS 建议在 Nginx 层统一处理(SSL 终止),后端使用 HTTP 简化配置
- 监控日志开启
upstream_response_time便于排查后端性能问题