一、Nginx动静分离

简介

动静分离是负载均衡的一种实现方式,他将静态资源和动态资源分离到不同服务器上,实现的原理和普通负载均衡区别不大,只是将真实服务器进行了区分

配置方式

LB

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
/etc/nginx/conf.d/proxy.conf
upstream static{
server 192.168.146.130:80;
}

upstream java{
server 192.168.146.133:8080;
}

server{
listen 80;
server_name 192.168.146.134;

location ~* .*\.(jpg|png|gif)$ {
proxy_pass http://static;
include proxy_params; #请求头文件,文件名可自定义
}
location ~* .*\.jsp$ {
proxy_pass https://java;
include proxy_params;
}
}

/etc/nginx/proxy_params
proxy_set_header Host $http_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_set_header Host 设置的是代理主机ip值
proxy_set_header Host $http_host;
# X-Real-IP 指客户端的真实IP,如果设置了$remote_addr这个值,后端服务器就能获取到客户端的真实IP
proxy_set_header X-Real-IP $remote_addr;
# X-Real-IP 主要用于直接获取真实客户端的 IP 地址,适用于简单的代理环境;而 X-Forwarded-For 则提供了记录整个
请求链路上所有 IP 地址的能力,适用于复杂的多级代理架构

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# X-Forwarded-Proto(XFP)是一个事实上的标准首部,用来确定客户端和服务器或代理连接之间所采取的协议(https http)
proxy_set_header X-Forwarded-Proto $scheme;
#这些指令的核心作用是让后端服务器 “穿透” 反向代理,获取客户端请求的真实上下文(主机名、IP、代理链路、协议)
#确保后端服务的日志、权限控制、协议适配等功能正常工作。在生产环境的反向代理配置中,这些头通常是必配项。

RS-Static

1
2
3
4
5
6
7
8
server{
listen 80;
server_name 192.168.146.130;

location ~* .*\.(png|jpg|gif)$ {
root /html/nginx/images;#咋该路径下存放一张图片
}
}

RS-Dynamic
这个要先下载tomcat,dnf install -y tomcat
然后启动就可以了,最后在/usr/share/tomcat/webapps/ROOT/下创建jsp文件,这是tomcat默认读取的路径

最后在网页上测试,输入LB路径/nginx.png测试,或者LB路径/test.jsp

二、Nginx继续深入

Nginx为什么能支持高并发和拥有高性能

  • nginx采用多进程+异步非阻塞方式(IO多路复用Epoll)

什么是多路IO复用

  • 传统单线程(阻塞IO):服务员一次性之服务于一个顾客,直到将顾客的全部需求解决。
  • IO多路复用:谁举手,帮谁解决,且只解决当前需求

就像是老师在课堂上班学生解决问题,谁举手就帮谁解决,但不会一直等到该学生做完整个实验才帮其他学生解决,而是解决完学生当前的需求就结束。

Nginx日志切割

目的是防止单个日志文件过大,读取麻烦,也是方便阅读,快速找到对应时间的日志

1
2
3
4
5
6
7
#!/bin/bash
LOG_PATH=/usr/local/nginx/logs
YESTERDAY=$(date -d 'yesterday' +%Y-%m-%d)

cp /var/log/nginx/access.log ${LOG_PATH}/access_${YESTERDAY}.log && >/var/log/nginx/access.log

cp /var/log/nginx/error.log ${LOG_PATH}/error_${YESTERDAY}.log && >/var/log/nginx/error.log

写完后添加一下x权限,就可以添加定时任务了

1
2
3
4
crontab -e

0 0 * * * /usr/local/nginx/logs/NginxLogRotate.sh
#分时日月周。表示每天凌晨0点0分执行脚本

常见错误码

