0

0

微服务架构下 Apache 作为 API 网关的限流设计

月夜之吻

月夜之吻

发布时间:2025-07-14 14:35:01

|

905人浏览过

|

来源于php中文网

原创

apache作为api网关的限流设计核心在于保护后端服务,避免突发流量导致雪崩;1.使用mod_ratelimit模块可基于请求速率进行简单限流,如配置每分钟最多60个请求;2.结合lua脚本和redis实现更灵活的ip级限流,通过计数和过期机制控制流量;3.选择合适算法如令牌桶应对突发流量、漏桶平滑流量或滑动窗口提高精度;4.动态调整策略可通过配置中心、api接口或监控系统实时更新限流参数;5.处理被限流请求时可返回429错误码、retry-after提示、排队等待或降级响应以平衡用户体验与系统负载。

微服务架构下 Apache 作为 API 网关的限流设计

微服务架构下,Apache 作为 API 网关的限流设计核心在于保护后端服务,避免因突发流量导致服务雪崩。 通过配置 Apache 的模块,例如 mod_ratelimitmod_qos,可以实现基于请求速率、连接数等多种维度的限流策略。 关键是根据实际业务需求和后端服务承受能力,灵活调整限流参数。

解决方案

在微服务架构中,Apache 作为 API 网关的限流设计,需要综合考虑性能、灵活性和可维护性。 下面介绍一种基于 mod_ratelimit 和 Lua 脚本的限流方案,并结合实际场景进行说明。

  1. 安装和配置 mod_ratelimit

首先,确保 Apache 已经安装了 mod_ratelimit 模块。 如果没有安装,可以通过以下命令安装(以 Debian/Ubuntu 为例):

   sudo apt-get update
   sudo apt-get install libapache2-mod-ratelimit
   sudo a2enmod ratelimit
   sudo systemctl restart apache2

然后,在 Apache 的配置文件中启用 mod_ratelimit。 例如,在 VirtualHost 配置中添加以下内容:

   
       ServerName example.com

       
           Options Indexes FollowSymLinks
           AllowOverride All
           Require all granted
       

       
           # 启用限流,每分钟最多允许 60 个请求
           
               Ratelimit on
               RatelimitRequests 60
               RatelimitInterval 60
           
       

       ErrorLog ${APACHE_LOG_DIR}/error.log
       CustomLog ${APACHE_LOG_DIR}/access.log combined
   

上述配置表示对整个网站进行限流,每分钟最多允许 60 个请求。

  1. 使用 Lua 脚本进行更灵活的限流

mod_ratelimit 提供的限流方式比较简单,如果需要更灵活的限流策略,可以使用 Lua 脚本结合 Apache 的 mod_lua 模块。

首先,安装 mod_lua 模块:

   sudo apt-get update
   sudo apt-get install libapache2-mod-lua
   sudo a2enmod lua
   sudo systemctl restart apache2

然后,创建一个 Lua 脚本,例如 ratelimit.lua,用于实现限流逻辑:

   -- ratelimit.lua

   local redis = require "redis"

   -- Redis 连接配置
   local redis_host = "127.0.0.1"
   local redis_port = 6379
   local redis_db = 0

   -- 限流配置
   local limit_requests = 100  -- 每分钟最多允许的请求数
   local limit_interval = 60   -- 时间窗口,单位:秒

   -- 获取客户端 IP 地址
   local client_ip = ngx.var.remote_addr

   -- Redis key,用于存储客户端 IP 的请求计数
   local redis_key = "ratelimit:" .. client_ip

   -- 连接 Redis
   local red = redis:new()
   red:set_timeout(1000) -- 连接超时时间,单位:毫秒
   local ok, err = red:connect(redis_host, redis_port)
   if not ok then
       ngx.log(ngx.ERR, "failed to connect to redis: ", err)
       return ngx.exit(500)
   end

   -- 获取当前请求计数
   local current_count, err = red:get(redis_key)
   if not current_count then
       current_count = 0
   end

   -- 判断是否超过限流
   if tonumber(current_count) >= limit_requests then
       ngx.status = ngx.HTTP_TOO_MANY_REQUESTS
       ngx.say("Too Many Requests")
       ngx.exit(ngx.HTTP_TOO_MANY_REQUESTS)
   end

   -- 增加请求计数
   local new_count, err = red:incr(redis_key)
   if not new_count then
       ngx.log(ngx.ERR, "failed to increment redis key: ", err)
       return ngx.exit(500)
   end

   -- 设置过期时间,确保计数器在时间窗口后自动过期
   red:expire(redis_key, limit_interval)

   -- 关闭 Redis 连接
   local ok, err = red:close()
   if not ok then
       ngx.log(ngx.ERR, "failed to close redis: ", err)
   end

