404 无法识别主机 <虚拟主机名> 和网址:<路径> 的代理

您正在查看 Apigee Edge 文档。
转到 Apigee X 文档
info

问题

客户端应用会收到 HTTP 状态代码 404,并显示消息 Not Found 和错误消息 Unable to identify proxy for host: VIRTUAL_HOST and url: PATH ,以作为对 API 调用的响应。

此错误表示 Edge 找不到指定虚拟主机和路径的 API 代理。

错误消息

您会收到以下 HTTP 状态代码:

HTTP/1.1 404 Not Found

您还会看到类似于以下内容的错误消息:

{
   "fault":{
      "faultstring":"Unable to identify proxy for host: default and url: \/oauth2\/token",
      "detail":{
         "errorcode":"messaging.adaptors.http.flow.ApplicationNotFound"
      }
   }
}

上述错误消息表示 Edge 找不到 default 虚拟主机和 /oauth2/token 路径的 API 代理。

可能的原因

以下列出了一些可能导致此错误的原因:

原因 说明 适用的问题排查说明
API 代理未与特定虚拟主机关联 特定 API 代理未配置为接受错误消息中指定的虚拟主机上的请求。 Edge Public 和 Private Cloud 用户
在 API 代理的新部署修订版本中移除了虚拟主机 如果客户端仍在使用的特定虚拟主机从新部署的修订版本中移除,则可能会导致此问题。 Edge Public 和 Private Cloud 用户
路径未与任何 API 代理关联 特定 API 代理未配置为接受错误消息中指定的路径上的请求。 Edge Public 和 Private Cloud 用户
API 代理未部署在环境中 特定 API 代理未部署在您尝试发出 API 请求的特定环境中。 Edge Public 和 Private Cloud 用户
环境未加载到消息处理器上 由于错误,特定环境(您尝试发出 API 请求的环境)未 加载到消息处理器上。 Edge Private Cloud 用户
API 代理未部署在一个或多个消息处理器上 由于部署期间缺少 事件通知,API 代理可能未部署在一个或多个消息处理器上。 Edge Private Cloud 用户

常见诊断步骤

NGINX 和消息处理器日志有助于排查 404 错误。 请按照以下步骤检查日志:

  1. 使用以下命令查看 NGINX 日志:
    /opt/apigee/var/log/edge-router/nginx/ORG~ENV.PORT#_access_log
  2. 检查日志条目中是否存在以下字段:
    字段
    Upstream_status, status 404
    X-Apigee-fault-code messaging.adaptors.http.flow.ApplicationNotFound

    记下日志中的消息 ID。

  3. 检查消息处理器日志 (/opt/apigee/var/log/edge-message-processor/logs/system.log) 查看特定 API 是否有 messaging.adaptors.http.flow.ApplicationNotFound,或者 API 请求是否有第 2 步中的唯一消息 ID。

    消息处理器日志中的错误消息示例

  4. NIOThread@1 ERROR ADAPTORS.HTTP.FLOW - AbstractRequestListener.onException() : Request:POST, uri:/weather, message Id:null, exception:com.apigee.rest.framework.ResourceNotFoundException{ code = messaging.adaptors.http.flow.ApplicationNotFound, message = Unable to identify proxy for host: vh1 and url: /weather, associated contexts = []}, context:Context@342ea86b input=ClientInputChannel(SSLClientChannel[Accepted: Remote:10.123.123.123:8443 Local:10.135.33.68:62092]@1206954 useCount=1 bytesRead=0 bytesWritten=0 age=1ms  lastIO=0ms  isOpen=true)

    上面的日志显示,错误代码和错误消息如下:

    code = messaging.adaptors.http.flow.ApplicationNotFound,
    message = Unable to identify proxy for host: vh1 and url: /weather

原因:API 代理未与特定虚拟主机关联

如果 API 代理未配置为接受特定虚拟主机的请求,则 我们可能会收到 404 Not Found 响应,并显示错误消息 Unable to identify proxy for host: VIRTUAL_HOST and url: PATH.

