常见问题

APISIX 在这些指标表现上优于其它 API 网关,同时具有平台无关性和完全动态的特性,如支持多种协议、细粒度路由和多语言支持。

APISIX 和其他的 API 网关有什么不同之处?

Apache APISIX 在以下方面有所不同:

— 它使用 etcd 来保存和同步配置,而不是使用如 PostgreSQL 或 MySQL 这类的关系数据库。etcd 中的实时事件通知系统比这些替代方案更容易扩展。这允许 APISIX 实时同步配置,使代码简洁,并避免单点故障。

APISIX 所展现出的性能如何?

与其它 API 网关相比,Apache APISIX 提供了更好的性能,其单核 QPS 高达 18,000,平均延迟仅为 0.2 ms。

如果您想获取性能基准测试的具体结果,请查看 benchmark

Apache APISIX 支持哪些平台?

Apache APISIX 是一个开源的云原生 API 网关,它支持在裸金属服务器上运行,也支持在 Kubernetes 上使用,甚至也可以运行在 Apple Silicon ARM 芯片上。

如何理解“Apache APISIX 是全动态的”?

Apache APISIX 是全动态的 API 网关,意味着当你在更改一个配置后,只需要重新加载配置文件就可以使其生效。

APISIX 可以动态处理以下行为:

  • 重新加载插件
  • 代理重写
  • 对请求进⾏镜像复制
  • 对请求进⾏修改
  • 健康状态的检查
  • 动态控制指向不同上游服务的流量⽐

APISIX 是否有控制台界面?

APISIX 具有功能强大的 Dashboard,并且 APISIX Dashboard 是一个独立的项目。你可以通过 用户操作界面来部署 APISIX Dashboard。

我可以为 Apache APISIX 开发适合自身业务的插件吗?

当然可以,APISIX 提供了灵活的自定义插件,方便开发者和企业编写自己的逻辑。

如果你想开发符合自身业务逻辑的插件,请参考:。

为什么 Apache APISIX 选择 etcd 作为配置中心?

对于配置中心,配置存储只是最基本功能,APISIX 还需要下面几个特性:

  1. 集群中的分布式部署
  2. 通过比较来监视业务
  3. 多版本并发控制
  4. 变化通知
  5. 高性能和最小的读/写延迟

etcd 提供了这些特性,并且使它比 PostgreSQL 和 MySQL 等其他数据库更理想。

如果你想了解更多关于 etcd 与其他替代方案的比较,请参考。

使用 LuaRocks 安装 Apache APISIX 依赖项时,为什么会导致超时、安装缓慢或安装失败?

可能是因为使用的 LuaRocks 服务器延迟过高。

为了解决这个问题,你可以使用 https_proxy 或者使用 --server 参数指定一个更快的 LuaRocks 服务器。

你可以运行如下命令来查看可用的服务器(需要 LuaRocks 3.0+):

中国大陆用户可以使用 luarocks.cn 作为 LuaRocks 的服务器。

以下命令可以帮助你更快速的安装依赖:

  1. make deps ENV_LUAROCKS_SERVER=https://luarocks.cn

如果通过上述操作仍然无法解决问题,可以尝试使用 --verbose 参数获取详细的日志来诊断问题。

如何构建 APISIX-Base 环境?

有些功能需要引入额外的 NGINX 模块,这就要求 APISIX 需要运行在 APISIX-Base 上。如果你需要这些功能,你可以参考 api7/apisix-build-tools 中的代码,构建自己的 APISIX-Base 环境。

我该如何使用 Apache APISIX 进行灰度发布?

举个例子,比如:foo.com/product/index.html?id=204&page=2,并考虑您需要根据查询字符串中的 id 在此条件下进行灰度发布:

  1. Group A:id <= 1000
  2. Group B:id > 1000

在 Apache APISIX 中有两种不同的方法来实现这一点:

  1. 创建一个Route并配置 vars 字段:
  1. curl -i http://127.0.0.1:9180/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
  2. {
  3. "uri": "/index.html",
  4. "vars": [
  5. ["arg_id", "<=", "1000"]
  6. ],
  7. "plugins": {
  8. "redirect": {
  9. "uri": "/test?group_id=1"
  10. }
  11. }
  12. }'
  13. curl -i http://127.0.0.1:9180/apisix/admin/routes/2 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
  14. {
  15. "uri": "/index.html",
  16. "vars": [
  17. ["arg_id", ">", "1000"]
  18. ],
  19. "plugins": {
  20. "redirect": {
  21. "uri": "/test?group_id=2"
  22. }
  23. }
  24. }'