状态码 名称 大白话解释 常见场景
200 OK 请求成功!服务器正常返回了你要的数据。 网页正常访问、API请求成功
301 Moved Permanently 永久搬家了!这个网址以后都用新地址,浏览器会自动跳转。 网站换域名(比如 http 跳 https)
302 Found (临时重定向) 暂时换个地方!这次先跳转,下次可能还用旧地址。 临时维护页面跳转、登录后跳回原页
304 Not Modified 没变过,用缓存吧!你本地缓存的文件还能用,不用重新下载。 静态资源(图片/CSS/JS)缓存生效时
400 Bad Request 你发了个无效请求!服务器看不懂(比如参数格式错了)。 表单提交缺少必填字段、URL格式错误
401 Unauthorized 没带通行证!需要登录或认证,但你还没提供。 访问需要登录的页面、API密钥缺失
403 Forbidden 禁止访问!你有身份,但权限不够(比如普通用户访问管理员页面)。 文件权限设置错误、IP被拉黑
404 Not Found 找不到了!你请求的页面或文件不存在。 输错网址、服务器删除了页面
405 Method Not Allowed 姿势不对!你用错了请求方法(比如该用POST却用了GET)。 用GET请求只支持POST的API
500 Internal Server Error 服务器崩了!代码写错了或服务器内部故障(比如数据库挂了)。 PHP/Python代码报错、服务崩溃
502 Bad Gateway 网关炸了!Nginx后面的服务(比如PHP、Node.js)没响应或挂了。 后端服务没启动、负载过高
503 Service Unavailable 忙不过来了!服务器当前超负荷(比如流量太大)。 高并发抢购、服务器维护中
504 Gateway Timeout 等太久了!Nginx后面的服务处理超时(比如数据库查询卡死)。 后端服务响应慢、网络延迟

Nginx优化方案(牢记)

基础优化

  1. 使用最新稳定版本。Nginx新版本通常会优化性能、修复安全漏洞和提供新特性,因此建议使用最新稳定版。
  2. 选择合适的编译参数。编译时可以去掉不必要的模块,例如:
    1
    2
    3
    4
    5
    ./configure --prefix=/usr/local/nginx \
    --with-http_ss1_module \
    --with-http_v2_module \
    --without-http_autoinde_module \
    --without-http_ssi_module
    减少不必要的模块可以提升Nginx启动速度和运行效率

性能优化

  1. 调整worker进程
  • nginx是基于事件驱动的异步架构,默认worker_processes数量通常为CPU核心数:worker_processes auto;
    也可以手动指定。
  • worker_connections指定每个worker能同时处理的最大链接数建议为10240;
  1. 开启高效事件模型
    1
    2
    3
    4
    events{
    use epoll; #Linux推荐用epoll,FreeBSD可使用kqueue
    worker_connections 1024;
    }
  2. 启用sendfile
    1
    2
    3
    4
    #开启sendfile可以提高文件传输效率
    sendfile on; #减少数据拷贝,提高传输效率
    tcp_nopush on; #减少网络包数量,提高吞吐量
    tcp_nodelay on; #减少TCP延迟,提高小数据包响应速度
  3. 增大缓存和缓冲区
    1
    2
    3
    client_body_buffer_size 512k;
    client_header_buffer_size 32k;
    large_client_header_buffers 4 64k;
    这些参数用于优化大请求体和大请求头的处理,减少频繁的磁盘IO。
  4. 设定合理的Keepalive
    1
    2
    keepalive_timeout 65; # 设定TCP链接保持事件,适当增加可以减少握手开销。
    keepallive_requests 10000; # 限制单个链接的最大请求数,避免长时间链接导致资源耗尽

反向代理优化

  1. 配置缓存,对于静态资源或可缓存的后端响应,可以使用proxy_cache
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=cache_zone:10m max_size=1g inactive=60m;
    #keys_zone=cache_zone:10m 定义10M的缓存索引空间,在内存中
    #inactive=60m 60分钟内未使用的缓存将被清理
    #levels=1:2 缓存文件分两级目录存放,防止单个目录文件太多导致性能下降
    #/var/cache/nginx 缓存文件存放在服务器这个目录下
    #max_size=1g 缓存最多占用1G空间

    server {
    location / {
    proxy_cache cache_zone;
    proxy_cache_valid 200 302 10m;
    proxy_cache_valid 404 1m;
    proxy_pass http://backend;
    }
    }
  2. 启用gzip压缩
    1
    2
    3
    4
    gzip on;
    gzip_type text/plain text/css application/json appllication/javascript image/svg+xml;
    gzip_comp_level 5; #压缩等级,推荐4~6之间
    gzip_min_length 1024; #小于1kb的数据不压缩
  3. 限制请求速率,防止DDOS或恶意攻击
    1
    2
    3
    4
    5
    6
    limit_req_zone $binary_remote_addr zone=one:10m rate=5r/s; #限制最多5次请求
    server{
    location / {
    limit_req zone=one burst=10 nodelay;#允许突发10个请求
    }
    }

