1. 从零到一:为什么我们需要一个现代的API网关?
如果你正在构建微服务、管理多个后端应用,或者厌倦了在Nginx配置文件里反复折腾location和upstream,那么你很可能已经听过API网关这个词。但今天我们不谈那些老生常谈的概念,我想从一个更实际的场景说起:去年我接手了一个遗留系统,它由十几个用不同语言写的服务组成,对外暴露的接口散落在各处。每次有新需求,比如要统一加个认证、限流或者把请求转发到新的服务地址,我们都要去改好几个地方的Nginx配置,然后心惊胆战地nginx -s reload。更头疼的是,没有一个集中的地方能看清所有流量的来龙去脉,出了问题只能靠猜和查日志。
这就是我决定引入APISIX的起点。APISIX不是一个简单的反向代理,它是一个动态、实时、高性能的API网关。和传统的Nginx最大区别在于,它的所有路由、插件配置都是通过API动态管理的,无需重启服务。这意味着你可以在毫秒级别内上线一个新的API路由,或者给一批接口全局开启限流,而服务本身毫无感知。对于追求快速迭代和稳定性的团队来说,这种能力是革命性的。
基于热词中提到的“静态路由配置实验”、“默认路由怎么配置”,我能感觉到很多朋友可能还停留在手动配置路由的阶段。APISIX要解决的,正是这种配置僵化、变更成本高的问题。它把路由规则、上游服务、认证、安全、可观测性等能力都抽象成了可通过API操作的对象,让API管理变得像搭积木一样灵活。接下来,我会带你从搭建到实战,完整走一遍APISIX的核心使用流程,你会发现,管理API流量可以如此简单。
2. 搭建基石:部署APISIX与Dashboard的全链路指南
搭建环境是第一步,也是最容易踩坑的一步。网上教程很多,但往往忽略了版本兼容性和生产环境的细节。我会基于当前(以知识截止日期为参考)的稳定版本,给出一个兼顾开发测试与生产部署准备的方案。
2.1 核心组件选型与架构理解
在动手之前,我们先理清几个核心组件和它们之间的关系:
- APISIX (数据平面): 这是处理实际流量的核心网关。它基于Nginx和OpenResty,但通过插件机制扩展了无数功能。它不直接存储配置,而是从“配置中心”拉取。
- etcd (配置中心): APISIX使用etcd作为默认的配置存储和服务发现中心。所有你创建的路由、服务、上游、插件配置,最终都存储在etcd中。APISIX节点会监听etcd的变化,并实时更新自己的路由规则。
- APISIX Dashboard (控制平面): 这是一个可视化的管理界面,让你可以通过Web UI来操作上述所有资源。它本质上是一组RESTful API,你的操作会通过它写入etcd,进而被APISIX读取。
所以,数据流向是:你在Dashboard上点点点 -> Dashboard调用其API -> 配置写入etcd -> APISIX监听etcd并更新内存配置 -> 新流量生效。
注意:对于生产环境,强烈建议将APISIX、etcd、Dashboard部署在不同的节点上,并考虑etcd集群的高可用。对于本地测试或学习,我们可以用Docker Compose一键拉起所有服务,这是最便捷的方式。
2.2 使用Docker Compose快速搭建开发环境
假设你已经安装了Docker和Docker Compose。我们创建一个docker-compose.yml文件。这里的关键是版本匹配和网络配置。
version: "3" services: etcd: image: bitnami/etcd:3.5.9 container_name: apisix-etcd environment: - ALLOW_NONE_AUTHENTICATION=yes - ETCD_ADVERTISE_CLIENT_URLS=http://0.0.0.0:2379 - ETCD_LISTEN_CLIENT_URLS=http://0.0.0.0:2379 ports: - "2379:2379" networks: - apisix-net apisix: image: apache/apisix:3.8.0-debian container_name: apisix-gateway restart: always volumes: - ./apisix_logs:/usr/local/apisix/logs - ./apisix_conf/config.yaml:/usr/local/apisix/conf/config.yaml:ro depends_on: - etcd ports: - "9080:9080" # HTTP 代理端口 - "9091:9091" # Admin API 端口 - "9443:9443" # HTTPS 代理端口 - "9180:9180" # 控制台API端口(apisix-dashboard使用) networks: - apisix-net apisix-dashboard: image: apache/apisix-dashboard:3.0.1-alpine container_name: apisix-dashboard restart: always depends_on: - apisix environment: - APISIX_DASHBOARD_CONF=/usr/local/apisix-dashboard/conf/conf.yaml volumes: - ./dashboard_conf/conf.yaml:/usr/local/apisix-dashboard/conf/conf.yaml:ro ports: - "9000:9000" networks: - apisix-net networks: apisix-net: driver: bridge接下来,我们需要准备APISIX和Dashboard的配置文件。
创建APISIX配置文件 (./apisix_conf/config.yaml):这个文件告诉APISIX去哪里找etcd,以及如何配置自己。
apisix: node_listen: - port: 9080 admin_key: - name: "admin" key: edd1c9f034335f136f87ad84b625c8f1 # 默认的admin key,生产环境务必修改! role: admin deployment: admin: allow_admin: - 0.0.0.0/0 # 允许访问Admin API的IP,生产环境应限制 admin_key_required: true etcd: host: - "http://etcd:2379" # 注意这里用的是Docker服务名`etcd` prefix: "/apisix" timeout: 30创建Dashboard配置文件 (./dashboard_conf/conf.yaml):这个文件告诉Dashboard如何连接etcd和APISIX的Admin API。
conf: listen: host: 0.0.0.0 port: 9000 etcd: endpoints: - "http://etcd:2379" # 同样使用服务名 prefix: "/apisix" apisix: admin_api_url: "http://apisix:9180/apisix/admin" # 指向APISIX容器的Admin API admin_key: "edd1c9f034335f136f87ad84b625c8f1" # 必须和APISIX配置中的admin_key一致 log: level: warn现在,在包含docker-compose.yml的目录下,执行:
docker-compose up -d等待片刻,访问http://localhost:9000即可进入Dashboard(默认用户名/密码:admin/admin)。访问http://localhost:9080是APISIX的代理端口,但目前还没有路由,会返回404。
踩坑点1:网络连接与主机名。在Docker Compose中,服务之间通过服务名(如etcd,apisix)通信。配置文件里必须用服务名,而不是localhost或127.0.0.1,否则容器内无法访问其他服务。
踩坑点2:Admin Key安全。上面的配置使用了默认key,这在公网环境下极其危险。任何人拿到这个key都可以通过Admin API(端口9091)完全控制你的网关。生产环境必须生成一个复杂的key并替换,同时严格限制allow_admin的IP范围。
3. 路由配置实战:从基础转发到高级匹配
路由(Route)是APISIX中最核心的概念,它定义了“什么样的请求”应该被转发到“哪里去”。热词中反复出现“静态路由配置”,在APISIX里,我们配置的是“动态路由”。
3.1 创建你的第一个路由:Hello World
我们首先通过Dashboard创建一个最简单的路由。
- 登录Dashboard,进入“路由”菜单,点击“创建”。
- 基本信息: 给路由起个名字,比如
first-route。 - 请求匹配: 这是路由规则的核心。
- 路径: 输入
/hello。这意味着所有以/hello开头的请求都会匹配这条路由。 - 高级匹配: 可以先留空,我们后续再玩。
- 路径: 输入
- 上游服务: 这里定义请求被转发到哪里。
- 选择“上游”为“新建上游”。
- 上游名称:
my-first-upstream。 - 目标节点: 我们创建一个用于测试的Mock服务。输入
httpbin.org作为主机,端口80。httpbin.org是一个用于HTTP测试的公共服务。 - 权重默认100。
- 插件配置: 暂时不启用任何插件,点击“下一步”。
- 提交: 检查信息后点击“提交”。
现在,访问http://localhost:9080/hello,APISIX会将请求转发到http://httpbin.org/hello,你应该能看到httpbin的响应。访问http://localhost:9080/hello/anything也会被转发到http://httpbin.org/hello/anything。这就是最基本的路由匹配和转发。
3.2 理解路由匹配的优先级与高级规则
如果只有一条路由,很简单。但当你有几十上百条路由时,理解匹配优先级就至关重要。APISIX的路由匹配遵循“更具体的规则优先”原则。
让我们通过Dashboard再创建几条路由来实验:
- 精确匹配路由: 创建路径为
/hello/exact的路由,上游指向另一个测试服务(比如mock.api.com, 这里为了演示,你可以用另一个Mock服务地址,或仍在httpbin但路径不同)。这种完全精确的路径匹配优先级最高。 - 前缀匹配路由: 我们已经有了
/hello。 - 通用匹配路由: 创建路径为
/*的路由,作为兜底。
现在测试:
- 请求
/hello/exact/foo: 匹配/hello(前缀匹配),因为/hello/exact是精确匹配,但/hello/exact/foo不是它,所以降级为前缀匹配/hello。 - 请求
/hello/exact:精确匹配/hello/exact的路由生效。 - 请求
/other: 匹配通用路由/*。
除了路径,路由匹配还可以基于域名(host)、方法(method)、请求头(headers)、查询参数(args)等。例如,你可以创建一条规则:Host: api.example.comANDPath: /v1/*ANDMethod: POST。这在实现API版本化、多租户隔离时非常有用。
实操心得: 在设计路由时,尽量让规则互斥,避免过于宽泛的前缀匹配导致意外流量被错误路由。善用“优先级”字段(在Dashboard的“高级匹配”中),可以手动调整路由的匹配顺序,数字越大优先级越高。对于重要的核心接口,使用精确匹配或Host+精确路径的组合是最稳妥的。
3.3 上游、服务与消费者:厘清核心概念
在创建路由时,你直接绑定了“上游”。但APISIX还有“服务”和“消费者”两个概念,它们是什么关系?
- 上游(Upstream): 定义了一组后端服务节点(负载均衡的目标),以及负载均衡策略(轮询、一致性哈希等)、健康检查等配置。它是物理后端的抽象。
- 服务(Service): 是某类业务功能的抽象,可以绑定一组插件配置(如限流、认证)。一个服务可以关联一个上游。路由可以关联一个服务。这样做的好处是,多个路由(如
/user/*下的所有接口)可以共享同一套上游和插件配置,避免重复配置。 - 消费者(Consumer): 代表API的使用者(用户、应用)。可以为消费者配置身份凭证(如API Key)和专属的插件配置(比如给VIP用户更高的限流额度)。
一个典型的流程是:消费者通过认证插件(如key-auth)识别身份 ->路由根据请求特征匹配 -> 路由关联的服务生效其插件 ->服务指向的上游处理请求并返回。
在Dashboard上,我建议的配置顺序是:先创建上游(定义好后端),再创建服务(绑定上游和通用插件),最后创建路由(绑定服务)。这样逻辑最清晰,也便于维护。
4. 插件生态:为你的API注入超能力
插件是APISIX的灵魂。热词中提到了“vscode git插件”、“translation插件”,APISIX的插件思想类似,都是为核心系统添加可插拔的功能模块。APISIX官方提供了上百个插件,涵盖认证、安全、流量控制、可观测性、请求/响应转换等方方面面。
4.1 认证与安全:从零搭建API防线
我们以最常用的key-auth(API密钥认证)和cors(跨域)插件为例。
场景: 我们希望/user/profile这个接口必须通过API Key才能访问。
操作步骤:
- 创建消费者: 在Dashboard“消费者”菜单中,创建一名消费者,比如叫
app-client。在插件配置中,启用key-auth插件,系统会自动生成一个Key(如auth-key-123),你也可以手动指定。保存。 - 配置路由插件: 找到或创建一条路径为
/user/profile的路由。在它的“插件配置”中,启用key-auth插件。通常只需保持默认配置(header中取Key,名为apikey)即可。 - 测试:
- 不带Key访问
http://localhost:9080/user/profile: 会返回401 Unauthorized和{"message":"Missing API key found in request"}。 - 带Key访问:
curl http://localhost:9080/user/profile -H 'apikey: auth-key-123'。此时请求成功转发到上游。
- 不带Key访问
结合cors插件: 如果这个API需要被浏览器前端调用,还必须解决跨域问题。在同一路由的插件配置中,继续启用cors插件。你可以精细配置允许的源(allow_origins)、方法(allow_methods)、头信息(allow_headers)等。对于开发环境,可以简单配置allow_origins: "*"和allow_credentials: false(注意生产环境不要这样配)。
注意:插件是有执行顺序的。通常认证类插件(如
key-auth,jwt-auth)会优先执行,因为如果认证失败,后续的限流、转发等操作就没有必要了。APISIX内部有默认顺序,一般无需手动调整。
4.2 流量治理:限流与熔断保稳定
当你的API开始承受压力,限流和熔断是保证服务稳定的关键。热词中虽然没有直接提及,但这是API网关的核心场景。
limit-count限流插件: 限制单个客户端在单位时间内的请求次数。
- 在目标路由或服务上启用该插件。
- 关键配置:
count: 允许的请求数。time_window: 时间窗口(秒)。key_type: 限流维度,常用var(变量),配合key使用。key: 例如remote_addr(按客户端IP限流),或consumer_name(按消费者限流)。
- 示例配置:
{"count":100, "time_window":60, "key_type":"var", "key":"remote_addr"}表示每个IP每分钟最多100次请求。超限后返回503 Service Temporarily Unavailable。
proxy-mirror镜像流量插件: 这是线上问题排查的神器。它可以将线上流量复制一份(镜像)发送到另一个测试环境,而不影响主流程。这在复现线上bug、进行压测数据收集时非常有用。配置时只需指定一个host作为镜像目标即可。
实操心得:限流策略的设计。不要一上来就全局限流。建议按业务重要性分层设置:1)对核心登录、支付接口,按用户ID或IP实施严格限流;2)对查询类接口,可以设置较宽松的全局限流;3)对管理后台接口,按消费者或IP白名单控制。同时,一定要在Dashboard或通过日志监控限流触发情况,它可能是攻击的征兆,也可能是自身性能瓶颈的体现。
4.3 日志与可观测性:让流量一目了然
APISIX本身会输出访问日志,但更强大的功能是通过插件将日志推送到中心化系统。
syslog插件: 可以将日志推送到Syslog服务器,便于传统系统集成。http-logger插件: 这是我个人最常用的。它可以将每个请求的详细日志(包括请求头、响应头、上游响应时间等)以JSON格式POST到你指定的一个HTTP接口(比如ELK的Logstash、或自研的日志服务)。
配置http-logger时,你需要提供一个uri。此外,可以配置batch_max_size和inactive_timeout来控制日志批量发送的规则,避免对上游日志服务造成压力。
结合Dashboard监控: APISIX Dashboard内置了简单的监控面板,可以查看QPS、带宽、etcd状态等。但对于深度监控,建议使用prometheus插件暴露Metrics数据,然后由Grafana进行展示。这能让你清晰地看到每个路由的延迟、状态码分布、流量大小,是性能分析和容量规划的基础。
5. 生产环境进阶:配置、调试与排坑指南
将APISIX用于生产环境,除了前面提到的安全配置,还有更多细节需要注意。
5.1 配置文件深度解析与优化
我们之前用的config.yaml是最简配置。生产环境需要关注更多参数:
apisix: node_listen: - port: 9080 enable_admin: true admin_key: - name: "admin" key: your_super_strong_and_secret_key_here # 必须修改! role: admin config_center: etcd # 配置中心类型 router: http: radixtree_uri # 路由匹配算法,radixtree性能很好 stream_proxy: # 如果需要代理TCP/UDP流量,在此配置 tcp: - addr: 9100 deployment: role: traditional # 角色:traditional(传统)或data_plane(数据平面,配合控制平面) role_traditional: config_provider: etcd admin: allow_admin: # 强烈建议指定IP白名单,如公司的运维网络IP段 - 10.0.0.0/8 - 192.168.1.0/24 admin_key_required: true etcd: host: - "http://etcd-node1:2379" - "http://etcd-node2:2379" - "http://etcd-node3:2379" # 生产环境etcd集群 prefix: "/apisix" timeout: 30 plugins: # 明确列出需要加载的插件,避免加载无用插件浪费内存 - key-auth - limit-count - cors - proxy-rewrite - http-logger # ... 仅添加你需要的插件关键优化点:
- 禁用不必要的插件: 在
plugins列表里只启用需要的插件,可以显著减少内存占用和提高性能。 - 调整工作进程: 通过环境变量
APISIX_WORKER_PROCESSES可以设置Nginx worker进程数,通常设置为与CPU核心数相等。 - 日志轮转: 确保挂载的日志目录有日志轮转策略(如使用
logrotate),防止日志占满磁盘。
5.2 常见问题排查思路
即使配置正确,在实际运行中也可能遇到问题。这里分享几个我踩过的坑和排查思路。
问题一:路由配置成功,但访问返回404或502。
- 检查上游健康状态: 在Dashboard的“上游”页面,检查目标节点是否健康。APISIX默认有健康检查,不健康的节点会被暂时摘除。
- 检查插件冲突: 是否启用了
proxy-rewrite插件修改了URI或Host,导致上游无法识别?是否启用了redirect插件?逐一禁用插件进行排查。 - 查看APISIX错误日志:
docker logs apisix-gateway查看网关本身的错误信息,通常会有更详细的 upstream 连接失败原因。 - 使用
curl -v调试: 在APISIX服务器上,直接curl上游服务地址,看网络是否通,端口是否正确。
问题二:Dashboard操作成功,但配置不生效。
- 检查etcd连接: 确认APISIX和Dashboard的配置中,etcd的地址和端口是否正确,网络是否互通。
- 检查配置前缀: 确保APISIX和Dashboard的
prefix配置一致(默认都是/apisix)。 - 直接查询etcd: 这是终极手段。使用etcdctl工具查看配置是否真的写入了:
etcdctl get --prefix /apisix。你可以看到所有以JSON格式存储的路由、上游等数据。如果这里没有,说明Dashboard写入失败;如果有但APISIX不生效,说明APISIX读取etcd有问题。
问题三:性能瓶颈。
- 监控系统资源: 使用
top或htop查看APISIX进程的CPU和内存使用情况。 - 分析慢日志: 如果启用了
http-logger,关注upstream_response_time字段,如果这个值很大,瓶颈可能在上游服务,而非网关本身。 - 调整Nginx参数: 对于超高并发场景,可能需要调整APISIX底层的Nginx参数,如
worker_connections,这需要修改APISIX的模板文件并重建镜像,属于高级优化。
5.3 版本升级与备份策略
升级: APISIX版本迭代较快,新版本会修复bug并带来新功能。升级前务必:
- 详细阅读官方发布公告和升级指南。
- 在测试环境充分验证。
- 备份etcd中的所有数据。
- 采用滚动升级方式,先升级一个节点,验证无误后再升级其他节点。
备份: 你的所有配置都存储在etcd中。定期备份etcd数据是必须的。可以使用etcdctl snapshot save命令创建快照。备份时,确保APISIX集群处于稳定状态。
6. 超越基础:动态上游与服务发现集成
对于微服务架构,后端服务实例是动态变化的。手动在APISIX里维护上游节点列表是不现实的。这就需要用到服务发现集成。
APISIX支持多种服务发现方式,最常用的是与Nacos、Consul、Eureka等注册中心集成。这里以Nacos为例简述思路:
- 在APISIX配置中启用Nacos发现: 需要在
config.yaml的discovery部分配置Nacos服务器地址。 - 创建使用服务发现的上游: 在Dashboard创建上游时,“服务发现”类型选择“nacos”,并在“服务名”中填写你在Nacos中注册的服务名称(如
user-service)。 - 关联路由: 创建路由时,选择这个上游即可。
此后,当user-service有新的实例注册到Nacos或下线时,APISIX会自动更新其负载均衡节点列表,实现真正的动态路由。这大大降低了运维复杂度。
7. 写在最后:从工具到理念的转变
搭建和配置APISIX,掌握插件使用,这些是具体的技能。但在这个过程中,更重要的是理解一种理念:将流量管理、API策略从业务代码中彻底解耦。
以前,限流、认证、熔断的代码可能散落在各个服务里,标准不一,难以维护。现在,你可以在网关层统一定义、全局生效。以前,一个服务下线或扩容需要通知所有调用方修改配置,现在只需要在注册中心操作,网关自动感知。
APISIX Dashboard提供的可视化界面,让开发和运维人员能清晰地看到整个系统的流量脉络,而不再是一堆冰冷的配置文件。当出现问题时,你可以快速定位是网关策略导致,还是上游服务本身故障。
我个人的体会是,引入APISIX这类现代API网关的初期,会有一个学习和适应成本,比如要理解其路由模型、插件机制。但一旦团队熟悉了这套模式,后续的API管理、迭代、监控都会变得异常顺畅。它就像给整个系统配备了一个智能交通指挥中心,让每一股数据流都井然有序。