【架构实战】API网关架构设计(Kong/APISIX)
·
一、为什么需要API网关
在微服务架构中,客户端直接调用后端服务会带来诸多问题:
- 客户端复杂度高:需要知道所有服务地址,调用逻辑复杂
- 横切关注点重复:每个服务都要实现认证、限流、日志
- 安全风险:后端服务直接暴露,存在安全漏洞
- 难以统一治理:无法统一监控、限流、降级
API网关作为统一入口:
- 路由转发:请求路由到后端服务
- 负载均衡:多实例负载
- 认证授权:统一身份认证
- 限流熔断:流量控制
- 日志监控:请求链路追踪
二、Kong网关实战
1. 安装部署
Docker方式:
# 创建网络
docker network create kong-net
# 启动PostgreSQL(Kong的数据库)
docker run -d \
--name kong-database \
--network=kong-net \
-p 5432:5432 \
-e "POSTGRES_USER=kong" \
-e "POSTGRES_DB=kong" \
-e "POSTGRES_PASSWORD=kong" \
postgres:13
# 初始化Kong数据库
docker run --rm \
--network=kong-net \
-e "KONG_DATABASE=postgres" \
-e "KONG_PG_HOST=kong-database" \
-e "KONG_PG_PASSWORD=kong" \
-e "KONG_PROXY_ACCESS_LOG=/dev/stdout" \
-e "KONG_ADMIN_ACCESS_LOG=/dev/stdout" \
kong:latest kong migrations bootstrap
# 启动Kong
docker run -d \
--name kong \
--network=kong-net \
-e "KONG_DATABASE=postgres" \
-e "KONG_PG_HOST=kong-database" \
-e "KONG_PG_PASSWORD=kong" \
-e "KONG_PROXY_LISTEN=0.0.0.0:8000" \
-e "KONG_ADMIN_LISTEN=0.0.0.0:8001" \
-p 8000:8000 \
-p 8443:8443 \
-p 8001:8001 \
-p 8444:8444 \
kong:latest
DB-less模式(无数据库):
# docker-compose.yml
version: '3'
services:
kong:
image: kong:latest
environment:
KONG_DATABASE: off
KONG_DECLARATIVE_CONFIG: /usr/local/kong/kong.yml
volumes:
- ./kong.yml:/usr/local/kong/kong.yml
ports:
- "8000:8000"
- "8443:8443"
2. 添加服务
方式一:Admin API
# 添加服务
curl -X POST http://localhost:8001/services/ \
--data "name=order-service" \
--data "url=http://order-service:8080" \
--data "protocol=http"
# 添加路由
curl -X POST http://localhost:8001/services/order-service/routes/ \
--data "name=order-route" \
--data "paths[]=/order" \
--data "methods[]=GET" \
--data "methods[]=POST"
# 验证
curl -i http://localhost:8000/order/list
方式二:Declarative配置
# kong.yml
_format_version: "3.0"
services:
- name: order-service
url: http://order-service:8080
routes:
- name: order-route
paths:
- /order
methods:
- GET
- POST
plugins:
- name: rate-limiting
config:
second: 100
policy: local
- name: user-service
url: http://user-service:8080
routes:
- name: user-route
paths:
- /user
plugins:
- name: jwt
3. 插件配置
限流插件:
# 本地限流(每分钟100次)
curl -X POST http://localhost:8001/services/order-service/plugins/ \
--data "name=rate-limiting" \
--data "config.second=100" \
--data "config.minute=1000" \
--data "config.policy=local"
# Redis限流(分布式限流)
curl -X POST http://localhost:8001/services/order-service/plugins/ \
--data "name=rate-limiting" \
--data "config.second=100" \
--data "config.policy=redis" \
--data "config.redis_host=redis-server" \
--data "config.redis_port=6379"
JWT认证插件:
curl -X POST http://localhost:8001/services/user-service/plugins/ \
--data "name=jwt" \
--data "config.uri_param_names=jwt" \
--data "config.cookie_names=token"
CORS跨域插件:
curl -X POST http://localhost:8001/services/order-service/plugins/ \
--data "name=cors" \
--data "config.origins=*" \
--data "config.methods=GET,POST,PUT,DELETE" \
--data "config.headers=Content-Type,Authorization" \
--data "config.exposed_headers=X-Total-Count" \
--data "config.credentials=true" \
--data "config.max_age=3600"
请求转换插件:
curl -X POST http://localhost:8001/services/order-service/plugins/ \
--data "name=request-transformer" \
--data "config.add.headers=X-Kong-Request-ID:$(uuidgen)" \
--data "config.remove.headers=User-Agent"
三、APISIX网关实战
1. 安装部署
Docker Compose方式:
# docker-compose.yml
version: '3'
services:
apisix:
image: apache/apisix:latest
environment:
APISIX_DEFAULTS: |
nginx_config:
worker_rlimit_nofile: 65536
volumes:
- ./apisix/config.yaml:/usr/local/apisix/conf/config.yaml
- ./apisix/routes.yaml:/usr/local/apisix/conf/routes.yaml
ports:
- "9080:9080"
- "9443:9443"
depends_on:
- etcd
etcd:
image: bitnami/etcd:latest
environment:
- ALLOW_NONE_AUTHENTICATION=yes
- ETCD_ADVERTISE_CLIENT_URLS=http://etcd:2379
volumes:
- etcd_data:/bitnami/etcd
volumes:
etcd_data:
2. 配置示例
静态路由配置:
# routes.yaml
routes:
# 订单服务路由
- id: order-service
uri: /order/*
upstream:
type: roundrobin
nodes:
"order-service-1:8080": 1
"order-service-2:8080": 1
plugins:
# 限流
limit-req:
rate: 100
burst: 200
rejected_code: 429
# JWT认证
jwt-auth:
key: user-key
secret: my-secret-key
# 链路追踪
apache-apisix-logger:
host: log-server
port: 5044
# 用户服务路由
- id: user-service
uri: /user/*
upstream:
type: roundrobin
nodes:
"user-service-1:8080": 1
"user-service-2:8080": 1
plugins:
proxy-cache:
cache_key:
- uri
- args
cache_http_status:
- 200
cache_ttl: 60
# 全局插件
plugins:
prometheus:
enabled: true
3. 动态路由(Admin API)
# 添加路由
curl -X PUT http://127.0.0.1:9180/apisix/admin/routes/1 \
-H "X-API-KEY: edd1c9f34a337a9f8ec4e6e4a6e0" \
-H "Content-Type: application/json" \
-d '{
"uri": "/api/*",
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:8080": 1
}
},
"plugins": {
"limit-req": {
"rate": 100,
"burst": 50,
"rejected_code": 503
}
}
}'
4. 基于请求头的路由
-- 自定义路由逻辑
function route_by_header(conf, ctx)
local version = ngx.req.get_headers()["X-Version"]
local service_name = ctx.var.arg_service
if version == "v2" then
return "v2-backend"
elseif version == "v1" then
return "v1-backend"
end
return "default-backend"
end
5. 健康检查
upstreams:
- id: order-service
type: roundrobin
checks:
active:
type: http
http_path: /health
healthy:
interval: 2
successes: 2
unhealthy:
interval: 1
http_failures: 3
passive:
type: http
healthy:
successes: 3
unhealthy:
http_failures: 3
tcp_failures: 3
nodes:
"order-service-1:8080": 100
"order-service-2:8080": 100
四、网关选型对比
功能对比
| 特性 | Kong | APISIX | Nginx |
|---|---|---|---|
| 性能 | 高 | 高 | 最高 |
| 动态配置 | 支持 | 支持 | 需reload |
| 插件生态 | 丰富 | 丰富 | 有限 |
| 学习成本 | 中 | 中 | 低 |
| 配置格式 | Declarative YAML | YAML/JSON | Nginx conf |
| 服务发现 | Consul/Eureka | Consul/Nacos | upstream |
| 限流 | 本地/Redis | 本地/Redis | 需扩展 |
Kong vs APISIX详细对比
| 维度 | Kong | APISIX |
|---|---|---|
| 架构 | PostgreSQL + Nginx | etcd + Nginx |
| 热更新 | 自动 | 自动 |
| 插件执行时机 | 早 | 可配置 |
| 日志格式 | JSON | JSON/CSV |
| Admin API | RESTful | RESTful |
| Dashboard | 官方提供 | 官方提供 |
选型建议
选择Kong的场景:
- 已有PostgreSQL基础设施
- 需要成熟的插件生态
- 团队熟悉Kong配置
选择APISIX的场景:
- 需要更高的性能
- 使用etcd作为配置中心
- 需要更灵活的插件执行时机
选择Nginx的场景:
- 简单的反向代理需求
- 对性能要求极高
- 不需要复杂的功能
五、生产最佳实践
1. 高可用部署
┌─────────────┐
│ 负载均衡 │
└──────┬──────┘
┌──────────────┼──────────────┐
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ Kong 1 │ │ Kong 2 │ │ Kong 3 │
└────┬─────┘ └────┬─────┘ └────┬─────┘
│ │ │
└─────────────┼─────────────┘
▼
┌─────────────────┐
│ PostgreSQL │
│ (主从复制) │
└─────────────────┘
2. 安全配置
# Kong安全插件链
plugins:
# 1. CORS跨域
- name: cors
# 2. IP黑名单
- name: ip-restriction
config:
allow: ["10.0.0.0/8", "172.16.0.0/12"]
deny: []
# 3. 请求限流
- name: rate-limiting
config:
second: 100
policy: redis
# 4. JWT认证
- name: jwt
# 5. 请求大小限制
- name: request-size-limiting
config:
allowed: [10, "10kb"]
3. 监控配置
# Kong监控(Prometheus + Grafana)
plugins:
- name: prometheus
config:
per_consumer: false
# Grafana Dashboard
- panels:
- title: "Kong Request Rate"
targets:
- expr: sum(rate(kong_http_requests_total[5m])) by (service)
- title: "Kong Latency"
targets:
- expr: histogram_quantile(0.99, rate(kong_latency_ms_bucket[5m]))
六、总结
API网关是微服务架构的核心组件:
- 统一入口:简化客户端调用
- 横切关注点:认证、限流、日志统一处理
- 动态配置:无需重启即可更新路由和插件
- 可观测性:完整的请求监控和链路追踪
选型建议:
- 小规模场景:Nginx足够
- 中等规模:Kong或APISIX
- 大规模高性能需求:APISIX
思考题:你们的系统用的是什么API网关?有没有遇到过性能瓶颈?
个人观点,仅供参考
更多推荐




所有评论(0)