这个 Lua 脚本使用 Redis 存储客户端 IP 的请求计数,并设置过期时间,实现基于 IP 的限流。

接下来,在 Apache 的 VirtualHost 配置中添加以下内容,启用 Lua 脚本:

   
       ServerName example.com

       
           Options Indexes FollowSymLinks
           AllowOverride All
           Require all granted
       

       
           # 启用 Lua 脚本进行限流
           
               LuaHookPerRequest /path/to/ratelimit.lua
           
       

       ErrorLog ${APACHE_LOG_DIR}/error.log
       CustomLog ${APACHE_LOG_DIR}/access.log combined
   

确保将 /path/to/ratelimit.lua 替换为实际的 Lua 脚本路径。

  1. 测试限流

配置完成后,重启 Apache 服务:

   sudo systemctl restart apache2

然后,使用 curl 或其他工具,在短时间内发送大量请求到 example.com,观察是否会返回 429 Too Many Requests 错误。

如何选择合适的限流算法?

选择合适的限流算法取决于具体的应用场景和需求。 常见的限流算法包括:

  • 令牌桶算法 (Token Bucket): 以恒定速率生成令牌,请求只有在拿到令牌后才能被处理。 适合应对突发流量,因为桶中可以存储一定数量的令牌。

    第一团购
    第一团购

    第一团购软件是基于Web应用的B/S架构的团购网站建设解决方案的建站系统。它可以让用户高效、快速、低成本的构建个性化、专业化、强大功能的团购网站。从技术层面来看,本程序采用目前软件开发IT业界较为流行的ASP.NET和SQLSERVER2000数据库开发技术架构。从功能层面来看,前台首页每天显示一个服务或插产品的限时限最低成团人数的团购项目,具有邮件订阅,好友邀请,人人网、开心网、新浪微博、MSN

    下载
  • 漏桶算法 (Leaky Bucket): 请求先进入漏桶,然后以恒定速率从漏桶中流出。 适合平滑流量,防止后端服务被压垮。

  • 固定窗口计数器算法 (Fixed Window Counter): 在固定的时间窗口内,记录请求的数量。 简单易实现,但可能存在临界问题。

  • 滑动窗口计数器算法 (Sliding Window Counter): 将时间窗口划分为多个小窗口,分别记录每个小窗口内的请求数量。 可以更精确地限制流量,避免临界问题。

例如,如果需要应对突发流量,可以选择令牌桶算法; 如果需要平滑流量,可以选择漏桶算法; 如果对精度要求不高,可以选择固定窗口计数器算法; 如果对精度要求较高,可以选择滑动窗口计数器算法。 在实际应用中,还可以将多种算法结合使用,以达到更好的限流效果。

如何动态调整限流策略?

动态调整限流策略对于应对不断变化的流量模式至关重要。 可以通过以下几种方式实现动态调整:

  • 使用配置中心: 将限流配置存储在配置中心,例如 Consul、Etcd 或 ZooKeeper。 当配置发生变化时,Apache 可以从配置中心动态拉取最新的配置。

  • 使用 API 接口: 提供 API 接口,允许管理员或自动化工具动态调整限流参数。 Apache 可以定期或在接收到特定事件时,调用 API 接口获取最新的配置。

  • 使用监控系统: 集成监控系统,例如 Prometheus 或 Grafana,监控 Apache 的性能指标和后端服务的负载情况。 当监控系统检测到异常情况时,可以自动调整限流策略。

例如,可以使用 Consul 存储限流配置,并使用 Lua 脚本从 Consul 中动态拉取配置。 当 Consul 中的配置发生变化时,Lua 脚本可以自动更新限流参数。