诊断

  1. 检查 API 代理的 Proxy Endpoint 配置,查看 API 代理是否 配置为接受错误中指定的虚拟主机的请求。这由 VirtualHost 元素表示。我们来看一个 ProxyEndpoint 配置示例,以便了解这一点。

    Proxy Endpoint 配置示例,显示 API 代理接受 安全虚拟主机上的请求

  2. 假设虚拟主机在特定环境中定义如下:
    名称 端口 主机别名
    default 80 myorg-prod.apigee.net
    secure 443 myorg-prod.apigee.net
  3. 您使用网址 http://myorg-prod.apigee.net/weatherdefault VirtualHost 发出 API 请求
  4. 由于 ProxyEndpoint 没有 default VirtualHost(如上例所示),因此您会收到 404 响应代码,并显示以下错误消息:
    {"fault":{"faultstring":"Unable to identify proxy for host: default and url: \/weather","detail":{"errorcode":"messaging.adaptors.http.flow.ApplicationNotFound"}}}
  5. 请转到下面的“解决方案”部分来解决此问题。
  6. 如果 ProxyEndpoint 配置为接受 default VirtualHost 上的请求,请转到下一个原因 - 路径未与任何 API 代理关联

解决方案

  1. 将缺少的 VirtualHost 添加到 ProxyEndpoint 配置中,以 解决此问题。对于上面显示的示例,您可以按如下方式将默认 VirtualHost 添加到 ProxyEndpoint 配置中:
    <VirtualHost>default</VirtualHost>

    Proxy Endpoint 配置示例,显示正在添加的默认> VirtualHost>

  2. 或者,在上面提到的示例中,如果您打算仅将 secure VirtualHost 用于此特定 API 代理,则仅使用 HTTPS 协议向 secure VirtualHost 发出 API 请求:
    https://myorg-prod.apigee.net/weather

原因:在 API 代理的新部署修订版本中移除了虚拟主机

如果在移除特定虚拟主机 (该虚拟主机是之前部署的修订版本的一部分)后部署了 API 代理的新修订版本,而客户端 仍在使用的特定虚拟主机用于发出 API 请求,则可能会导致此问题。

诊断

  1. 检查 API 代理的 Proxy Endpoint 配置,查看 API 代理是否 配置为接受错误中指定的虚拟主机的请求。这由 ProxyEndpoint 配置中的 VirtualHost 元素表示。
  2. 如果错误中指定的虚拟主机在 ProxyEndpoint 配置中不存在,请执行以下步骤。否则,请转到下一个原因 - 路径未与任何 API 代理关联
  3. 将之前部署的修订版本的 ProxyEndpoint 配置与当前 部署的修订版本进行比较。
    1. 例如,假设您之前部署的修订版本为 5,而您的 当前部署的修订版本为 6
      • 在修订版本 5 的 Proxy Endpoint 中配置的虚拟主机
      • <HTTPProxyConnection>
            <BasePath>/weather</BasePath>
            <Properties/>
            <VirtualHost>vh1</VirtualHost>
        </HTTPProxyConnection>
      • 在修订版本 6 的 Proxy Endpoint 中配置的虚拟主机
      • <HTTPProxyConnection>
            <BasePath>/weather</BasePath>
            <Properties/>
            <VirtualHost>secure</VirtualHost>
        </HTTPProxyConnection>
    2. 在上面的示例中,VirtualHost vh1 存在于 revision 5, 中,但在 revision 6 中被移除并替换为 VirtualHost secure
    3. 因此,如果您或您的客户端使用 VirtualHost vh1(属于 revision 5)向此 API 代理发出请求,则会收到 404 响应代码,并显示以下错误消息:
      {"fault":{"faultstring":"Unable to identify proxy for host: vh1 and url: \/weather","detail":{"errorcode":"messaging.adaptors.http.flow.ApplicationNotFound"}}}
  4. 检查当前部署的修订版本中是否有意 intentionallyunintentionally 无意地进行了虚拟主机更改,并采取 “ Resolution 解决方案”部分中说明的相应措施。