负载均衡优化

  1. 选择合适的算法
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    upstream backend {
    least_conn; # 选择连接最少的服务器
    #least_conn;:优先将请求分配给当前连接最少的后端服务器,适合长连接应用
    server backend1.example.com;
    server backend2.example.com;
    }

    #开启https

    server{
    listen 443 ssl;
    ssl_certificate /etc/nginx/ssl/qiuhou.pem;
    ssl_certificate_key /etc/nginx/ssl/qiuhou.key;
    ......
    }

日志监控优化

  1. 关闭不必要的日志
  2. 监控nginx运行状态,访问http://localhost/nginx_status可查看
    1
    2
    3
    4
    5
    6
    7
    8
    server {
    location = /nginx_status {
    stub_status on;#观察运行状态
    access_log off; #关闭访问日志
    allow 127.0.0.1;
    deny all;
    }
    }

安全优化

  1. 隐藏nginx版本信息
    server_tokens off;
  2. 限制请求方法
    1
    2
    3
    if ($request_method !~ ^(GET|POST|HEAD)$){
    return 444;
    }
  3. 保护关键路径
    1
    2
    3
    location ~ ^/(wp-admin|admin|config){
    deny all;
    }

总结

nginx优化可以从多个方面入手

  1. 基础优化:使用最新版本,合理编译参数。
  2. 性能优化:调整worker_processes、sendfile,leepalive等。
  3. 反向代理优化:启用缓存,gzip压缩,限流等。
  4. 负载均衡优化:优化后端分配策略,开启http/2
  5. 日志与监控优化:关闭冗余日志,使用stub_status监控。
  6. 安全优化:隐藏版本号,限制请求方法,保护敏感路径。

Nginx的配置文件中匹配优先级

‘=’ > ‘^~‘ > ‘~/~*‘ > ‘/‘

  1. ‘=‘精确匹配(优先级最高),location=/login,只匹配/login,
  2. ’^~‘前缀匹配(如果匹配,就不再检查正则)
  3. ’~‘或’~*‘正则匹配,~:区分大小写,~*:不区分
  4. ’/‘通用匹配

今天遇到的问题

  1. clone的虚拟机无法上网,已经用nmcli con mod更改过ip,ping 223.5.5.5和百度显示不可达。排查dns,现在/etc/resolve.conf上增加nameserver 223.5.5.5,发现还是不行,然后使用ip route查看网关路由,发现没有默认路由(default via), 添加网关ip,ip route add default via 192.168.146.2 dev ens33;然后就可以了,不过该命令是临时添加的,重启完就没了,要想永久生效,需要写入配置文件,vim /etc/sysconfig/network-scripts/ifcfg-ens33

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    TYPE=Ethernet
    BOOTPROTO=static # 静态IP,若用DHCP则改为dhcp
    IPADDR=192.168.146.133 # 自定义IP
    NETMASK=255.255.255.0 # 子网掩码
    GATEWAY=192.168.146.2 # 网关(即你之前配置的默认路由)
    DNS1=8.8.8.8
    DNS2=114.114.114.114
    NAME=ens33
    DEVICE=ens33
    ONBOOT=yes # 开机自动启动
  2. 在配置动静分离时,使用nginx -t报错,两个报错,一个是在静态location块中没有添加请求头文件proxy_params;一个是请求头文件的存放路径不对,我放在了和nginx的conf文件一个路径下,正确应该放到他的上一级/etc/nginx下。

  3. 在将博客网站改成https时,发现进不去了(域名还没备案完成),根因是域名没有备案完成,不过在配置文件中的listen端口后面要加ssl,然后windows的hosts文件要加域名解析,然后访问的时候在IP后面加443端口号。