Skip to content

APISIX — 高性能 API 网关

架构设计

Apache APISIX 基于 Nginx + LuaJIT,以 etcd 作为配置中心,实现毫秒级动态路由更新。

Client ──► APISIX(数据平面)──► Upstream

         etcd(配置存储)

         APISIX Dashboard / Admin API(控制平面)

APISIX 核心优势:
  - 配置变更实时生效(无需 reload)
  - 插件热加载
  - 支持 WASM 插件
  - 原生 eBPF 支持(实验性)

核心概念

概念说明
Route路由规则,匹配请求并转发
Service上游服务抽象,可被多个 Route 引用
Upstream上游节点集合,支持负载均衡
Plugin插件,附加在 Route/Service/Global 上
ConsumerAPI 消费者,绑定认证凭证
Plugin Config可复用的插件配置组

基础配置

Admin API 操作

bash
# 创建 Upstream
curl -X PUT http://localhost:9180/apisix/admin/upstreams/1 \
  -H "X-API-KEY: edd1c9f034335f136f87ad84b625c8f1" \
  -d '{
    "type": "roundrobin",
    "nodes": {
      "order-service:8080": 1,
      "order-service-2:8080": 1
    },
    "checks": {
      "active": {
        "http_path": "/health",
        "interval": 5,
        "healthy": {"successes": 2},
        "unhealthy": {"http_failures": 3}
      }
    }
  }'

# 创建 Route
curl -X PUT http://localhost:9180/apisix/admin/routes/1 \
  -H "X-API-KEY: edd1c9f034335f136f87ad84b625c8f1" \
  -d '{
    "uri": "/api/orders/*",
    "methods": ["GET", "POST", "PUT", "DELETE"],
    "upstream_id": "1",
    "plugins": {
      "limit-req": {
        "rate": 100,
        "burst": 50,
        "key": "remote_addr"
      },
      "jwt-auth": {}
    }
  }'

声明式配置(apisix.yaml)