解决方案

如果您发现新修订版本中移除了一个或多个虚拟主机,这可能是故意的,也可能是意外的。对于每种情况,请执行以下解决方案/建议步骤来解决此问题。

场景 #1:有意更改

如果虚拟主机移除是有意的,您可以选择以下某个 选项,建议采用第一个选项:

  1. 使用不同的基本路径创建新代理,并使用不同的虚拟主机 (该虚拟主机在之前部署的修订版本中不存在)。
  2. 如果您想继续使用现有 API 代理,但使用不同的虚拟主机, 最好保留现有虚拟主机并添加其他虚拟主机。

    这样可确保此 API 代理的用户不受更改的影响。

  3. 如果您想使用现有 API 代理,并且仅使用不同的虚拟主机,请 提前通知您的用户,并在维护期间进行此更改。

    这样可确保此 API 代理的用户了解更改,并且他们 可以使用不同的虚拟主机来调用此 API 代理。因此,他们不会受到更改的影响。

场景 #2:意外更改

如果虚拟主机移除是意外的,而不是有意的,请执行以下操作:

  1. 更新当前部署的修订版本中的 ProxyEndpoint 配置,以使用 之前部署的修订版本中使用的相同虚拟主机。在上面的示例中,将以下部分从:
    <HTTPProxyConnection>
        <BasePath>/weather</BasePath>
        <Properties/>
        <VirtualHost>secure</VirtualHost>
    </HTTPProxyConnection>

    更改为

    <HTTPProxyConnection>
        <BasePath>/weather</BasePath>
        <Properties/>
        <VirtualHost>vh1</VirtualHost>
    </HTTPProxyConnection>
  2. 重新部署修订版本。

最佳做法

始终建议在维护期间 或流量预计最少时部署新代理或新修订版本,这样可以避免部署期间出现的任何问题,或最大限度地减少对流量的影响。

原因:路径未与任何 API 代理关联

如果 API 代理未配置为接受 API 请求网址中使用的特定路径的请求,则我们可能会收到 404 Not Found 响应,并显示错误消息 Unable to identify proxy for host: VIRTUAL_HOST and url: PATH.

诊断

  1. 查看您打算发出 API 请求的特定 API 代理的 ProxyEndpoint 配置。
  2. 检查 API 代理是否配置为接受错误消息中指示的特定路径的请求。您可以通过执行 场景 #1场景 #2中的步骤来完成此操作。

场景 #1:路径与 API 代理的基本路径不匹配

  1. 如果错误消息中指示的 path 与特定 API 代理的 basepath 不同,或者它不是以 basepath 开头,则可能是导致错误的原因。
  2. 我们来举例说明:
    1. 预期 API 代理的 basepath/weather
    2. API 请求网址为 https://myorg-prod.apigee.net/climate。这意味着 API 请求网址中使用的路径为 /climate.
  3. 在此示例中,pathbasepath 不同,并且不是以 basepath 开头。因此,您会收到以下错误:
    {
       "fault":{
          "faultstring":"Unable to identify proxy for host: secure and url: \/climate",
          "detail":{
             "errorcode":"messaging.adaptors.http.flow.ApplicationNotFound"
          }
       }
    }

