概述
本文将介绍如何使用HAProxy作为API网关,实现请求路由和限流功能。HAProxy作为高性能的负载均衡器,通过合理配置可以轻松转型为功能强大的API网关。
HAProxy作为API网关
API网关是客户端与后端服务群之间的中间层,本质上是一个反向代理。它负责将API调用路由到对应服务,同时承担安全防护、流量监控、负载均衡等核心职责。
HAProxy 是一款开源的软件负载均衡器和应用交付控制器,以其高性能和稳定性在业界广泛应用。接下来我们将通过配置让HAProxy扮演API网关的角色。
使用HAProxy进行HTTP API路由
API网关的核心功能之一是根据请求特征(路径、域名、数据格式等)将HTTP请求路由到目标服务器。
基本配置
HAProxy的基础配置是作为负载均衡器。以下配置定义了前端(frontend)和后端(backend):
frontend haproxy_as_api_gateway
bind 127.0.0.1:80
default_backend load_balancing
backend load_balancer
server server1 127.0.0.1:8080
server server2 127.0.0.1:8081
配置说明:
- 定义了两个后端服务器用于负载均衡
- 客户端访问
127.0.0.1:80
时,HAProxy会将请求路由到后端服务器 - 后端服务器分别监听
127.0.0.1:8080
和127.0.0.1:8081
后续我们将基于此配置扩展API网关功能。
按路径分离请求
在微服务架构中,API网关需要根据请求路径将调用路由到对应服务。
假设我们的在线商店有两个接口:
- 订单接口:
127.0.0.1:80/order
- 发票接口:
127.0.0.1:80/invoicing
对应部署了两个微服务:
- 订单服务:
127.0.0.1:8080
- 发票服务:
127.0.0.1:8081
配置如下:
frontend haproxy_as_api_gateway
bind 127.0.0.1:80
acl PATH_order path_beg -i /order
acl PATH_invoicing path_beg -i /invoicing
use_backend order_service if PATH_order
use_backend invoicing_service if PATH_invoicing
backend order_service
server server1 127.0.0.1:8080
backend invoicing_service
server server1 127.0.0.1:8081
关键点:
acl
定义访问控制列表(ACL),匹配请求路径use_backend
根据路径条件选择后端服务/order
路径请求路由到订单服务,/invoicing
路径请求路由到发票服务
当订单服务负载过高时,可添加新服务器实现负载均衡:
backend order_service
server server1 127.0.0.1:8080
server server2 127.0.0.1:8090
这样既实现了服务路由,又完成了负载均衡,简单粗暴但有效。
按域名分离请求
实际生产中常需根据域名隔离API访问权限。继续在线商店案例:
- 消费者网站:
127.0.0.1
- 运营门户:
127.0.0.2
需求:
- 消费者只能访问订单接口
- 运营团队只能访问发票接口
配置实现:
frontend haproxy_as_api_gateway
bind :80
acl consumerapi_host req.hdr(Host) -i -m dom 127.0.0.1
acl operationapi_host req.hdr(Host) -i -m dom 127.0.0.2
acl PATH_order path_beg -i /order
acl PATH_invoicing path_beg -i /invoicing
use_backend order_service if consumerapi_host PATH_order
use_backend invoicing_service if operationapi_host PATH_invoicing
backend order_service
server server1 127.0.0.1:8080
server server2 127.0.0.1:8090
backend invoicing_service
server server1 127.0.0.1:8081
路由规则:
- 仅当请求来自
127.0.0.1
且路径为/order
时,路由到订单服务 - 仅当请求来自
127.0.0.2
且路径为/invoicing
时,路由到发票服务 - 其他组合将被拒绝(如消费者访问发票接口)
按数据格式分离请求
有时需要根据请求数据格式(如JSON/XML)路由到不同服务端点。扩展订单服务场景:
frontend haproxy_as_api_gateway
bind :80
acl consumerapi_host req.hdr(Host) -i -m dom 127.0.0.1
acl operationapi_host req.hdr(Host) -i -m dom 127.0.0.2
acl api_json req.hdr(Content-Type) -i -m dom application/json
acl api_xml req.hdr(Content-Type) -i -m dom application/xml
acl PATH_order path_beg -i /order
acl PATH_invoicing path_beg -i /invoicing
use_backend order_service_json if consumerapi_host api_json PATH_order
use_backend order_service_xml if consumerapi_host api_xml PATH_order
use_backend invoicing_service if operationapi_host PATH_invoicing
backend order_service_json
server server1 127.0.0.1:8080
backend order_service_xml
server server2 127.0.0.1:8090
backend invoicing_service
server server1 127.0.0.1:8081
实现逻辑:
- 通过
Content-Type
请求头区分数据格式 - JSON请求路由到
127.0.0.1:8080
- XML请求路由到
127.0.0.1:8090
- 发票服务保持不变
这种配置在需要兼容多版本API或特殊客户端时特别有用。
限流
限流是保护后端服务的关键手段。假设我们要限制订单接口:10秒内最多100次请求,超过则判定为异常流量。
配置步骤
创建限速配置文件
path_param_rates.map
:/order 100
使用HAProxy的Stick Table实现计数(Stick Table是HAProxy内置的高性能内存存储):
frontend haproxy_as_api_gateway
bind :80
stick-table type string size 1m expire 10s store http_rate_limiting
http-request track-sc0 base32+src
http-request set-var(req.rate_limit) path,map_beg(path_param_rates.map,20)
http-request set-var(req.request_rate) base32+src,table_http_rate_limiting()
acl rate_abuse var(req.rate_limit),sub(req.request_rate) lt 0
http-request deny deny_status 429 if rate_abuse
acl consumerapi_host req.hdr(Host) -i -m dom 127.0.0.1
acl operationapi_host req.hdr(Host) -i -m dom 127.0.0.2
acl consumerapi_json req.hdr(Content-Type) -i -m dom application/json
acl consumerapi_xml req.hdr(Content-Type) -i -m dom application/xml
acl PATH_order path_beg -i /order
acl PATH_invoicing path_beg -i /invoicing
use_backend order_service_json if consumerapi_host consumerapi_json PATH_order
use_backend order_service_xml if consumerapi_host consumerapi_xml PATH_order
use_backend invoicing_service if operationapi_host PATH_invoicing
backend order_service_json
server server1 127.0.0.1:8080
backend order_service_xml
server server2 127.0.0.1:8090
backend invoicing_service
server server1 127.0.0.1:8081
限流机制解析:
- 创建Stick Table
http_rate_limiting
,设置10秒过期时间 - 跟踪客户端请求频率(
base32+src
哈希处理客户端IP) - 从配置文件读取路径对应的限流阈值(
/order
为100) - 计算剩余配额:
阈值 - 当前请求数
- 当剩余配额小于0时,返回429状态码(Too Many Requests)
效果: 10秒内超过100次订单请求将触发限流,有效防止恶意刷单或突发流量压垮服务。
结论
本文通过HAProxy实现了API网关的核心功能:
- 智能路由:支持按路径、域名、数据格式等多种维度路由
- 流量控制:基于Stick Table实现高效限流
- 负载均衡:原生支持服务扩展
HAProxy配置简洁高效,特别适合作为轻量级API网关。生产环境中建议结合日志监控和健康检查进一步完善架构,避免踩坑。