如何处理被限流的请求?

处理被限流的请求需要考虑用户体验和系统可用性。 常见的处理方式包括:

  • 返回错误码: 返回 429 Too Many Requests 错误码,告知客户端请求被限流。 客户端可以根据错误码进行重试。

  • 返回重试提示: 返回 Retry-After 头部,告知客户端在多长时间后可以重试。

  • 排队等待: 将被限流的请求放入队列中,等待后续处理。 这种方式可能会增加请求的延迟。

  • 降级处理: 对于非核心业务,可以进行降级处理,例如返回缓存数据或简化响应内容。

例如,可以返回 429 Too Many Requests 错误码,并添加 Retry-After 头部,告知客户端在 60 秒后可以重试:

HTTP/1.1 429 Too Many Requests
Content-Type: application/json
Retry-After: 60

{
  "message": "Too Many Requests"
}

客户端可以根据 Retry-After 头部的值,在 60 秒后重试请求。

相关专题

更多
curl_exec
curl_exec

curl_exec函数是PHP cURL函数列表中的一种,它的功能是执行一个cURL会话。给大家总结了一下php curl_exec函数的一些用法实例,这个函数应该在初始化一个cURL会话并且全部的选项都被设置后被调用。他的返回值成功时返回TRUE, 或者在失败时返回FALSE。

425

2023.06.14

linux常见下载安装工具
linux常见下载安装工具

linux常见下载安装工具有APT、YUM、DNF、Snapcraft、Flatpak、AppImage、Wget、Curl等。想了解更多linux常见下载安装工具相关内容,可以阅读本专题下面的文章。

174

2023.10.30

登录token无效
登录token无效

登录token无效解决方法:1、检查token的有效期限,如果token已经过期,需要重新获取一个新的token;2、检查token的签名,如果签名不正确,需要重新获取一个新的token;3、检查密钥的正确性,如果密钥不正确,需要重新获取一个新的token;4、使用HTTPS协议传输token,建议使用HTTPS协议进行传输 ;5、使用双因素认证,双因素认证可以提高账户的安全性。

6085

2023.09.14

登录token无效怎么办
登录token无效怎么办

登录token无效的解决办法有检查Token是否过期、检查Token是否正确、检查Token是否被篡改、检查Token是否与用户匹配、清除缓存或Cookie、检查网络连接和服务器状态、重新登录或请求新的Token、联系技术支持或开发人员等。本专题为大家提供token相关的文章、下载、课程内容,供大家免费下载体验。

804

2023.09.14

token怎么获取
token怎么获取

获取token值的方法:1、小程序调用“wx.login()”获取 临时登录凭证code,并回传到开发者服务器;2、开发者服务器以code换取,用户唯一标识openid和会话密钥“session_key”。想了解更详细的内容,可以阅读本专题下面的文章。

1060

2023.12.21

token什么意思
token什么意思

token是一种用于表示用户权限、记录交易信息、支付虚拟货币的数字货币。可以用来在特定的网络上进行交易,用来购买或出售特定的虚拟货币,也可以用来支付特定的服务费用。想了解更多token什么意思的相关内容可以访问本专题下面的文章。

1224

2024.03.01

硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

1018

2023.10.19

PHP接口编写教程
PHP接口编写教程

本专题整合了PHP接口编写教程,阅读专题下面的文章了解更多详细内容。

63

2025.10.17

Golang gRPC 服务开发与Protobuf实战
Golang gRPC 服务开发与Protobuf实战

本专题系统讲解 Golang 在 gRPC 服务开发中的完整实践,涵盖 Protobuf 定义与代码生成、gRPC 服务端与客户端实现、流式 RPC(Unary/Server/Client/Bidirectional)、错误处理、拦截器、中间件以及与 HTTP/REST 的对接方案。通过实际案例,帮助学习者掌握 使用 Go 构建高性能、强类型、可扩展的 RPC 服务体系,适用于微服务与内部系统通信场景。

8

2026.01.15

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
ASP 教程
ASP 教程

共34课时 | 3.6万人学习

微信小程序开发之API篇
微信小程序开发之API篇

共15课时 | 1.2万人学习

进程与SOCKET
进程与SOCKET

共6课时 | 0.3万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号