更多 lua-resty-radixtree 匹配操作,请参考:。

2、通过 traffic-split 插件来实现。

比如,将 http://foo.com 重定向到 https://foo.com

Apache APISIX 提供了几种不同的方法来实现:

  1. redirect 插件中将 http_to_https 设置为 true
  1. curl http://127.0.0.1:9180/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
  2. {
  3. "uri": "/hello",
  4. "host": "foo.com",
  5. "plugins": {
  6. "redirect": {
  7. "http_to_https": true
  8. }
  9. }
  10. }'
  1. 结合高级路由规则 varsredirect 插件一起使用:
  1. curl -i http://127.0.0.1:9180/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
  2. {
  3. "uri": "/hello",
  4. "host": "foo.com",
  5. "vars": [
  6. [
  7. "scheme",
  8. "==",
  9. "http"
  10. ]
  11. ],
  12. "redirect": {
  13. "uri": "https://$host$request_uri",
  14. "ret_code": 301
  15. }
  16. }
  17. }'
  1. 使用 serverless 插件:
  1. curl -i http://127.0.0.1:9180/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
  2. {
  3. "uri": "/hello",
  4. "plugins": {
  5. "serverless-pre-function": {
  6. "phase": "rewrite",
  7. "functions": ["return function() if ngx.var.scheme == \"http\" and ngx.var.host == \"foo.com\" then ngx.header[\"Location\"] = \"https://foo.com\" .. ngx.var.request_uri; ngx.exit(ngx.HTTP_MOVED_PERMANENTLY); end; end"]
  8. }
  9. }
  10. }'

然后测试下是否生效:

  1. curl -i -H 'Host: foo.com' http://127.0.0.1:9080/hello

响应信息应该是:

  1. HTTP/1.1 301 Moved Permanently
  2. Date: Mon, 18 May 2020 02:56:04 GMT
  3. Content-Type: text/html
  4. Content-Length: 166
  5. Connection: keep-alive
  6. Location: https://foo.com/hello
  7. Server: APISIX web server
  8. <html>
  9. <head><title>301 Moved Permanently</title></head>
  10. <body>
  11. <center><h1>301 Moved Permanently</h1></center>
  12. <hr><center>openresty</center>
  13. </body>
  14. </html>

我应该如何更改 Apache APISIX 的日志等级?

Apache APISIX 默认的日志等级为 warn,你需要将日志等级调整为 info 来查看 core.log.info 的打印结果。

  1. nginx_config:
  2. error_log_level: "info"

我应该如何重新加载 Apache APISIX 的自定义插件?

所有的 Apache APISIX 的插件都支持热加载的方式。

如果你想了解更多关于热加载的内容,请参考。

在处理 HTTP 或 HTTPS 请求时,我该如何配置 Apache APISIX 来监听多个端口?

默认情况下,APISIX 在处理 HTTP 请求时只监听 9080 端口。

要配置 Apache APISIX 监听多个端口,你可以:

  1. 修改 conf/config.yaml 中 HTTP 端口监听的参数 node_listen,示例:

    1. apisix:
    2. node_listen:
    3. - 9080
    4. - 9081
    5. - 9082

    处理 HTTPS 请求也类似,修改 conf/config.yaml 中 HTTPS 端口监听的参数 ssl.listen,示例:

    1. apisix:
    2. ssl:
    3. enable: true
    4. listen:
    5. - port: 9443
    6. - port: 9444
    7. - port: 9445
  2. 重启或者重新加载 APISIX。

APISIX 如何利用 etcd 如何实现毫秒级别的配置同步?

Apache APISIX 使用 etcd 作为它的配置中心。etcd 提供以下订阅功能(比如:watch、)。它可以监视对特定关键字或目录的更改。

APISIX 主要使用 etcd.watchdir 监视目录内容变更:

  • 如果监听目录没有数据更新:则该调用会被阻塞,直到超时或其他错误返回。

  • 如果监听目录有数据更新:etcd 将立刻返回订阅(毫秒级)到的新数据,APISIX 将它更新到内存缓存。

我应该如何自定义 APISIX 实例 id?

默认情况下,APISIX 从 conf/apisix.uid 中读取实例 id。如果找不到,且没有配置 id,APISIX 会生成一个 uuid 作为实例 id。

