Nginx详讲

目录

一、Nginx简介

1、Nginx是什么

  • Nginx (engine x) 是一个高性能的HTTP反向代理web服务器,同时也提供IMAP/POP3/SMTP服务。Nginx是由伊戈尔·赛索耶夫为俄罗斯访问量第二的Rambler.ru站点(俄文:Рамблер)开发的,第一个公开版本0.1.0发布于2004年10月4日。其将源代码以类BSD许可证的形式发布,因它的稳定性丰富的功能集简单的配置文件低系统资源的消耗而闻名。2011年6月1日,nginx 1.0.4发布。
  • Nginx是一款轻量级Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,在BSD-like 协议下发行。其特点是占有内存少,并发能力强,事实上nginx的并发能力在同类型的网页服务器中表现较好,中国大陆使用nginx网站用户有:百度、京东、新浪、网易、腾讯、淘宝等。
  • Nginx 是高性能的 HTTP 和反向代理的web服务器,处理高并发能力是十分强大的,能经受高负载的考验,有报告表明能支持高达 50,000 个并发连接数。
  • Nginx支持热部署启动简单,可以做到7*24不间断运行。几个月都不需要重新启动。

2、Nginx的优势

  • 高性能 :Nginx是一个高性能的HTTP和反向代理服务器,能够处理大量的并发连接和请求,适合高流量的网站。

  • 高可靠性:Nginx使用事件驱动和异步处理方式,能够在保持高性能的同时,提供高可靠性的服务。

  • 灵活性:Nginx支持多种配置方式,可以通过配置文件灵活地调整其行为,满足不同的需求。

  • 扩展性:Nginx可以通过模块扩展其功能,支持负载均衡、缓存、SSL加密等多种功能。

  • 低资源消耗 :Nginx是一个轻量级的服务器,占用的系统资源较少,适合在资源有限的环境中部署

  • 跨平台 :Nginx支持多种操作系统,包括Linux、Unix、MacOS等,具有很好的跨平台兼容性。

  • 社区支持:Nginx有一个活跃的开源社区,提供了大量的文档、教程和模块,方便用户学习和使用。

  • 安全性 :Nginx提供了一些基本的安全功能,如防止DDoS攻击、防止SQL注入等,可以提高网站的安全性。

  • 易于维护 :Nginx的配置文件简单明了,易于理解和维护,降低了运维的难度。

  • 支持多种协议:Nginx不仅支持HTTP和HTTPS协议,还支持其他协议如SMTP、POP3等,可以作为多种服务的代理服务器。

3、Nginx下载

Nginx的下载路径:Nginx的官方网址

解压缩之后,进入Nginx的工作目录,工作目录如下:

启动

  • 启动方式一 :双击nginx.exe,双击后你能看见一个小黑窗口一闪而过。
  • 启动方式二 :打开cmd命令窗口,切换到nginx解压目录下,输入命令 nginx.exe ,回车即可

注意:如果安装目录是中文的情况,打开exe文件时会报错。
检查是否安装成功

打开浏览器:浏览器地址栏输入网址 http://localhost:80 回车,出现以下页面说明启动成功!

nginx的配置文件是conf目录下的nginx.conf,默认配置的nginx监听的端口为80,如果80端口被占用可以修改为未被占用的端口即可。

当我们修改了nginx的配置文件nginx.conf 时,不需要关闭nginx后重新启动nginx ,只需要执行命令 nginx -s reload 即可让改动生效

关闭Nginx:

如果使用cmd命令窗口启动nginx, 关闭cmd窗口是不能结束nginx进程的,可使用两种方法关闭nginx

  • 方法一:(1)输入nginx命令 nginx -s stop(快速停止nginx) 或 nginx -s quit(完整有序的停止nginx),这两个命令的区别在于nginx -s stop是快速停止Nginx,而nginx -s quit是有序的停止Nginx,前者可能会导致数据没有完全保存;
  • 方法二:(2)使用taskkill taskkill /f /t /im nginx.exe
  • 注意事项:方法一必须要在Nginx的安装包目录下。否则无法找到Nginx。

二、Nginx的核心功能

1、Nginx的反向代理

什么是反向代理?

正向代理

  • 客户端知道目标服务器

  • 代理服务器代表客户端访问目标

  • 用途:科学上网、缓存加速

    客户端 → 正向代理 → 互联网 → 目标网站

反向代理

  • 客户端不知道目标服务器

  • 代理服务器代表后端服务器提供服务

  • 用途:负载均衡、安全防护

    客户端 → 反向代理 → 后端服务器群
    (Nginx) (隐藏的)