解决方案

  1. 确保 API 请求网址中使用的 path 与特定 API 代理的 basepath 相同。
  2. 在上面的示例中,API 请求网址应如下所示:
    {
    https://myorg-prod.apigee.net/weather

场景 #2:路径与任何可用的条件流都不匹配

  1. 如果 API 请求网址中使用的 pathbasepath 开头,则错误消息中指示的 path suffixbasepath 之后的部分)可能与任何条件流都不匹配,这可能会导致 404 错误。
  2. 我们来举例说明:
    1. 预期 API 代理的 basepath/weather
    2. API 请求网址为 https://myorg-prod.apigee.net/weather/Delhi。这意味着 API 请求网址中使用的路径为 /weather/Delhi.
  3. 在此示例中,pathbasepath /weather 开头。 此外,它还具有 /Delhipath suffix
  4. 现在,检查 ProxyEndpoint 中是否有任何条件流。
  5. 如果没有条件流或只有几个非条件流,请转到下一个原因 - API 代理未部署在环境中
  6. 如果 ProxyEndpoint 仅包含条件流,请检查以下内容:
    1. 如果所有这些条件流中的条件都检查特定的 proxy.pathsuffix (基本路径之后的路径)。
    2. 并且,如果 path suffix 在 API 请求网址中指定的与任何 条件都不匹配,则会导致错误。
  7. 假设我们在 ProxyEndpoint 中有两个流,并且这两个流都是 条件流,如下所示:
    <Condition>(proxy.pathsuffix MatchesPath "/Bangalore") and (request.verb = "GET")</Condition>
    
    <Condition>(proxy.pathsuffix MatchesPath "/Chennai") and (request.verb = "GET")</Condition>
    1. 在上面的示例中,我们有两个条件流,一个将 proxy.pathsuffix(基本路径之后的路径)与/Bangalore匹配,另一个与/Chennai匹配。但没有与 /Delhi 匹配的条件流,而 是在 API 请求网址中传递的 path suffix
    2. 这是导致 404 错误的原因。因此,您会收到以下错误:
      {
         "fault":{
            "faultstring":"Unable to identify proxy for host: secure and url: \/weather\/Delhi",
            "detail":{
               "errorcode":"messaging.adaptors.http.flow.ApplicationNotFound"
            }
         }
      }

解决方案

  1. 确保 path suffix 与代理端点中的至少一个条件流匹配。
  2. 在上面的示例中,您可以使用以下方法之一来解决此错误:
    1. 如果您想为路径 /Delhi、 执行任何特定政策集,请添加一个单独的流,其中包含所需的政策集,并确保有一个条件 与 /proxy.pathsuffix /Delhi 匹配,如下所示:
      <Condition>(proxy.pathsuffix MatchesPath "/Delhi") and (request.verb = "GET")</Condition>
    2. 如果您想为路径 /Delhi 执行通用政策集,请在 通用流中确保有一个条件允许使用通用 /proxy.pathsuffix。也就是说,它将允许使用 basepath /weather 之后的任何路径,如下所示:
      <Condition>(proxy.pathsuffix MatchesPath "/**") and (request.verb = "GET")</Condition>

如果 ProxyEndpoint 具有正确的 basepath,并且 API 网址中指定的 path suffix 与其中一个条件流匹配,请转到下一个原因 - API 代理未部署在环境中

原因:API 代理未部署在环境中

诊断

  1. 确定 API 请求网址中使用的主机别名所在的环境。 为此,您可以在 Edge 界面中检查组织每个环境中的所有虚拟主机的详细信息。

    例如,假设有以下配置:

    • 如果 http://myorg-prod.apigee.net/weather 是您的网址,则 myorg-prod.apigee.net 是主机别名。
    • 主机别名 myorg-prod.apigee.net 配置为组织 prod 环境中某个 虚拟主机的一部分。
  2. 检查特定 API 代理是否部署在上面第 1 步中确定的特定环境中。
  3. 如果 API 代理未部署在特定环境中,则会导致 404 错误。
    1. 因此,在上面第 1 步中使用的示例中,假设 API 代理未部署在 prod 环境中,则会导致错误。
    2. 请转到下面的“解决方案”部分。
  4. 如果 API 代理部署在特定环境中,请转到下一个原因 - 环境未加载到消息处理器上

解决方案

将 API 代理部署在您打算发出 API 请求的特定环境中。

原因:环境未加载到消息处理器上

诊断

  1. 登录到每个消息处理器,并使用以下命令检查您发出 API 请求的特定环境是否已加载到消息处理器上:
    curl -v 0:8082/v1/runtime/organizations/<orgname>/environments
  2. 如果特定环境列为上述命令的一部分,请转到下一个原因 - API 代理未部署在一个或多个消息处理器上
  3. 如果未列出特定环境,请检查 /opt/apigee/var/log/edge-message-processor/logs/system.log/opt/apigee/var/log/edge-message-processor/logs/startupruntimeerrors.log 上的 消息处理器,了解在加载环境期间是否有任何错误。
  4. 可能会有许多不同的错误导致无法在消息处理器上加载环境。 解决方案取决于发生的错误。