要指定一个有意义的 id 来绑定 Apache APISIX 到你的内部系统,请在你的 ./conf/config.yaml 中设置 id:

为什么 error.log 中会出现 “failed to fetch data from etcd, failed to read etcd dir, etcd key: xxxxxx” 的错误?

请按照以下步骤进行故障排除:

  1. 确保 Apache APISIX 和集群中的 etcd 部署之间没有任何网络问题。
  2. 如果网络正常,请检查是否为 etcd 启用了。默认状态取决于你是使用命令行还是配置文件来启动 etcd 服务器。
  • 如果使用命令行选项,默认启用 gRPC 网关。可以手动启用,如下所示:
  1. etcd --enable-grpc-gateway --data-dir=/path/to/data

注意:当运行 etcd --help 时,这个参数不会显示。

  • 如果使用配置文件,默认关闭 gRPC 网关。你可以手动启用,如下所示:

    etcd.json 配置:

  1. {
  2. "enable-grpc-gateway": true,
  3. "data-dir": "/path/to/data"
  4. }

etcd.conf.yml 配置

  1. enable-grpc-gateway: true

注意:事实上这种差别已经在 etcd 的 master 分支中消除,但并没有向后兼容到已经发布的版本中,所以在部署 etcd 集群时,依然需要小心。

我应该如何创建高可用的 Apache APISIX 集群?

Apache APISIX 可以通过在其前面添加一个负载均衡器来实现高可用性,因为 APISIX 的数据面是无状态的,并且可以在需要时进行扩展。

Apache APISIX 的控制平面是依赖于 etcd cluster 的高可用实现的,它只依赖于 etcd 集群。

为什么使用源码安装 Apache APISIX 时,执行 make deps 命令会失败?

当使用源代码安装 Apache APISIX 时,执行 make deps 命令可能会出现如下错误:

  1. $ make deps
  2. ......
  3. Error: Failed installing dependency: https://luarocks.org/luasec-0.9-1.src.rock - Could not find header file for OPENSSL
  4. No file openssl/ssl.h in /usr/local/include
  5. You may have to install OPENSSL in your system and/or pass OPENSSL_DIR or OPENSSL_INCDIR to the luarocks command.
  6. Example: luarocks install luasec OPENSSL_DIR=/usr/local
  7. make: *** [deps] Error 1

这是由于缺少 OpenResty openssl 开发工具包。要安装它,请参考installation dependencies

我如何通过 APISIX 代理访问 APISIX Dashboard?

你可以按照以下步骤进行配置:

  1. 为 Apache APISIX 代理和 Admin API 配置不同的端口,或者禁用 Admin API。
  1. deployment:
  2. admin:
  3. admin_listen: # use a separate port
  4. ip: 127.0.0.1
  5. port: 9180

2、添加 APISIX Dashboard 的代理路由:

  1. curl -i http://127.0.0.1:9180/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
  2. {
  3. "uris":[ "/*" ],
  4. "name":"apisix_proxy_dashboard",
  5. "upstream":{
  6. "nodes":[
  7. {
  8. "host":"127.0.0.1",
  9. "port":9000,
  10. "weight":1
  11. }
  12. ],
  13. "type":"roundrobin"
  14. }
  15. }'

注意: Apache APISIX Dashboard 正在监听 127.0.0.1:9000

如何使用正则表达式 (regex) 匹配 Route 中的 uri

