简体   繁体   English

GCM (legacy FCM) 发送 GOAWAY HTTP/2 帧

[英]GCM (legacy FCM) sends GOAWAY HTTP/2 frames

Our push backend uses GCM API to send notifications to Android devices.我们的推送后端使用GCM API向 Android 设备发送通知。
Endpoint: https://fcm.googleapis.com/fcm/send端点: https://fcm.googleapis.com/fcm/send
HTTP client: Java 11 Http Client (with HTTP/2 setting): HTTP 客户端: Java 11 Http 客户端(使用 HTTP/2 设置):

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

Problem问题
Sometimes we get GOAWAY frames from GCM.有时我们会从 GCM 获得GOAWAY帧。 But java http client hides both error-code and payload for those frames (just throws some generic exception).但是java http 客户端隐藏了这些帧的错误代码和有效负载(只是抛出了一些通用异常)。 So we don't know what is causing GOAWAY .所以我们不知道是什么导致GOAWAY

Questions问题

  1. Is it an expected behavior of GCM API?这是 GCM API 的预期行为吗?
  2. What could cause it?什么可能导致它?
  3. How to debug it?如何调试它?

It's hard to tell for sure why GCM sends GOAWAY - only the GCM team can really answer this.很难确定为什么 GCM 会发送GOAWAY - 只有 GCM 团队才能真正回答这个问题。 However some of the usual reasons for it are:然而,一些常见的原因是:

  • The server your client is connected to is going down for maintainence.您的客户端连接到的服务器正在关闭以进行维护。 Before doing that it enters a draining mode that allows to complete ongoing requests while preventing new ones.在此之前,它会进入耗尽模式,允许完成正在进行的请求,同时阻止新的请求。 This is achieved by sending a GOAWAY that informs the client that no new requests should be started on that connection.这是通过发送一个GOAWAY通知客户端不应在该连接上启动新请求来实现的。
  • The server wants the client to migrate to a different connection for load balancing purposes服务器希望客户端迁移到不同的连接以达到负载平衡的目的

That means a server sending a GOAWAY is not a bug, it's just something to be expected in a cloud setup.这意味着发送GOAWAY的服务器不是错误,这只是云设置中的预期。

The HTTP/2 specifciation provides some further information on how to handle GOAWAY : https://tools.ietf.org/html/rfc7540#section-6.8 HTTP/2 规范提供了有关如何处理GOAWAY的更多信息: https://tools.ietf.org/html/rfc7540#section-6.8

Regarding handling it: Ideally your HTTP/2 client might already do that fully internally:关于处理它:理想情况下,您的 HTTP/2 客户端可能已经在内部完全做到了:

  • if it receives a GOAWAY frame while no request is active it should create a new connection for the next request如果它在没有请求处于活动状态时收到GOAWAY帧,它应该为下一个请求创建一个新连接
  • if it receives a GOAWAY frame while a request has been sent, and if that GOAWAY frame indicates the request hasn't been processed, a new client can be created and the request retried.如果它在发送请求时收到GOAWAY帧,并且如果该GOAWAY帧指示请求尚未处理,则可以创建新客户端并重试请求。 This works even if its a non-idempotent request (like a POST ), since we know the server hasn't processed the request yet.即使它是一个非幂等请求(如POST ),这也有效,因为我们知道服务器尚未处理该请求。

If the JDK11 client does not do that automatically, the only thing you can really do here is retry on application layer.如果 JDK11 客户端没有自动执行此操作,那么您在这里真正可以做的就是在应用层重试。

According to is there any way to handle HTTP/2 Goaway received IOException in HttpClient java?根据有什么方法可以处理 HttpClient java 中的 HTTP/2 Goaway 收到的 IOException? it seems like the client might throw an IOException whose message contains GOAWAY received .似乎客户端可能会抛出一个IOException ,其消息包含GOAWAY received That might be a good signal to retry.这可能是重试的好信号。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM