Nginx限流配置实战:保护你的个人项目

Nginx限流配置实战:保护你的个人项目

前段时间我的个人博客上线后,有一天突然访问特别慢,一看服务器日志,好家伙------被爬虫疯狂扫接口,一分钟请求了几千次。

作为一个99元低配ECS,哪经得起这么折腾。赶紧把Nginx限流配上了,问题解决。

今天就把Nginx限流的几种常用配置分享出来,希望对你有帮助。


一、为什么要限流

个人项目上线后,你可能会遇到这些情况:

  • 爬虫疯狂抓取:把你的文章接口当API调
  • 恶意刷接口:有人用脚本扫你的登录接口
  • 瞬时高并发:文章突然火了,大量用户同时访问
  • 资源耗尽:低配ECS扛不住大量并发请求

限流不是为了让用户用不了,而是保护你的服务器不被拖垮。合理的限流配置,能让有限的资源服务好真正的用户。

二、Nginx限流基础配置

Nginx限流主要靠两个模块:limit_req(请求频率限制)和 limit_conn(并发连接限制)。

2.1 限制请求频率

nginx 复制代码
# 在 http 块定义限流区域
http {
    # 定义一个名为 "mylimit" 的限流区域
    # 10m 表示存储10MB的客户端IP信息
    # rate=1r/s 表示每秒只允许1个请求
    limit_req_zone $binary_remote_addr zone=mylimit:10m rate=1r/s;
    
    server {
        location /api/ {
            # 应用限流
            # burst=5 表示允许超过限制的5个请求排队
            # nodelay 表示排队请求不延迟处理
            limit_req zone=mylimit burst=5 nodelay;
            
            proxy_pass http://localhost:8083;
        }
    }
}

参数说明:

参数 作用
rate=1r/s 每秒1个请求,超过的会被拒绝
burst=5 允许突发5个请求排队
nodelay 排队的请求不延迟处理
10m 存储10MB的IP信息,够存几万个IP了

2.2 限制并发连接数

nginx 复制代码
http {
    # 定义连接限制区域
    limit_conn_zone $binary_remote_addr zone=connlimit:10m;
    
    server {
        location /api/ {
            # 每个IP最多10个并发连接
            limit_conn connlimit 10;
            
            # 超时的请求断开
            limit_conn_status 503;
        }
    }
}

三、实际场景配置

场景1:保护文章接口

博客的文章列表和详情接口是爬虫最喜欢抓的:

nginx 复制代码
http {
    # 文章接口限流:每秒2个请求
    limit_req_zone $binary_remote_addr zone=articles:10m rate=2r/s;
    
    server {
        location ~ ^/api/posts {
            limit_req zone=articles burst=10 nodelay;
            proxy_pass http://localhost:8083;
        }
    }
}

场景2:保护登录接口

登录接口更要严格限流,防止暴力破解:

nginx 复制代码
http {
    # 登录接口限流:每分钟5个请求
    limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;
    
    server {
        location /api/auth/login {
            limit_req zone=login burst=3 nodelay;
            # 返回429状态码
            limit_req_status 429;
            proxy_pass http://localhost:8083;
        }
    }
}

场景3:限制某个目录的下载

如果你的网站有文件下载功能:

nginx 复制代码
http {
    limit_conn_zone $binary_remote_addr zone=download:10m;
    
    server {
        location /download/ {
            # 每个IP同时只能下载1个文件
            limit_conn download 1;
            # 限制下载速度为 500KB/s
            limit_rate 500k;
        }
    }
}

四、白名单配置

有时候需要给特定IP(比如你自己)放行:

nginx 复制代码
http {
    # 创建一个变量,默认为空
    geo $limited {
        default 1;
        # 你自己的IP不限流
        你的服务器IP 0;
        你的家庭宽带IP 0;
    }
    
    # 只在 $limited=1 时限流
    limit_req_zone $binary_remote_addr zone=api:10m rate=1r/s;
    
    server {
        location /api/ {
            if ($limited) {
                limit_req zone=api burst=5 nodelay;
            }
            proxy_pass http://localhost:8083;
        }
    }
}

五、限流后的友好提示

当用户被限流时,Nginx默认返回503,但你可以自定义返回内容,让体验更好:

nginx 复制代码
server {
    # 自定义限流返回
    error_page 429 /429.html;
    
    location = /429.html {
        root /usr/share/nginx/html;
        internal;
    }
    
    # 或者返回JSON格式
    error_page 429 @rate_limit_json;
    location @rate_limit_json {
        default_type application/json;
        return 200 '{"code":429,"message":"请求太频繁,请稍后再试"}';
    }
}

六、验证限流效果

配置完后,用 curl 测试一下:

bash 复制代码
# 快速发送10个请求,看有几个被限流
for i in $(seq 1 10); do
  curl -s -o /dev/null -w "%{http_code}\n" http://你的域名/api/posts
done

正常情况下你会看到一部分返回 200,一部分返回 429(被限流了)。

七、总结

Nginx限流是保护个人项目最简单有效的手段之一,配置起来也就几行代码,但效果立竿见影。

我的云深不知处博客配置了限流之后,再也没被爬虫打趴过。如果你也把个人项目部署在某云ECS上,建议第一时间配上限流。

如果你还没有服务器,可以看看某云的低至9.9元ECS活动,买个低配的先练手。新用户还有85折首购优惠,几十块钱就能跑一年个人项目,够用了。

如果你还没有服务器或者其它个人开发产品,点击「独立开发者的省钱攻略」获取更多福利优惠。


关于作者:无羡,独立开发者,专注AI应用开发。

📌 分类:全栈开发

👉 关注我获取更多技术分享

👉 个人博客:云深不知处

👉 独立开发省钱攻略:查看详情

👉 体验我的AI产品:一纸云深

如果这篇文章对你有帮助,欢迎点赞、收藏、关注,你的支持是我持续创作的动力!

点击「阅读原文」查看我的独立开发笔记


👉 点击查看我的个人介绍

👉 点击查看我的小红书主页