第 12 章 对 API 基础架构进行故障排除
本指南旨在帮助您识别和修复 API 基础架构问题的原因。
API 基础架构是一个冗长而复杂的主题。但是,您的基础架构中至少需要三个移动部分:
- API 网关
- 3scale
- API
这三种元素中的任何一个错误都会导致 API 用户无法访问您的 API。但是,很难找到导致失败的组件。本指南将为您提供对基础架构进行故障排除以确定问题的一些建议。
使用以下部分来识别并修复可能出现的常见问题:
12.1. 常见集成问题
有一些证据可以指出您与 3scale 集成时存在一些非常常见的问题。它们将根据您是处于 API 项目开头、设置基础架构还是已存在于生产中而有所不同。
12.1.1. 集成问题
以下小节尝试概述了在与 3scale 集成的初始阶段,APIcast 错误日志中可能看到的一些常见问题:从使用 APIcast Hosted 开始,在启动之前,运行自我管理的 APIcast。
12.1.1.1. APIcast 托管
当您首次在 Service Integration 屏幕上将 API 与 APIcast Hosted 集成时,您可能会在页面中看到一些以下错误,或者通过测试调用返回,以检查集成是否成功。
测试请求失败:执行过期
检查您的 API 是否可从公共互联网访问。APIcast Hosted 无法与私有 API 一起使用。如果您不想使 API 公开可用于与 APIcast Hosted 集成,您可以在 APIcast Hosted 和 API 之间设置一个私有 secret,以拒绝任何来自 API 网关的调用。
可接受的格式是
protocol://address(:port)
删除 API 专用基础 URL 末尾的所有路径。您可以在"映射规则"模式或 API test GET request 的开头添加它们。
使用 HTTP 代码 XXX 测试请求失败
-
405
:检查端点是否接受 GET 请求。APIcast 只支持 GET 请求来测试集成。 -
403:缺少身份验证参数
:如果您的 API 已有一些身份验证,APIcast 将无法发出测试请求。 -
403:身份验证失败
:如果这不是您通过 3scale 创建的第一个服务,请检查您是否在服务下创建了带有凭据的应用,以发出测试请求。如果是您要集成的第一个服务,请确保您还没有删除在注册时创建的测试帐户或应用程序。
-
12.1.1.2. APIcast 自我管理
在成功测试了与 APIcast 自我管理的集成后,您可能希望自己托管 API 网关。以下是首次安装自我管理网关并通过它调用 API 时您可能会遇到的一些错误。
upstream timed out (110:Connection timed out) while connecting to upstream
检查 API 网关和公共 Internet 之间没有防火墙或代理,从而妨碍您自我管理的网关到达 3scale。
failed to get list of services: invalid status:403 (Forbidden)
2018/06/04 08:04:49 [emerg] 14#14: [lua] configuration_loader.lua:134: init(): failed to load configuration, exiting (code 1) 2018/06/04 08:04:49 [warn] 22#22: *2 [lua] remote_v2.lua:163: call(): failed to get list of services: invalid status: 403 (Forbidden) url: https://example-admin.3scale.net/admin/api/services.json , context: ngx.timer ERROR: /opt/app-root/src/src/apicast/configuration_loader.lua:57: missing configuration
检查您在
THREESCALE_PORTAL_ENDOINT
值中使用的访问令牌是否正确,以及帐户管理 API 范围。使用curl
命令验证它:curl -v "https://example-admin.3scale.net/admin/api/services.json?access_token=<YOUR_ACCESS_TOKEN>"
它应当通过 JSON 正文返回 200 响应。如果返回错误状态代码,请检查响应正文以了解详细信息。
主机 apicast.example.com 没有找到服务
2018/06/04 11:06:15 [warn] 23#23: *495 [lua] find_service.lua:24: find_service(): service not found for host apicast.example.com, client: 172.17.0.1, server: _, request: "GET / HTTP/1.1", host: "apicast.example.com"
此错误表示公共基本 URL 尚未正确配置。您应该确保配置的 Public Base URL 与用于自助管理的 APIcast 请求的相同。配置正确的公共基本 URL 后:
-
确保 APIcast 已配置为"生产环境"(如果不使用
THREESCALE_DEPLOYMENT_ENV
变量覆盖独立 APIcast 的默认配置)。确保您将配置提升到生产环境。 -
如果您使用
APICAST_CONFIGURATION_CACHE
和APICAST_CONFIGURATION_LOADER
环境变量自动重新加载配置,请重新启动 APIcast。
-
确保 APIcast 已配置为"生产环境"(如果不使用
以下是一些可能指向不正确 APIcast 自助管理的集成的其他症状:
- 映射规则与 API 调用的 / Double 计数不匹配 :根据您定义 API 上方法和实际 URL 端点之间的映射方式,您可能会发现有时每个请求都不匹配的方法或被递增一次。要对此进行故障排除,请通过 3scale 调试标头 对 API 发出测试调用。这将返回 API 调用匹配的所有方法的列表。
- 未找到身份验证参数 :确保您将参数发送到 Service Integration 屏幕中指定的正确位置。如果没有将凭证作为标头发送,则凭据必须以 GET 请求和正文参数的查询参数形式发送,所有其他 HTTP 方法。使用 3scale 调试标头来再次检查从 API 网关的请求读取的凭据。
12.1.2. 产品问题
在全面测试了设置并且已使用 API 长时间使用 API 后,很少会出现与 API 网关相关的问题。但是,以下是您可能在真实生产环境中遇到的一些问题:
12.1.2.1. 可用性问题
可用性问题通常由 nginx error.log 中的 上游超时
错误定性;例如:
upstream timed out (110: Connection timed out) while connecting to upstream, client: X.X.X.X, server: api.example.com, request: "GET /RESOURCE?CREDENTIALS HTTP/1.1", upstream: "http://Y.Y.Y.Y:80/RESOURCE?CREDENTIALS", host: "api.example.com"
如果您遇到 3scale 的可用性问题,这可能是原因:
您解析了不再使用的旧 3scale IP。
最新版本的 API 网关配置文件将 3scale 定义为每次强制 IP 解析的变量。为获得快速修复,重新加载您的 NGINX 实例。对于长期修复,请确保将其定义为每个服务器块中的变量,而不是在上游块中定义 3scale 后端;例如:
server { # Enabling the Lua code cache is strongly encouraged for production use. Here it is enabled . . . set $threescale_backend "https://su1.3scale.net:443";
引用它时:
location = /threescale_authrep { internal; set $provider_key "YOUR_PROVIDER_KEY"; proxy_pass $threescale_backend/transactions/authrep.xml?provider_key=$provider_key&service_id=$service_id&$usage&$credentials&log%5Bcode%5D=$arg_code&log%5Brequest%5D=$arg_req&log%5Bresponse%5D=$arg_resp; }
您缺少白名单中的一些 3scale IP。以下是 3scale 解析到的 IP 的当前列表:
- 75.101.142.93
- 174.129.235.69
- 184.73.197.122
- 50.16.225.117
- 54.83.62.94
- 54.83.62.186
- 54.83.63.187
54.235.143.255
以上问题是指感知的 3scale 可用性问题。但是,如果您的 API 位于 AWS ELB 后面,您可能会遇到与 API 网关的 API 可用性类似的问题。这是因为 NGINX 默认在启动时执行 DNS 解析,然后缓存 IP 地址。但是,ELB 无法确保静态 IP 地址,它们可能会经常更改。当 ELB 更改为其他 IP 时,NGINX 无法访问它。
此问题的解决方案与强制进行运行时 DNS 解析的修复程序类似。
-
通过在
http
部分的顶部添加以下行来设置特定的 DNS 解析器,如 Google DNS:解析器 8.8.8.8 8.8.4.4;
。 -
将 API 基本 URL 设置为
server
部分顶部附近任何位置的变量。设置 $api_base "http://api.example.com:80";
-
在
location /
部分中,找到proxy_pass
行并将其替换为proxy_pass $api_base;
。
-
通过在
12.1.3. 部署后的问题
如果您更改了 API,如添加新端点,您必须确保在下载 API 网关的新配置文件之前添加新方法和 URL 映射。
当您修改了从 3scale 下载的配置时,最常见问题是在 Lua 中的代码错误,这会导致 500 - 内部服务器错误
,例如:
curl -v -X GET "http://localhost/" * About to connect() to localhost port 80 (#0) * Trying 127.0.0.1... connected > GET / HTTP/1.1 > User-Agent: curl/7.22.0 (x86_64-pc-linux-gnu) libcurl/7.22.0 OpenSSL/1.0.1 zlib/1.2.3.4 libidn/1.23 librtmp/2.3 > Host: localhost > Accept: */* > < HTTP/1.1 500 Internal Server Error < Server: openresty/1.5.12.1 < Date: Thu, 04 Feb 2016 10:22:25 GMT < Content-Type: text/html < Content-Length: 199 < Connection: close < <head><title>500 Internal Server Error</title></head> <center><h1>500 Internal Server Error</h1></center> <hr><center>openresty/1.5.12.1</center> * Closing connection #0
您可以看到 nginx error.log 了解原因,例如:
2016/02/04 11:22:25 [error] 8980#0: *1 lua entry thread aborted: runtime error: /home/pili/NGINX/troubleshooting/nginx.lua:66: bad argument #3 to '_newindex' (number expected, got nil) stack traceback: coroutine 0: [C]: in function '_newindex' /home/pili/NGINX/troubleshooting/nginx.lua:66: in function 'error_authorization_failed' /home/pili/NGINX/troubleshooting/nginx.lua:330: in function 'authrep' /home/pili/NGINX/troubleshooting/nginx.lua:283: in function 'authorize' /home/pili/NGINX/troubleshooting/nginx.lua:392: in function while sending to client, client: 127.0.0.1, server: api-2445581381726.staging.apicast.io, request: "GET / HTTP/1.1", host: "localhost"
在 access.log 中,类似如下:
127.0.0.1 - - [04/Feb/2016:11:22:25 +0100] "GET / HTTP/1.1" 500 199 "-" "curl/7.22.0 (x86_64-pc-linux-gnu) libcurl/7.22.0 OpenSSL/1.0.1 zlib/1.2.3.4 libidn/1.23 librtmp/2.3"
上一节将向您介绍在 3scale 旅程的任何阶段可能会遇到的最常见、知名的问题。
如果已经检查所有这些内容,且您仍无法找到问题的原因和解决方案,您应该进入有关 识别 API 请求问题 的更详细部分。从 API 开始,再重新尝试确定故障点到客户端。