解决方案

由于多种原因,环境可能未加载到消息处理器上。本部分 说明了可能导致此问题的几个原因,并介绍了如何解决 此问题。

  1. 如果您在消息处理器日志中看到以下错误之一,则表示这是由在指定环境中添加到指定密钥库/信任库的证书/密钥发现的 问题导致的。

    错误 #1:java.security.KeyStoreException: Cannot overwrite own certificate

    2018-01-30 12:04:38,248 pool-47-thread-4 ERROR MESSAGING.RUNTIME - AbstractConfigurator.propagateEvent() : Error while handling the update for the Configurator
    com.apigee.kernel.exceptions.spi.UncheckedException: Failed to add certificate : mycert in key store : mytruststore in environment : test
    at com.apigee.entities.configurators.KeyStore.setCertificateEntry(KeyStore.java:156) ~[config-entities-1.0.0.jar:na]
    at com.apigee.entities.configurators.KeyStore.handleUpdate(KeyStore.java:101) ~[config-entities-1.0.0.jar:na]
    at com.apigee.entities.AbstractConfigurator.propagateEvent(AbstractConfigurator.java:85) ~[config-entities-1.0.0.jar:na]
    at com.apigee.messaging.runtime.Environment.handleUpdate(Environment.java:238) [message-processor-1.0.0.jar:na]
    
    Caused by: java.security.KeyStoreException: Cannot overwrite own certificate
    at com.sun.crypto.provider.JceKeyStore.engineSetCertificateEntry(JceKeyStore.java:355) ~[sunjce_provider.jar:1.8.0_151]
    at java.security.KeyStore.setCertificateEntry(KeyStore.java:1201) ~[na:1.8.0_151]
    at com.apigee.entities.configurators.KeyStore.setCertificateEntry(KeyStore.java:153) ~[config-entities-1.0.0.jar:na]

    ... 20 common frames omitted

    2018-01-30 12:04:38,250 pool-47-thread-4 ERROR MESSAGING.RUNTIME - AbstractConfigurator.rollbackTransaction() : Error in processing the changes : Unknown resource type cert

    错误 #2:java.security.KeyStoreException: Cannot overwrite secret key

    2017-11-01 03:28:47,560 pool-21-thread-7 ERROR MESSAGING.RUNTIME - AbstractConfigurator.propagateEvent() : Error while handling the update for the Configurator
    com.apigee.kernel.exceptions.spi.UncheckedException: Failed to add certificate : mstore in key store : myTruststore in environment : dev
    at com.apigee.entities.configurators.KeyStore.setCertificateEntry(KeyStore.java:156) ~[config-entities-1.0.0.jar:na]
    at com.apigee.entities.configurators.KeyStore.handleUpdate(KeyStore.java:101) ~[config-entities-1.0.0.jar:na]
    ...
    Caused by: java.security.KeyStoreException: Cannot overwrite secret key
    at com.sun.crypto.provider.JceKeyStore.engineSetCertificateEntry(JceKeyStore.java:354) ~[sunjce_provider.jar:1.8.0_144]
    at java.security.KeyStore.setCertificateEntry(KeyStore.java:1201) ~[na:1.8.0_144]
    at com.apigee.entities.configurators.KeyStore.setCertificateEntry(KeyStore.java:153) ~[config-entities-1.0.0.jar:na]
    ... 20 common frames omitted
    
    2017-11-01 03:28:47,562 pool-21-thread-7 ERROR MESSAGING.RUNTIME - AbstractConfigurator.rollbackTransaction() : Error in processing the changes : Unknown resource type cert
  2. 使用以下管理 API 调用获取上一步中显示的错误消息中指定的密钥库/信任库的详细信息:
    curl -v "http://<management-IPaddress>:8080/v1/organizations/<org-name>/environments/<env-name>/keystores/myTruststore" -u <user> 

    输出示例

    {
       "certs":[
          "mycert",
          "mycert-new"
       ],
       "keys":[
          "mycert"
       ],
       "name":"myTruststore"
    }
  3. 输出示例显示,信任库 myTruststore中有两个证书和一个密钥。信任库通常不包含密钥。如果包含密钥,最好只有一个证书和一个密钥。
  4. 使用以下 API 获取有关这两个证书的详细信息:
    curl -s http://<management-IPaddress>:8080/v1/runtime/organizations/<org-name>/environments/<env-name>/keystores/<keystore-name>/certs/<cert-name>
    
  5. 检查每个证书的失效日期,并确定已过期/较旧的证书。
  6. 从信任库 myTruststore 中删除已过期或不需要的证书。