简单的反向代理

javascript 复制代码
http {
    server {
        listen 80;
        server_name example.com;
        
        location / {
            proxy_pass http://localhost:3000;
            # 代理到本地的3000端口(如Node.js应用)
        }
    }
}

完整的基础配置

javascript 复制代码
server {
    listen 80;
    server_name api.example.com;
    
    location / {
        # 后端服务器地址
        proxy_pass http://127.0.0.1:8080;
        
        # 重要:传递客户端真实IP
        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 off;
    }
}

带负载均衡的方向代理

javascript 复制代码
http {
    # 定义上游服务器组
    upstream backend_servers {
        # 权重负载均衡
        server 192.168.1.101:8080 weight=3;  # 30%的请求
        server 192.168.1.102:8080 weight=2;  # 20%的请求
        server 192.168.1.103:8080 weight=5;  # 50%的请求
        
        # 健康检查
        max_fails=3;      # 失败3次标记为不可用
        fail_timeout=30s; # 30秒后重试
        
        # 负载均衡算法(默认轮询)
        # least_conn;     # 最少连接
        # ip_hash;        # IP哈希(会话保持)
        # hash $request_uri consistent;  # 一致性哈希
    }
    
    server {
        listen 80;
        server_name app.example.com;
        
        location / {
            proxy_pass http://backend_servers;
            
            # 负载均衡相关
            proxy_next_upstream error timeout http_500 http_502 http_503 http_504;
            proxy_next_upstream_tries 3;
            
            # 保持连接
            proxy_http_version 1.1;
            proxy_set_header Connection "";
        }
    }
}

带动静分离的反向代理

