【问题标题】:GCM (legacy FCM) sends GOAWAY HTTP/2 framesGCM (legacy FCM) 发送 GOAWAY HTTP/2 帧
【发布时间】:2021-07-03 04:17:43
【问题描述】:

我们的推送后端使用 GCM API 向 Android 设备发送通知。
端点:https://fcm.googleapis.com/fcm/send
HTTP 客户端:Java 11 Http Client(带有 HTTP/2 设置):

var httpClient = HttpClient.newBuilder()
    .version(HttpClient.Version.HTTP_2)
    // ...
    .build();

问题
有时我们会从 GCM 获得 GOAWAY 帧。但是java http client hides 这些帧的错误代码和有效负载(只是抛出一些通用异常)。所以我们不知道是什么导致了GOAWAY

问题

  1. 这是 GCM API 的预期行为吗?
  2. 可能是什么原因造成的?
  3. 如何调试?

【问题讨论】:

    标签: java firebase-cloud-messaging google-cloud-messaging http2


    【解决方案1】:

    很难确定为什么 GCM 会发送 GOAWAY - 只有 GCM 团队才能真正回答这个问题。然而,一些常见的原因是:

    • 您的客户端连接到的服务器正在关闭以进行维护。在此之前,它会进入耗尽模式,允许完成正在进行的请求,同时阻止新的请求。这是通过发送GOAWAY 通知客户端不应在该连接上启动新请求来实现的。
    • 服务器希望客户端迁移到不同的连接以实现负载平衡

    这意味着发送GOAWAY 的服务器不是错误,这只是云设置中的预期结果。

    HTTP/2 规范提供了有关如何处理 GOAWAY 的更多信息:https://www.rfc-editor.org/rfc/rfc7540#section-6.8

    关于处理它:理想情况下,您的 HTTP/2 客户端可能已经在内部完全做到了:

    • 如果在没有请求处于活动状态时收到GOAWAY 帧,它应该为下一个请求创建一个新连接
    • 如果它在发送请求时接收到GOAWAY 帧,并且如果GOAWAY 帧表明请求尚未处理,则可以创建新客户端并重试请求。即使它是一个非幂等请求(如POST),它也可以工作,因为我们知道服务器尚未处理该请求。

    如果 JDK11 客户端没有自动执行此操作,那么您在这里真正可以做的就是在应用层重试。

    根据is there any way to handle HTTP/2 Goaway received IOException in HttpClient java?,似乎客户端可能会抛出一个IOException,其消息包含GOAWAY received。这可能是重试的好信号。

    【讨论】:

      猜你喜欢
      • 2017-05-26
      • 2021-03-21
      • 1970-01-01
      • 2022-08-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多