如果问题仍然存在,或者您看到除上述第 1 步中提到的错误之外的任何错误,请转到必须收集的诊断信息

原因:API 代理未 部署在一个或多个消息处理器上

API 代理可能未部署在一个或多个消息处理器上。此问题很少发生,主要是由于在部署特定 API 代理期间,管理服务器缺少向 消息处理器发送的事件通知。在这种情况下,您也无法在 Edge 界面中创建跟踪会话。

诊断

  1. 登录到每个消息处理器,并使用以下命令检查是否部署了 API 代理的特定修订版本:
    curl -v 0:8082/v1/runtime/organizations/<orgname>/environments/<envname>/apis/<apiname>/revisions
    
  2. 如果 API 代理的特定修订版本未显示为上述第 1 步中提到的命令 的输出,请按照 “解决方案”中的说明重启特定消息处理器。
  3. 对所有消息处理器重复执行第 1-2 步。
  4. 如果 API 代理的特定修订版本部署在所有消息处理器上,则 这不是导致此问题的原因。请转到 必须收集的诊断信息

解决方案

重启未部署 API 代理特定修订版本的特定消息处理器 。

/opt/apigee/apigee-service/bin/apigee-service edge-message-processor restart

使用 API Monitoring 诊断问题

API Monitoring 借助 API Monitoring,您可以快速找出问题区域 以诊断错误、性能和延迟时间问题及其来源,例如开发者应用、 API 代理、后端目标或 API 平台。

对于此问题,您可以前往 API Monitoring > 调查 页面,选择适当的日期、代理等,您可能会看到以下详细信息:

界面中的故障代码和状态代码

  • 故障代码messaging.adaptors.http.flow.ApplicationNotFound
  • 状态代码404
  • 故障来源ApigeeMP

此外,您还可以点击上面的屏幕截图中显示的查看日志 ,并进一步检查。

查看日志

通过一个示例场景,演示如何 排查 5xx 问题,以使用 API Monitoring 解决 API 问题。例如,您可能需要设置提醒,以便在404状态代码的数量超过特定阈值时收到通知。

必须收集的诊断信息

如果按照上述说明操作后问题仍然存在,请收集以下 诊断信息。与 Apigee Edge 支持团队联系,并与他们分享这些信息。

  1. 如果您是 Public Cloud 用户,请提供以下信息:
    • 组织名称
    • 环境名称
    • API 代理名称
    • 用于重现错误的完整 curl 命令
  2. 如果您是 Private Cloud 用户,请提供以下信息:
    • 观察到的完整错误消息
    • 环境名称
    • API 代理软件包
    • 消息处理器日志 /opt/apigee/var/log/edge-message-processor/logs/system.log
    • 每个消息处理器上以下命令的输出。
    • curl -v 0:8082/v1/runtime/organizations/<orgname>/environments
      curl -v 0:8082/v1/runtime/organizations/<orgname>/environments/<envname>/apis/<apiname>/revisions
            
  3. 有关您已尝试的此 playbook 中的哪些部分的详细信息,以及有助于我们快速解决此问题的任何其他见解。