你可以在 Route 中使用 vars 字段来匹配正则表达式:

  1. curl -i http://127.0.0.1:9180/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
  2. {
  3. "uri": "/*",
  4. "vars": [
  5. ["uri", "~~", "^/[a-z]+$"]
  6. ],
  7. "upstream": {
  8. "type": "roundrobin",
  9. "nodes": {
  10. "127.0.0.1:1980": 1
  11. }
  12. }'

测试请求:

  1. # uri 匹配成功
  2. $ curl http://127.0.0.1:9080/hello -i
  3. HTTP/1.1 200 OK
  4. ...
  5. # uri 匹配失败
  6. $ curl http://127.0.0.1:9080/12ab -i
  7. HTTP/1.1 404 Not Found
  8. ...

如果你想了解 vars 字段的更多信息,请参考 。

这是支持的,下面是一个 FQDNhttpbin.default.svc.cluster.local(一个 Kubernetes Service)的示例:

  1. curl http://127.0.0.1:9180/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
  2. {
  3. "uri": "/ip",
  4. "upstream": {
  5. "type": "roundrobin",
  6. "nodes": {
  7. "httpbin.default.svc.cluster.local": 1
  8. }
  9. }
  10. }'
  1. curl http://127.0.0.1:9080/ip -i

Admin API 的 X-API-KEY 指的是什么?是否可以修改?

Admin API 的 X-API-KEY 指的是 ./conf/config.yaml 文件中的 ,默认值是 edd1c9f034335f136f87ad84b625c8f1。它是 Admin API 的访问 token。

默认情况下,它被设置为 edd1c9f034335f136f87ad84b625c8f1,也可以通过修改 ./conf/conf/config 中的参数来修改,如下示例:

然后访问 Admin API:

  1. curl -i http://127.0.0.1:9180/apisix/admin/routes/1 -H 'X-API-KEY: newkey' -X PUT -d '
  2. {
  3. "uris":[ "/*" ],
  4. "name":"admin-token-test",
  5. "upstream":{
  6. "nodes":[
  7. {
  8. "host":"127.0.0.1",
  9. "port":1980,
  10. "weight":1
  11. }
  12. ],
  13. "type":"roundrobin"
  14. }
  15. }'
  16. HTTP/1.1 200 OK
  17. ......

注意:通过使用默认令牌,可能会面临安全风险。在将其部署到生产环境时,需要对其进行更新。

如何允许所有 IP 访问 Apache APISIX 的 Admin API?

Apache APISIX 默认只允许 127.0.0.0/24 的 IP 段范围访问 Admin API

如果你想允许所有的 IP 访问,只需在 ./conf/config.yaml 配置文件中添加如下的配置,然后重启或重新加载 APISIX 就可以让所有 IP 访问 Admin API

  1. deployment:
  2. admin:
  3. allow_admin:
  4. - 0.0.0.0/0

注意:你可以在非生产环境中使用此方法,以允许所有客户端从任何地方访问 Apache APISIX 实例,但是在生产环境中该设置并不安全。在生产环境中,请仅授权特定的 IP 地址或地址范围访问 Apache APISIX 实例。

如何基于 acme.sh 自动更新 APISIX SSL 证书?

你可以运行以下命令来实现这一点:

  1. curl --output /root/.acme.sh/renew-hook-update-apisix.sh --silent https://gist.githubusercontent.com/anjia0532/9ebf8011322f43e3f5037bc2af3aeaa6/raw/65b359a4eed0ae990f9188c2afa22bacd8471652/renew-hook-update-apisix.sh
  1. chmod +x /root/.acme.sh/renew-hook-update-apisix.sh
  1. acme.sh --issue --staging -d demo.domain --renew-hook "/root/.acme.sh/renew-hook-update-apisix.sh -h http://apisix-admin:port -p /root/.acme.sh/demo.domain/demo.domain.cer -k /root/.acme.sh/demo.domain/demo.domain.key -a xxxxxxxxxxxxx"
  1. acme.sh --renew --domain demo.domain

详细步骤,请参考 APISIX 基于 acme.sh 自动更新 HTTPS 证书

在 Apache APISIX 中,我如何在转发到上游之前从路径中删除一个前缀?

在转发至上游之前移除请求路径中的前缀,比如说从 /foo/get 改成 /get,可以通过 [proxy-rewrite](/zh/docs/apisix/plugins/proxy-rewrite) 插件来实现:

  1. curl -i http://127.0.0.1:9180/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
  2. {
  3. "uri": "/foo/*",
  4. "plugins": {
  5. "proxy-rewrite": {
  6. "regex_uri": ["^/foo/(.*)","/$1"]
  7. }
  8. },
  9. "upstream": {
  10. "type": "roundrobin",
  11. "nodes": {
  12. "httpbin.org:80": 1
  13. }
  14. }
  15. }'

测试这个配置:

  1. curl http://127.0.0.1:9080/foo/get -i
  2. HTTP/1.1 200 OK
  3. ...
  4. {
  5. ...
  6. "url": "http://127.0.0.1/get"
  7. }

我应该如何解决 unable to get local issuer certificate 这个错误?

你可以手动设置证书的路径,将其添加到 ./conf/config.yaml 文件中,具体操作如下所示:

  1. apisix:
  2. ssl:
  3. ssl_trusted_certificate: /path/to/certs/ca-certificates.crt

注意:当你尝试使用 cosocket 连接任何 TLS 服务时,如果 APISIX 不信任对端 TLS 服务证书,都需要配置 apisix.ssl.ssl_trusted_certificate

例如:如果在 APISIX 中使用 Nacos 作为服务发现时,Nacos 开启了 TLS 协议,即 Nacos 配置的 hosthttps:// 开头,就需要配置 apisix.ssl.ssl_trusted_certificate,并且使用和 Nacos 相同的 CA 证书。

我应该如何解决 module 'resty.worker.events' not found 这个错误?

引起这个错误的原因是在 /root 目录下安装了 APISIX。因为 worker 进程的用户是 nobody,无权访问 /root 目录下的文件。

解决办法是改变 APISIX 的安装目录,推荐安装在 /usr/local 目录下。

在 Apache APISIX 中,plugin-metadataplugin-configs 有什么区别?

两者之间的差异如下:

部署了 Apache APISIX 之后,如何检测 APISIX 数据平面的存活情况(如何探活)?

可以创建一个名为 health-info 的路由,并开启 fault-injection 插件(其中 YOUR-TOKEN 是用户自己的 token;127.0.0.1 是控制平面的 IP 地址,可以自行修改):

  1. curl http://127.0.0.1:9180/apisix/admin/routes/health-info \
  2. -H 'X-API-KEY: YOUR-TOKEN' -X PUT -d '
  3. {
  4. "plugins": {
  5. "fault-injection": {
  6. "abort": {
  7. "http_status": 200,
  8. "body": "fine"
  9. }
  10. }
  11. },
  12. "uri": "/status"
  13. }'

验证方式:

访问 Apache APISIX 数据平面的 /status 来探测 APISIX,如果 response code 是 200 就代表 APISIX 存活。

note

这个方式只是探测 APISIX 数据平面是否存活,并不代表 APISIX 的路由和其他功能是正常的,这些需要更多路由级别的探测。

APISIX 与 相关的延迟较高的问题有哪些,如何修复?

etcd 作为 APISIX 的数据存储组件,它的稳定性关乎 APISIX 的稳定性。在实际场景中,如果 APISIX 使用证书通过 HTTPS 的方式连接 etcd,可能会出现以下 2 种数据查询或写入延迟较高的问题:

  1. 通过接口操作 APISIX Admin API 进行数据的查询或写入,延迟较高。
  2. 在监控系统中,Prometheus 抓取 APISIX 数据面 Metrics 接口超时。

这些延迟问题,严重影响了 APISIX 的服务稳定性,而之所以会出现这类问题,主要是因为 etcd 对外提供了 2 种操作方式:HTTP(HTTPS)、gRPC。而 APISIX 是基于 HTTP(HTTPS)协议来操作 etcd 的。

在这个场景中,etcd 存在一个关于 HTTP/2 的 BUG:如果通过 HTTPS 操作 etcd(HTTP 不受影响),HTTP/2 的连接数上限为 Golang 默认的 250 个。

所以,当 APISIX 数据面节点数较多时,一旦所有 APISIX 节点与 etcd 连接数超过这个上限,则 APISIX 的接口响应会非常的慢。

Golang 中,默认的 HTTP/2 上限为 250,代码如下:

目前,etcd 官方主要维护了 3.43.5 这两个主要版本。在 3.4 系列中,近期发布的 3.4.20 版本已修复了这个问题。至于 3.5 版本,其实,官方很早之前就在筹备发布 3.5.5 版本了,但截止目前(2022.09.13)仍尚未发布。所以,如果你使用的是 etcd 的版本小于 3.5.5,可以参考以下几种方式解决这个问题:

  1. 将 APISIX 与 etcd 的通讯方式由 HTTPS 改为 HTTP。
  2. 将 etcd 版本回退到 3.4.20
  3. 将 etcd 源码克隆下来,直接编译 release-3.5 分支(此分支已修复,只是尚未发布新版本而已)。

重新编译 etcd 的方式如下:

  1. git checkout release-3.5
  2. make GOOS=linux GOARCH=amd64

编译的二进制在 目录下,将其替换掉你服务器环境的 etcd 二进制后,然后重启 etcd 即可。

更多信息,请参考:

如果在使用 APISIX 过程中遇到问题,我可以在哪里寻求更多帮助?

  • :加入后请选择 channel-apisix 频道,即可通过此频道进行 APISIX 相关问题的提问。
  • 邮件列表:任何问题或对项目提议都可以通过社区邮件进行讨论。