概述

本文将介绍如何使用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:8080127.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次请求,超过则判定为异常流量。

配置步骤

  1. 创建限速配置文件 path_param_rates.map

    /order 100
    
  2. 使用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

限流机制解析:

  1. 创建Stick Table http_rate_limiting,设置10秒过期时间
  2. 跟踪客户端请求频率(base32+src 哈希处理客户端IP)
  3. 从配置文件读取路径对应的限流阈值(/order 为100)
  4. 计算剩余配额:阈值 - 当前请求数
  5. 当剩余配额小于0时,返回429状态码(Too Many Requests)

效果: 10秒内超过100次订单请求将触发限流,有效防止恶意刷单或突发流量压垮服务。

结论

本文通过HAProxy实现了API网关的核心功能:

  • 智能路由:支持按路径、域名、数据格式等多种维度路由
  • 流量控制:基于Stick Table实现高效限流
  • 负载均衡:原生支持服务扩展

HAProxy配置简洁高效,特别适合作为轻量级API网关。生产环境中建议结合日志监控和健康检查进一步完善架构,避免踩坑。


原始标题:Using HAProxy as an API Gateway for Routing and Rate Limiting | Baeldung