Nginx学习笔记

Nginx学习笔记

 
1、简介
Nginx是一款占用内存少、并发数高的高性能服务器,在国内应用广泛。用作Web开发而言,应用较多的大致是:反向代理、负载均衡、动静分离、高可用这几个方向。
 
2、代理
正向代理
正向代理是位于客户端和目标服务器之间的中介,客户端通过代理服务器发送请求,代理服务器将请求转发到目标服务器,并将响应返回给客户端
客户端:客户端知道代理服务器的存在,并通过它访问网络
隐私保护:目标服务器不知道实际的客户端信息
用途:多用于突破网络限制,访问被屏蔽的网站,例如:VPN(FQ用的或者公司的VPN)
 
反向代理
反向代理位于目标服务器和客户端之间中介,客户端发送请求到反向代理服务器,反向代理将请求根据要求转发到对应的 目标服务器,并将响应返回给客户端
负载均衡:反向代理可以将请求按规则分发到多台目标服务器上,实现负载均衡
客户端:客户端并不知道反向代理服务器的存在,客户端只发送请求,反向代理对客户端是无感的
隐私保护:可以隐藏目标服务器内部的真是地址,提高安全性
用途:常用于提高性能、安全性、可维护性等
 
总结:
正向代理:客户端知道并使用代理来访问外部资源。
反向代理:客户端不知情,所有请求先经过代理服务器,然后代理服务器再根据配置的规则将其转发到内部的目标服务器。
反向代理示例:
# HTTP代理HTTP
server {
    # 用于表示当前server块监听80端口
    listen 80;
    
    # 用于指定服务器域名或者IP,当客户端请求的Host头部和server_name中的任意一个值匹配时,Nginx将使用此server块来处理请求
    server_name mystudy.com;
    
    # listen和server_name的关系
    # listen决定了监听哪个端口,server_name决定了请求哪个Host,一个listen可以对应多个server_name,但一个server必须包含至少一个listen

    location / {
        proxy_pass http://localhost:3000;  # 将请求转发到后端服务器
        proxy_set_header Host $host;  # 设置请求头
        proxy_set_header X-Real-IP $remote_addr;  # 获取真实IP
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;  # 获取转发的IP
        proxy_set_header X-Forwarded-Proto $scheme;  # 获取协议类型
    }
    
    location /api {
        proxy_pass http://localhost:3001;  # 将请求转发到后端服务器
        proxy_set_header Host $host;  # 设置请求头
        proxy_set_header X-Real-IP $remote_addr;  # 获取真实IP
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;  # 获取转发的IP
        proxy_set_header X-Forwarded-Proto $scheme;  # 获取协议类型
    }
    
    location /api/user/ {
        proxy_pass http://localhost:3002;  # 将请求转发到后端服务器
        proxy_set_header Host $host;  # 设置请求头
        proxy_set_header X-Real-IP $remote_addr;  # 获取真实IP
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;  # 获取转发的IP
        proxy_set_header X-Forwarded-Proto $scheme;  # 获取协议类型
    }
    
    # 代理WebSocket连接
    location /websocket {
        proxy_pass http://backend:8080/websocket;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

# HTTPS代理到HTTP
server {
    listen 443 ssl;
    server_name myhttpsstudy.com;

    # HTTPS需要指定的 SSL/TLS 证书和私钥的路径
    ssl_certificate /path/to/your/certificate.crt;
    ssl_certificate_key /path/to/your/private.key;

    location / {
        proxy_pass https://backend:8443; # 后端 HTTPS 端口
        proxy_set_header Host $host; # 设置请求头
        proxy_set_header X-Real-IP $remote_addr; # 获取真实IP
        proxy_set_header X-Forwarded-Proto https; # 用于告知服务器当前请求是HTTPS的
    }
}

#将HTTP和HTTPS的请求都代理到同一个后端服务器上

# HTTP的代理块,它会将请求重定向到HTTPS
server {
    listen 80;
    server_name example.com;
    return 301 https://$server_name$request_uri; # 将 HTTP 重定向到 HTTPS
}

# HTTPS的代理块,将请求转发到后端服务器
server {
    listen 443 ssl;
    server_name example.com;

    ssl_certificate /path/to/your/certificate.crt;
    ssl_certificate_key /path/to/your/private.key;

    location / {
        proxy_pass http://backend:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Proto https;
    }
}

# HTTPS反向代理到HTTPS
server {
    listen 443 ssl;
    server_name mystudy.com;

    ssl_certificate /path/to/your/certificate.crt;
    ssl_certificate_key /path/to/your/private.key;

    location / {
        proxy_pass https://backend:8443; # 后端 HTTPS 端口
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Proto https;
    }
}

 

 
3、负载均衡
负载均衡是把来自客户端的请求按照预先配置的负载均衡算法,转发到不同的后端服务器上,这种方式使得单台服务器不会过载,从而提高整体响应速度和系统的可靠性。Nginx作为反向代理服务器,广泛的应用于实现负载均衡。
负载均衡算法:
轮询:依次将每个请求分配给后端的服务器
加权轮询:根据服务器的性能权重(可配置)来分发请求,权重高的服务器会接收到更多的请求
最少连接:将请求发送到当前连接数最少的后端服务器上,适合处理长连接的场景
IP哈希:通过对客户端的IP地址进行哈希计算,求得哈希值,根据哈希值来确定请求的目标服务器,适合需要会话保持(固定的用户每次都请求到固定的服务器上)的应用
健康检查:
Nginx可以定期对后端服务器进行健康检查,以确保只有健康的服务器才能接收到请求,如果某台服务器不可用,Nginx则不会向其分发请求而是将请求分发到健康的服务器上
故障转移:
Nginx可以在某个后端服务器出现故障时,迅速的将流量切换至其它正常运转的服务器上,以保证系统的可靠性
配置示例:
# 这是一个结合了均在均衡和反向代理的nginx配置示例

#让 Nginx 自动决定工作进程数量
worker_processes auto;

events {
    worker_connections 1024;
}

http {
    
# 在HTTP块中定义三个upstream并增加权重参数
# health_check用于开启nginx的健康检查功能并定义参数,当某台服务器不可用时,Nginx将不会将请求转发到该服务器上

    # product_servers代表产品
    upstream product_servers {
        server product-server-1:8080 weight=2;
        server product-server-2:8080 weight=2;
        server product-server-3:8080 weight=1;
        server product-server-4:8080 backup; # 备用服务器,只有当其他服务器都不可用时才使用
        health_check interval=5s timeout=1s fail_timeout=10s; # 健康检查
    }
    
    # cart_servers代表购物车
    upstream cart_servers {
        server cart-server-1:8081;
        server cart-server-2:8081;
        health_check interval=5s timeout=1s fail_timeout=10s;
    }

    # order_servers代表订单
    upstream order_servers {
        server order-server-1:8082;
        server order-server-2:8082;
        health_check interval=5s timeout=1s fail_timeout=10s;
    }

    server {
        listen 80;
        server_name myshop.com;

        # 以下三个localtion是三个常见的反省代理示例
        # proxy_pass指向了upstream负载均衡块来实现反向代理
        # upstream块中包含了多个后端服务的地址,也指定了负载均衡算法
        location /product {
            proxy_pass http://product_servers;
        }

        location /cart {
            proxy_pass http://cart_servers;
        }

        location /order {
            proxy_pass http://order_servers;
        }

        # 基于请求头的路由,根据不同的请求头来指向不同的upstream负载均衡块
        location /api {
            if ($http_x_api_version = "v1") {
                proxy_pass http://product_servers;
            }
            if ($http_x_api_version = "v2") {
                proxy_pass http://order_servers;
            }
        }

        # 基于 URI 的路由,更精确的控制,开启了基本的Basic Auth身份认证
        location ~ ^/admin/(.*) {
            proxy_pass http://order_servers;
            auth_basic "Restricted Area";
            auth_basic_user_file /etc/nginx/.htpasswd; # 需要配置.htpasswd文件
        }

        # 默认路由
        location / {
            proxy_pass http://product_servers;
        }

        # 其他配置...
    }
}

 

 
4、动静分离
动静分离,意如其名,是将静态资源和动态资源分离处理,用于提高网站性能和可维护性。
动态内容:通常指需要通过后端服务器生成的内容,这些内容通常需要实时计算和处理才能得出结果。例如:数据库查询结果、用户数据等等。
静态内容:固定不变的内容,例如:图片、CSS、HTML、JS文件等。一般使用专门的服务器来处理和存放静态资源,例如:托管子Nginx或者CDN上
优势:
1、性能提升:静态文件可以直接从静态服务器获取,减轻了后端服务器的负担
2、易于缓存:静态内容可以进行缓存,提升响应速度,减少资源访问次数
3、可扩展性:可以独立的扩展静态和动态服务器,两者互不影响
4、安全性:就动态处理和静态资源分离,可以降低被攻击的范围,减少攻击面
注意:
动静分离之后会产生跨域问题,这个也可以通过Nginx反向代理解决
 
配置示例:
worker_processes auto;
events {
    worker_connections 1024;
}

http {
    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    # 静态资源服务器地址,替换为你的实际地址
    upstream static_server {
        server static-server-ip:80; # 你的静态资源服务器IP和端口
        # 可以添加多个服务器,实现高可用
        # server static-server-ip2:80;
        # server static-server-ip3:80;
    }

    # 应用服务器地址,替换为你的实际地址
    upstream app_server {
        server app-server-ip:9000; # 你的应用服务器IP和端口,通常是PHP-FPM监听的端口
        # 可以添加多个服务器,实现高可用
        # server app-server-ip2:9000;
        # server app-server-ip3:9000;
    }

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

        # 设置缓存,提高性能
        location ~* \.(js|css|jpg|jpeg|png|gif|ico|svg|woff|woff2|ttf|eot)$ {
            proxy_pass http://static_server;
            proxy_cache static_cache;
            proxy_cache_valid 200 302 1h; # 缓存有效期为1小时
            proxy_cache_valid any 1m; # 其他状态码缓存1分钟
            proxy_cache_use_stale error timeout invalid_header updating http_500 http_502 http_503 http_504; # 缓存失效时使用旧缓存
            add_header Cache-Control public; # 允许浏览器缓存
            expires 1h; # 设置浏览器缓存有效期为1小时
        }

        # 处理动态请求
        location / {
            proxy_pass http://app_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;
        }

        # 错误页面
        error_page 404 /404.html;
        error_page 500 502 503 504 /50x.html;
        location = /404.html {
            root /var/www/html;
        }
        location = /50x.html {
            root /var/www/html;
        }
    }

    # 缓存配置
    proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=static_cache:10m inactive=1d;
}

 

 
5、高可用
Nginx的高可用需要以来keepalive,这么做是为了防止单台Nginx故障时导致的访问故障,将多台Nginx串联在一起,但每个nginx都有自己的ip,怎么将他们统一呢?这个时候就要引入虚拟ip的概念,nginx会在keepalive中配置一个虚拟ip将他们串联在一起,keepalive会监测同一虚拟ip下nginx的状态,如果其中某台nginx出现故障则停止对他发放用户请求。
 
6、Nginx工作原理
 
Nginx 的工作原理可以概括为一个基于事件驱动的、异步的、非阻塞的架构。它通过一个主进程和多个工作进程来处理请求,高效地利用系统资源,实现高并发处理能力。 下面我们逐步分解其工作机制:
1、主进程 (master process):
主要职责: 主进程负责读取和解析配置文件,管理工作进程,监控工作进程的运行状态,并在必要时重启或替换工作进程。它本身不处理任何客户端请求。
举个例子:主进程就像开发组长一样,在获取产品经理的需求后(读取和解析配置文件)将需求拆分并同步给组内成员(创建工作进程),并在每天下班前开会要求组员汇报需求进展(监控工作进程的运行状态),如果有特殊情况,例如张三请假了暂时不能继续需求的开发工作,需要将张三的工作分配给李四去完成(重启或替换工作进程)
 
功能:
加载配置文件。
创建、管理和监控工作进程。
接收信号并进行相应的处理(例如,重新加载配置文件、优雅地关闭服务器)。
处理一些管理任务,例如日志记录。
2、工作进程 (worker process):
主要职责: 工作进程是实际处理客户端请求的进程。 Nginx 使用多进程模型,每个工作进程处理一部分客户端连接。
工作方式: 工作进程采用异步非阻塞的方式处理请求。这意味着一个工作进程可以同时处理多个客户端请求,而不会因为一个请求的阻塞而影响其他请求的处理。 它通过事件机制来管理多个连接,当一个连接有事件发生(例如,数据到达、连接关闭)时,工作进程才会被唤醒处理。
事件驱动: Nginx 使用 epoll (Linux) 或 kqueue (FreeBSD) 等高效的事件驱动机制来监听网络事件。 这些机制允许 Nginx 同时监听大量的客户端连接,而不会造成性能瓶颈。
非阻塞 I/O: Nginx 使用非阻塞 I/O 操作,这意味着当一个 I/O 操作无法立即完成时,不会阻塞工作进程,而是返回一个错误码,工作进程可以继续处理其他请求。 当 I/O 操作完成时,Nginx 会通过事件机制通知工作进程。
举个例子:工作进程相当于普通开发人员,负责获取开发组长拆分的需求(处理请求),根据使用现有工具进行开发(系统调用,例如调用mysql、redis、读取文件等等),当需求开发遇到问题,向组长提出疑问且未得到明确答复前,先去做其它需求(异步非阻塞I/O),当得到明确答复后继续之前的工作
 
这里有必要说下同步异步,阻塞非阻塞
同步:调用者发起请求后,必须等待被调用者返回结果后才能去处理下一个请求,就像去饭店点菜,必须得等才做好了才能离开
异步:调用者发起请求后,不必等待被调用者返回结果也可以继续执行其它操作,被调用者处理完后会通过某种机制(例如回调函数、事件、信号等)告知调用者,就像点外卖,点完外卖就可以做其它事了,不需要一直等着,只要在外卖送到的时候取餐即可
阻塞:操作执行期间,调用者会被阻塞,直到操作完成,就像排队买火车票,必须排队等候,只有轮到自己了才能买票一样
非阻塞:操作执行期间,调用者不会被阻塞,可以继续执行其它操作,操作完成后通过某种机制将结果告知调用者,就像在12306买火车票一样,不用排队,随时都可以买票,付款结束后等待系统反馈结果即可
 
请求处理流程:
1、客户端请求: 客户端向 Nginx 发送请求。
2、连接接受: 主进程监听网络端口,接受客户端连接。
3、连接分配: 主进程将连接分配给一个空闲的工作进程。
4、请求处理: 工作进程处理请求,包括解析请求行、请求头、请求体,以及查找相应的资源。
5、资源处理: 如果请求的是静态资源,工作进程直接读取并返回资源;如果请求的是动态资源,工作进程会将请求转发给后端服务器(例如,FastCGI、uWSGI、Tomcat 等)。
6、响应返回: 工作进程将响应返回给客户端。
7、连接关闭: 连接关闭。
7、常用命令
所有Nginx的命令都要在Nginx的目录下执行,可以使用ps -ef | grep nginx 查看nginx的进程和位置
查看当前Nginx的版本号:./nginx -v
0
 
启动nginx:./nginx
关闭nginx:./nginx -s stop
重载nginx:./nginx -s reload (用于使新的配置文件生效且不用重启nginx)
 
7、常用配置
Nginx所有的配置都在conf目录下的nginx.conf文件中进行修改,示例如下:
0
 
配置文件由三部分组成:
1、全局块
用于配置全局运行的指令,位于文件开头到events块之前,示例如下:
0
示例中worker_processes 代表支持的最大并发数,数值越大可以支持的并发处理越多
 
2、events块
此模块主要涉及指令影响Nginx服务器与用户的网络连接,常用语设置work process喜爱的网络连接进行序列化,是 否允许同时接收多个网络连接,以及work process可以同时支持的最大连接数,这部分配置对nginx的性能影响很大,在实际应用 中应当灵活配置,上述全局块的示例图中的work_connections 1024代表着work process最大连接数是1024
 
3、http块
此部分是Nginx中配置最频繁的部分,包含了代理、缓存、日志等等绝大多数功能和第三方模块都在这里进行配置,需要注意,在http块中包含了http全局块、server块两部分。常见的反向搭理、负载均衡、动静分离、高可用都需要在此模块中来配置。
 
 
 
 
 
 
 
 
 
posted @ 2025-07-25 18:25  茴香饺子、  阅读(47)  评论(0)    收藏  举报