javascript 复制代码
server {
    listen 80;
    server_name www.example.com;
    
    # 静态文件(直接由Nginx处理)
    location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff|woff2|ttf|svg)$ {
        root /var/www/html/static;
        expires 30d;  # 缓存30天
        access_log off;
        add_header Cache-Control "public, immutable";
    }
    
    # API请求(代理到后端)
    location /api/ {
        proxy_pass http://127.0.0.1:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
    
    # 前端SPA应用(代理到前端服务器)
    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        
        # 支持WebSocket
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

反向代理解释


正向代理 就像我个人的VPN。我想访问Google,但直接访问不了,于是我在国外租了一台服务器作为代理。我在浏览器配置这个代理后,所有请求先到这台服务器,再由它转发到Google。这个代理为我个人服务,Google看到的是代理服务器的IP,不知道我的真实IP。

反向代理 就像淘宝的网关集群。数亿用户访问淘宝,但淘宝背后不是一台服务器,而是成千上万台。他们在这些服务器前部署了Nginx反向代理集群。用户访问taobao.com,请求先到反向代理,然后代理根据:

  1. 请求类型(商品、订单、支付)
  2. 服务器负载情况
  3. 地理位置
    智能地将请求分发到合适的后端服务器。

2、Nginx的负载均衡。。

什么是负载均衡?

负载均衡建立在现有网络结构之上,它提供了一种廉价有效透明的方法扩展网络设备和服务器的带宽、增加吞吐量、加强网络数据处理能力、提高网络的灵活性和可用性。

负载均衡(Load Balance)其意思就是将客户端的请求智能地分发到多个服务器上,以避免任何单个服务器过载,从而提高系统的整体处理能力和可靠性

简单来说就是:现有的请求使服务器压力太大无法承受,所有我们需要搭建一个服务器集群,去分担原先一个服务器所承受的压力,那现在我们有ABCD等等多台服务器,我们需要把请求分给这些服务器,但是服务器可能大小也有自己的不同,所以怎么分?如何分配更好?又是一个问题。
负载均衡的基础使用方法:

javascript 复制代码
http {
    # 1. 定义上游服务器组(upstream)
    upstream backend_servers {
        # 服务器列表
        server 192.168.1.101:8080;
        server 192.168.1.102:8080;
        server 192.168.1.103:8080;
    }
    
    # 2. 使用负载均衡
    server {
        listen 80;
        server_name app.example.com;
        
        location / {
            proxy_pass http://backend_servers;  # 指向upstream组
        }
    }
}

负载均衡算法(核心)

1 轮询(Round Robin) - 默认算法

javascript 复制代码
upstream backend {
    # 默认就是轮询,无需额外配置
    server 192.168.1.101:8080;
    server 192.168.1.102:8080;
    server 192.168.1.103:8080;
}

特点:按顺序分发请求,每个服务器轮流处理

2 权重轮询(Weighted Round Robin)

javascript 复制代码
upstream backend {
    server 192.168.1.101:8080 weight=3;  # 30%的请求
    server 192.168.1.102:8080 weight=5;  # 50%的请求
    server 192.168.1.103:8080 weight=2;  # 20%的请求
}

适用场景:服务器配置不同(CPU、内存差异)

3.IP哈希(IP Hash) - 会话保持

javascript 复制代码
upstream backend {
    ip_hash;  # 基于客户端IP的哈希
    
    server 192.168.1.101:8080;
    server 192.168.1.102:8080;
    server 192.168.1.103:8080;
}

特点 :同一IP的请求始终转发到同一服务器
适用场景:需要Session保持的应用

4 最少连接(Least Connections)

javascript 复制代码
upstream backend {
    least_conn;  # ← 只需要这个!
    
    server 192.168.1.101:8080;  # 当前连接数:5
    server 192.168.1.102:8080;  # 当前连接数:3 ← 选择这个
    server 192.168.1.103:8080;  # 当前连接数:8
}

特点 :将请求发给当前连接数最少的服务器
适用场景:处理时间长短不一的长连接场景

5.一致性哈希(Consistent Hash)
一致性哈希 是一种特殊的哈希算法,在服务器集群扩容或缩容时最小化数据重新分布的影响

javascript 复制代码
upstream backend {
    hash $request_uri consistent;  # 基于请求URI的一致性哈希
    
    server 192.168.1.101:8080;
    server 192.168.1.102:8080;
    server 192.168.1.103:8080;
}

特点:相同URI的请求始终到同一服务器,增减服务器时影响最小

3、Nginx的动静分离

什么是Nginx的动静分离?

Nginx的静态处理能力很强,但是动态处理能力不足,因此,在企业中常用动静分离技术。动静分离技术其实是采用代理的方式,在server{}段中加入带正则匹配的location来指定匹配项针对PHP的动静分离:静态页面交给Nginx处理,动态页面交给PHP-FPM模块或Apache处理。在Nginx的配置中,是通过location配置段配合正则匹配实现静态与动态页面的不同处理方式

目前,通过使用Nginx大大提高了网站的响应速度,优化了用户体验,让网站的健壮性更上一层楼!

动静分离就是将动态请求和静态请求分开处理:

  • 静态资源:图片、CSS、JS、字体等文件 → 由 Nginx 直接处理
  • 动态请求:API、业务逻辑、数据库操作 → 转发给后端应用服务器

为什么要做动静分离?

性能提升

优势

  1. 性能提升:Nginx处理静态文件比应用服务器快10-100倍
  2. 降低负载:减少应用服务器压力
  3. 并发能力:Nginx可处理上万并发静态请求
  4. 缓存友好:静态资源可设置长时间缓存

基础配置

javascript 复制代码
server {
    listen 80;
    server_name example.com;
    root /var/www/html;
    
    # 静态文件处理
    location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
        # Nginx直接处理,不转发到后端
        expires 30d;  # 缓存30天
        access_log off;  # 不记录访问日志
    }
    
    # 动态请求转发
    location / {
        proxy_pass http://backend_server:3000;
        proxy_set_header Host $host;
    }
}
javascript 复制代码
http {
    # 开启高效文件传输
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    
    # 文件缓存配置
    open_file_cache max=10000 inactive=30s;
    open_file_cache_valid 60s;
    open_file_cache_min_uses 2;
    open_file_cache_errors on;
    
    # 压缩配置(提升传输效率)
    gzip on;
    gzip_vary on;
    gzip_min_length 1024;
    gzip_types text/plain text/css text/xml text/javascript 
               application/javascript application/xml+rss 
               application/json image/svg+xml;
    
    server {
        listen 80;
        server_name www.example.com;
        root /var/www/example.com;
        
        # ========== 静态资源配置 ==========
        
        # 图片文件
        location ~* \.(jpg|jpeg|png|gif|bmp|webp|svg)$ {
            expires 365d;  # 缓存1年
            access_log off;
            add_header Cache-Control "public, immutable";
            
            # 图片优化:开启图片处理模块(需要编译时包含)
            # image_filter resize 800 600;
            # image_filter_jpeg_quality 85;
            
            # 防盗链
            valid_referers none blocked server_names *.example.com;
            if ($invalid_referer) {
                return 403;
            }
        }
        
        # 样式文件
        location ~* \.(css)$ {
            expires 30d;
            access_log off;
            add_header Cache-Control "public";
        }
        
        # JavaScript文件
        location ~* \.(js)$ {
            expires 30d;
            access_log off;
            add_header Cache-Control "public";
            
            # 对JS文件进行压缩(如果有预压缩版本)
            gzip_static on;
        }
        
        # 字体文件
        location ~* \.(woff|woff2|ttf|eot|otf)$ {
            expires 365d;
            access_log off;
            add_header Cache-Control "public, immutable";
            add_header Access-Control-Allow-Origin "*";  # 跨域支持
        }
        
        # 视频/音频文件
        location ~* \.(mp4|webm|ogg|mp3|wav|flac|aac)$ {
            expires 30d;
            access_log off;
            
            # 支持视频流媒体
            mp4;
            mp4_buffer_size 4M;
            mp4_max_buffer_size 10M;
        }
        
        # PDF/文档文件
        location ~* \.(pdf|doc|docx|xls|xlsx|ppt|pptx)$ {
            expires 7d;
            add_header Cache-Control "public";
            
            # 安全设置:防止直接在浏览器打开
            add_header X-Content-Type-Options "nosniff";
            add_header X-Frame-Options "SAMEORIGIN";
        }
        
        # ========== 动态请求配置 ==========
        
        # API接口
        location /api/ {
            proxy_pass http://api_backend:8080;
            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 10s;
            proxy_read_timeout 30s;
            
            # 禁用缓存
            proxy_no_cache 1;
            proxy_cache_bypass 1;
            add_header X-Cache-Status "BYPASS";
        }
        
        # WebSocket支持
        location /ws/ {
            proxy_pass http://websocket_backend:3000;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            proxy_set_header Host $host;
            
            # 长连接超时
            proxy_read_timeout 3600s;
        }
        
        # PHP动态请求(如果是PHP应用)
        location ~ \.php$ {
            fastcgi_pass php_backend:9000;
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            include fastcgi_params;
            
            # 安全设置
            fastcgi_hide_header X-Powered-By;
        }
        
        # 主应用路由(前端SPA应用)
        location / {
            # 尝试直接访问静态文件
            try_files $uri $uri/ @backend;
            
            # 如果是HTML文件,设置较短缓存
            if ($request_filename ~* ^.*?\.(html|htm)$) {
                expires 1h;
                add_header Cache-Control "public, must-revalidate";
            }
        }
        
        # 转发到后端应用(处理前端路由)
        location @backend {
            proxy_pass http://app_backend:3000;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_cache_bypass 1;
            proxy_no_cache 1;
        }
        
        # ========== 特殊配置 ==========
        
        # 禁止访问隐藏文件
        location ~ /\. {
            deny all;
            access_log off;
            log_not_found off;
        }
        
        # 禁止访问特定文件类型
        location ~* \.(log|sql|bak|conf|ini|sh)$ {
            deny all;
        }
        
        # 错误页面
        error_page 404 /404.html;
        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
            root /usr/share/nginx/html;
            internal;
        }
        
        # 访问日志格式
        access_log /var/log/nginx/example.com.access.log combined;
        error_log /var/log/nginx/example.com.error.log warn;
    }
}
相关推荐
乘云数字DATABUFF4 天前
5分钟部署开源APM Databuff:OpenTelemetry全链路追踪入门实战
运维·后端
荣--6 天前
一键部署不是为了省时间 —— 它是把"买来的 PaaS"变成"自己的平台"的拐点
运维·zabbix·工程化·一键部署·平台化·边界设计
江华森6 天前
动手实战学 Docker — 从零到集群编排完全指南
运维
Avan_菜菜6 天前
FRP 内网穿透完整实战:从 HTTP 映射到 HTTPS 自签代理
运维·nginx·https
SelectDB7 天前
Litefuse 开源并推出单进程轻量模式,25 秒就能跑起来的 Agent 可观测与评估平台
运维·后端·自动化运维
XIAOHEZIcode9 天前
Linux系统鼠标偏移常见原因以及修复方案
linux·运维·游戏
用户0328472220709 天前
如何搭建本地yum源(上)
运维
ping某11 天前
为什么 Nginx 明明监听了 80,转发后端时却用了 4xxxx 端口?
后端·nginx
大树8812 天前
金刚石散热越强,管路越先见顶
大数据·运维·服务器·人工智能·ai
摇滚侠12 天前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql