【问题标题】:IOException "Socket is closed: Unknown socket_descriptor" using java.net.DatagramSocket with Google App EngineIOException "Socket is closed: Unknown socket_descriptor" 使用 java.net.DatagramSocket 和 Google App Engine
【发布时间】:2015-05-19 01:32:41
【问题描述】:

我正在使用java.net.DatagramSocket 从 Google App Engine servlet 向 statsd 服务器发送 UDP 数据包。这通常有效;但是,我们会定期看到以下异常:

IOException - Socket is closed: Unknown socket_descriptor..

当这些 IOExceptions 发生时,调用DatagramSocket.isClosed() 返回false

这个问题经常发生以至于令人担忧,尽管我已经采取了一些解决方法(分配一个新套接字并使用 DeferredTask 队列重试),但最好了解这些错误的根本原因。

Google docs 提到,“套接字可能会在 2 分钟不活动后被回收;任何套接字操作都会使套接字再存活 2 分钟。”我不清楚这将如何影响 UDP 数据报。但是,我的一个怀疑是这在某种程度上与 GAE 实例生命周期有关。

我的代码(经过清理和提取)如下所示:

DatagramSocket _socket;

void init() {
    _socket = new DatagramSocket();
}

void send() {
    DatagramPacket packet = new DatagramPacket(<BYTES>, <LENGTH>, <HOST>, <PORT>); 
    _socket.send(packet);
}

感谢您对此的任何反馈!

【问题讨论】:

  • '我读到了一些关于DatagramSockets 的激进超时管理'在哪里?
  • 您引用的页面上没有出现“超时”一词。你指的是'Daily Data and Per-Minute (Burst) Data Limits'吗?
  • “回收”和“空闲”这两个词也不会出现在该页面上。你在说什么?
  • 我明白了。当你把一个词放在引号中时,它意味着它是一个字面引用。不是。未指定“回收”套接字的机制,但完全关闭与其他任何事情一样合理。
  • 正如我所指出的,当此异常发生时isClosed() 返回false

标签: java sockets google-app-engine


【解决方案1】:

解决此问题的方法是简单地使用几个帮助方法getSocket()releaseSocket() 来管理单个静态 DatagramSocket 实例,以通过 release 方法释放抛出 IOExceptions 的套接字,然后在下次访问时通过获取方法。此代码中未显示重试逻辑以重试失败的 socket.send()。在负载测试下,这似乎可以可靠地工作。

try {

    DatagramPacket packet = new DatagramPacket(<BYTES>, <LENGTH>, <HOST>, <PORT>);

    getSocket().send(packet);

} catch (IOException ioe) {

    releaseSocket();

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-04-28
    • 2013-07-15
    • 2012-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多