502 网关无效 - DuplicateHeader

<ph type="x-smartling-placeholder"></ph> 您正在查看 Apigee Edge 文档。
转到 Apigee X 文档
信息

问题

客户端应用收到 HTTP 状态代码 502 Bad Gateway 和错误代码 protocol.http.DuplicateHeader 作为 API 调用的响应。

错误消息

客户端应用将获得以下响应代码:

HTTP/1.1 502 Bad Gateway

此外,您可能还会看到类似于如下所示的错误消息:

{
   "fault":{
      "faultstring":"Duplicate Header \"Expires\"",
      "detail":{
         "errorcode":"protocol.http.DuplicateHeader"
      }
   }
}

可能的原因

如果 Apigee 中不允许有重复的特定 HTTP 标头,就会出现此错误 Edge 在由 从后端服务器迁移到 Apigee Edge

根据 RFC 7230,第 3.2.2 节:字段顺序发件人不得生成多个标头 具有相同字段名称的那些字段,除非相应字段的整个字段值 标头字段定义为以逗号分隔的列表,[即#(values)] 或标题字段是 众所周知的异常。如果 Apigee Edge 发现特定的标头,则不允许 在由服务器发送的 HTTP 响应 中多次发送 目标/后端服务器 则会返回 502 Bad Gateway 和错误代码 protocol.http.DuplicateHeader

<ph type="x-smartling-placeholder">

以下是导致此错误的可能原因:

原因 说明 适用的问题排查说明
响应中的标头重复 来自后端服务器的响应包含重复的标头。 Edge 公有云和私有云用户

常见诊断步骤

使用以下工具/技术之一来诊断此错误:

API 监控

<ph type="x-smartling-placeholder">

如需使用 API Monitoring 诊断错误,请执行以下操作:

  1. <ph type="x-smartling-placeholder"></ph> 以拥有用户身份登录 Apigee Edge 界面 适当的角色。
  2. 切换到您要在其中调查问题的单位。

  3. 导航至分析 >API 监控 >调查页面。
  4. 选择您观察到错误的具体时间范围。
  5. 确保将代理过滤器设置为全部
  6. 根据时间绘制错误代码
  7. 选择一个错误代码为 protocol.http.DuplicateHeader 的单元格,如下所示:

    查看放大图片

  8. 错误代码 protocol.http.DuplicateHeader 的相关信息如下所示:

    查看放大图片

  9. 确保 Status Code(状态代码)为 502(如上例所示)。
  10. 点击查看日志,然后展开失败请求对应的行。
  11. 在“日志”窗口中,请注意以下详细信息:

    • 状态代码502
    • 故障来源target
    • 错误代码protocol.http.DuplicateHeader
  12. 错误来源target,这表示来自后端服务器的响应包含重复标头。

跟踪工具

<ph type="x-smartling-placeholder">

如需使用跟踪工具诊断错误,请执行以下操作:

  1. 启用跟踪会话,并且 <ph type="x-smartling-placeholder">
      </ph>
    1. 等待发生 502 Bad Gateway 错误,或者
    2. 如果您可以重现问题,请进行 API 调用并重现 502 Bad Gateway 个错误
  2. 确保已启用 Show all Flow Infos

  3. 选择其中一个失败请求并检查跟踪记录。
  4. 浏览跟踪记录的不同阶段,并找到失败的位置。
  5. 该错误通常在 Request sent to target 服务器阶段,如下所示:

    查看放大图片

  6. 请记下跟踪记录中的错误值。

    上面的示例跟踪记录将错误显示为 Duplicate Header "Expires"。开始时间 错误是在请求发送到后端服务器后由 Apigee 引发的,它表示 后端服务器多次发送标头 Expires

  7. 进入跟踪记录中的 AX(分析的数据记录的)阶段,然后点击该阶段。
  8. 向下滚动到 Phase Details - Response Headers(阶段详情 - 响应标头)部分,并确定 X-Apigee-fault-codeX-Apigee-fault-source 的值,如下所示:

    查看放大图片

  9. 您将看到 X-Apigee-fault-codeX-Apigee-fault-source 的值 为 protocol.http.DuplicateHeadertarget,表示 导致此错误的原因是,针对 响应标头 Expires
    响应标头
    X-Apigee-fault-code protocol.http.DuplicateHeader
    X-Apigee-fault-source target
  10. 检查您是否在使用 代理链; 也就是说,如果目标服务器或目标端点正在调用 Apigee 中的另一个代理。

    1. 要确定这一点,请返回到 Request sent to target 服务器阶段。 点击 Show Curl

    2. 此时将打开 Curl for Request Sent to Target Server(请求发送到目标服务器)窗口,您可以从中执行以下操作: 确定目标服务器主机别名。

    3. 如果目标服务器主机别名指向虚拟主机别名,则该别名为代理。 链接。在这种情况下,您需要对链式代理重复上述所有步骤, 您可以确定导致 502 Bad Gateway 错误的实际原因。
    4. 如果目标服务器主机别名指向您的后端服务器,则表示 您的后端服务器将在响应中向 Apigee 发送重复的标头。

NGINX

<ph type="x-smartling-placeholder">

如需使用 NGINX 访问日志诊断错误,请执行以下操作:

  1. 如果您是 Private Cloud 用户,则可以使用 NGINX 访问日志 确定有关 HTTP 502 错误的关键信息。
  2. 查看 NGINX 访问日志:

    /opt/apigee/var/log/edge-router/nginx/ORG~ENV.PORT#_access_log

    其中ORGENVPORT# 替换为 实际值。

  3. 搜索查看在特定时间段内是否存在任何 502 错误 (如果问题在过去发生过)或者是否还有任何请求仍失败, 502
  4. 如果您发现任何包含 X-Apigee-fault-code 的 502 错误 protocol.http.DuplicateHeader 的值匹配,则 确定 X-Apigee-fault-source.

    NGINX 访问日志中的 502 错误示例

    以上 NGINX 访问日志中的示例条目包含 X- Apigee-fault-code X-Apigee-fault-source:

    响应标头
    X-Apigee-fault-code protocol.http.DuplicateHeader
    X-Apigee-fault-source target

原因:响应中的标头重复

诊断

  1. 确定使用 API 观察到的错误的错误代码错误来源 监控或 NGINX 访问日志(如常见诊断步骤中所述)。
  2. 如果故障来源的值为 target,则表示响应 包含重复标头。
  3. 您可以确定在响应中多次发送的实际标头 使用以下任一方法:

    错误消息

    使用错误消息

    1. 如果您有权查看从 Apigee Edge 收到的完整错误消息,请参阅 发送到 faultstringfaultstring 包含 已多次发送。

      示例错误消息:

      "faultstring":"Duplicate Header \"Expires\""
      
    2. 在上述错误消息中,您可以看到标头 Expires 已发送 如 faultstring 中所示。

    实际请求

    使用实际请求

    1. 如果您无权访问向目标服务器发出的实际请求,则获取 相应的 curl 命令, 使用跟踪工具第 10.a 步和 第 10.b.
    2. 如果您有权访问发送到目标服务器应用的实际请求, 然后执行以下步骤:

      1. 调用目标服务器。

        针对此示例中使用的目标服务器的示例请求

        curl -X GET "https://BACKEND_SERVER_HOST/response-headers?Expires=Mon%2C%2021%20June%202021%2007%3A28%3A00%20GMT&Expires=Mon%2C%2021%20June%202021%2007%3A28%3A00%20GMT" -v
        
      2. 验证响应中显示的标头列表。

        来自此示例中所用目标服务器的示例响应

        * ...Trimmed...
        > GET /response-headers?Expires=Mon%2C%2021%20June%202021%2007%3A28%3A00%20GMT&Expires=Mon%2C%2021%20June%202021%2007%3A28%3A00%20GMT HTTP/2
        > Host: BACKEND_SERVER_HOST
        > User-Agent: curl/7.64.1
        > Accept: */*
        >
        * Connection state changed (MAX_CONCURRENT_STREAMS == 128)!
        < HTTP/2 200
        < date: Fri, 02 Jul 2021 05:29:07 GMT
        < content-type: application/json
        < content-length: 166
        < server: gunicorn/19.9.0
        < Expires: Mon, 21 June 2021 07:28:00 GMT
        < Expires: Mon, 21 June 2021 07:28:00 GMT
        < access-control-allow-origin: *
        < access-control-allow-credentials: true
        <
        ----<Response BODY>------
        * Connection #0 to host httpbin.org left intact
        * Closing connection 0
        

        在上面的示例请求中,发送更多标头 Expires 。因此,此请求会失败,并显示 502 Bad Gateway 错误和错误代码:protocol.http.DuplicateHeader

        <ph type="x-smartling-placeholder">
      3. 如果 faultstring 中名称出现的标头出现, 在后端服务器响应中多次出现,则就是 错误。在上述情况下,标头 Expires 会发送多次。

        <ph type="x-smartling-placeholder">

分辨率

解决重复问题

方法 1 [推荐方法] 修复后端服务器,使其不包含重复标头

<ph type="x-smartling-placeholder">
  1. 分析特定后端服务器发送重复标头的原因 Expires 的值,并验证 API 代理是否可以接受该值。在 大多数情况下,根据 HTTP 规范, RFC7230
  2. 如果您不希望这样,请修改您的目标服务器应用,使其不发送重复的标头。 在上面的示例中,您会发现标头 Expires 发送了 两次,这并不可取。要解决此问题 目标服务器仅传递一次 Expires 标头。
  3. 如果需要,并且您希望允许出现重复的标头,请转到 选项 2 使用 CwC 属性

CwC

选项 2 使用 CwC 属性

<ph type="x-smartling-placeholder">

Apigee 提供 CwC 属性 HTTPHeader.<HeaderName> - 允许客户端应用和 服务器向 Apigee Edge 中的 API 代理发送重复的标头。

CwC 属性
HTTPHeader.<HeaderName> allowDuplicates,multivalued

例如,可以在消息处理器上设置以下属性以允许重复数据 以及标头 Expires 的多个值。

HTTPHeader.Expires=allowDuplicates, multiValued
  1. 如果您是 Private Cloud 用户,可将该属性配置为禁止使用 Apigee 不出现 502 Bad Gateway 错误,即使请求包含 使用 方法指南:配置消息处理器以使用重复标头
  2. 如果您是公有云用户,请与 Apigee Edge 支持团队联系以配置此 媒体资源。

规范

Apigee 返回 502 Bad Gateway 错误响应,因为它预期 后端服务器将根据以下 RFC 规范进行操作:

规范
<ph type="x-smartling-placeholder"></ph> RFC 7230,第 3.2.2 节:字段顺序
<ph type="x-smartling-placeholder"></ph> RFC 7230,第 3.2 节:标头字段

如果您仍然需要 Apigee 支持团队的任何帮助,请转到 必须收集诊断信息

必须收集的诊断信息

请收集以下诊断信息,然后联系 Apigee Edge 支持团队

如果您是公有云用户,请提供以下信息:

  • 组织名称
  • 环境名称
  • API 代理名称
  • 完成用于重现 502 错误的 curl 命令
  • API 请求的跟踪文件

如果您是 Private Cloud 用户,请提供以下信息:

  • 观察到失败请求的完整错误消息
  • 环境名称
  • API 代理软件包
  • API 请求的跟踪文件
  • NGINX 访问日志:

    /opt/apigee/var/log/edge-router/nginx/ORG~ENV.PORT#_access_log

    其中ORGENVPORT# 替换为 实际值。

  • 消息处理器系统日志 /opt/apigee/var/log/edge-message-processor/logs/system.log