yaml
# conf/apisix.yaml(DB-less 模式)
routes:
  - id: order-route
    uri: /api/orders/*
    upstream_id: order-upstream
    plugins:
      jwt-auth: {}
      limit-req:
        rate: 100
        burst: 50
        key: remote_addr

upstreams:
  - id: order-upstream
    type: roundrobin
    nodes:
      - host: order-service
        port: 8080
        weight: 1

consumers:
  - username: mobile-app
    plugins:
      jwt-auth:
        key: mobile-app-key
        secret: my-jwt-secret

#END

插件体系

认证插件

JWT Auth

bash
# 创建 Consumer
curl -X PUT http://localhost:9180/apisix/admin/consumers \
  -d '{
    "username": "mobile-app",
    "plugins": {
      "jwt-auth": {
        "key": "mobile-app-key",
        "secret": "my-jwt-secret",
        "algorithm": "HS256",
        "exp": 86400
      }
    }
  }'

# 获取 JWT Token
curl http://localhost:9180/apisix/plugin/jwt/sign?key=mobile-app-key

# 请求时携带 Token
curl -H "Authorization: Bearer <token>" http://localhost:9080/api/orders

OAuth 2.0

bash
curl -X PUT http://localhost:9180/apisix/admin/routes/1 \
  -d '{
    "uri": "/api/orders/*",
    "plugins": {
      "openid-connect": {
        "client_id": "apisix",
        "client_secret": "secret",
        "discovery": "https://keycloak:8080/realms/myrealm/.well-known/openid-configuration",
        "redirect_uri": "https://api.example.com/callback",
        "scope": "openid profile"
      }
    }
  }'

流量控制插件

limit-count(计数限流)

json
{
  "limit-count": {
    "count": 100,
    "time_window": 60,
    "key": "consumer_name",
    "key_type": "var",
    "rejected_code": 429,
    "rejected_msg": "Too many requests",
    "policy": "redis",
    "redis_host": "redis",
    "redis_port": 6379
  }
}

traffic-split(流量分割/灰度)

json
{
  "traffic-split": {
    "rules": [
      {
        "weighted_upstreams": [
          {
            "upstream": {
              "nodes": {"order-v2:8080": 1},
              "type": "roundrobin"
            },
            "weight": 10
          },
          {
            "weight": 90
          }
        ]
      }
    ]
  }
}

可观测性插件

json
{
  "prometheus": {},
  "zipkin": {
    "endpoint": "http://zipkin:9411/api/v2/spans",
    "sample_ratio": 0.1
  },
  "skywalking": {
    "sample_ratio": 1
  },
  "http-logger": {
    "uri": "http://log-collector:8080/logs",
    "batch_max_size": 1000,
    "inactive_timeout": 5
  }
}

WASM 插件

APISIX 支持用 Rust/Go/C++ 编写 WASM 插件:

rust
// Rust WASM 插件示例
use proxy_wasm::traits::*;
use proxy_wasm::types::*;

struct MyPlugin;

impl HttpContext for MyPlugin {
    fn on_http_request_headers(&mut self, _: usize, _: bool) -> Action {
        // 添加请求头
        self.set_http_request_header("X-Custom-Header", Some("from-wasm"));
        Action::Continue
    }
}
yaml
# 加载 WASM 插件
wasm:
  plugins:
    - name: my-plugin
      priority: 7999
      file: /path/to/plugin.wasm

Kubernetes Ingress

yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: order-ingress
  annotations:
    kubernetes.io/ingress.class: apisix
    k8s.apisix.apache.org/sslredirect: "true"
    k8s.apisix.apache.org/enable-cors: "true"
spec:
  rules:
    - host: api.example.com
      http:
        paths:
          - path: /orders
            pathType: Prefix
            backend:
              service:
                name: order-service
                port:
                  number: 8080

---
# ApisixRoute CRD(更强大)
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
  name: order-route
spec:
  http:
    - name: order-rule
      match:
        hosts:
          - api.example.com
        paths:
          - /orders/*
      backends:
        - serviceName: order-service
          servicePort: 8080
          weight: 90
        - serviceName: order-service-v2
          servicePort: 8080
          weight: 10
      plugins:
        - name: limit-req
          enable: true
          config:
            rate: 100
            burst: 50
            key: remote_addr

故障处理案例

案例一:etcd 连接失败导致配置无法更新

现象:Admin API 返回 500,路由配置无法更新。

排查

bash
# 检查 etcd 连接
curl http://localhost:9090/v1/healthcheck

# 查看 APISIX 错误日志
tail -f /usr/local/apisix/logs/error.log | grep etcd

解决

  • 检查 etcd 集群健康状态
  • 检查 APISIX 配置中的 etcd 地址
  • APISIX 有本地缓存,etcd 短暂不可用不影响流量转发

案例二:插件执行顺序问题

现象:认证插件在限流插件之后执行,导致未认证请求也消耗限流配额。

解决:APISIX 插件按 priority 排序执行,priority 越大越先执行:

常用插件优先级:
  real-ip: 23000
  jwt-auth: 2510
  key-auth: 2500
  limit-req: 1001
  limit-count: 1002
  proxy-rewrite: 1008

认证插件(2500+)默认在限流插件(1000+)之前执行,无需手动调整。

案例三:上游健康检查误判

现象:健康的上游节点被标记为不健康,流量全部打到少数节点。

解决

bash
# 查看上游健康状态
curl http://localhost:9180/apisix/admin/upstreams/1

# 手动恢复节点
curl -X PATCH http://localhost:9180/apisix/admin/upstreams/1 \
  -d '{"nodes": {"order-service:8080": 1}}'

# 调整健康检查阈值(减少误判)
{
  "checks": {
    "active": {
      "interval": 5,
      "healthy": {"successes": 3},      # 连续3次成功才标记健康
      "unhealthy": {"http_failures": 5}  # 连续5次失败才标记不健康
    }
  }
}

APISIX vs Kong 对比

维度APISIXKong
性能更高(etcd 动态配置,无 reload)
配置存储etcdPostgreSQL / DB-less
插件语言Lua / WASM / Go / PythonLua / Go
社区Apache 孵化,活跃商业公司主导
控制台APISIX Dashboard(开源)Kong Manager(部分商业)
云原生原生 K8s 支持Kong Ingress Controller
适用场景高性能、云原生企业级、插件生态丰富

PaaS 中间件生态系统深度学习文档