【发布时间】:2012-01-08 14:07:40
【问题描述】:
对不起,这是一个记录..
旧设置
我有一个 J2ME 客户端应用程序,它以 3 秒的间隔连接到服务器。连接在单独的线程中处理。线程在while循环中运行,执行如下:
- 打开 HTTP 连接
- 接收响应并发送到主 UI 线程进行处理
- 睡眠 3 秒
重复
服务器是 Apache 并且 KeepAlive 已关闭。来自客户端的 HTTP 请求的超时时间为 10 秒。每个循环大约需要 4.5 秒(总延迟 1.5 秒)。
每隔一段时间(每 1 或 2 小时一次),在低覆盖率(3G/GPRS 信号不佳)下,线程会收到一个 IO 块并在上面的第 1 步挂起。我认为正在发生的事情是沿线某处的连接已经断开,但应用程序不知道它并正在等待响应。我认为应该归咎于网络(在这种情况下为 O2)。连接可能会保持活动状态 30 分钟,最终终止并向应用程序返回 -1 响应长度,并且线程最终会继续。为了解决这个相对罕见的问题,如果响应时间超过 60 秒,我只是放弃了该线程,并创建了一个新线程。
直到最近这还不是一个大问题,但是我们改变了我们的网络设置如下:
新设置
- 由于带宽限制较低,我们将间隔减慢到 5 秒。
- 我们现在通过 SSL 隧道将所有连接路由到我们的服务器。
- 来自客户端的 HTTP 请求在 App 上仍有 10 秒的超时时间*
完成这些更改的循环大约需要 7.5 秒(总延迟时间为 2.5 秒)。延迟增加的原因是每个连接都需要通过 SSL 握手(由于 KeepAlive 关闭)。我们被建议在 apache 服务器上打开 KeepAlive,这意味着一次握手,然后为后续请求建立持久的 http 连接。我们这样做了,并且在很大程度上提高了连接速度。循环时间缩短到 6.5 秒。
所以我们现在可以将其添加到新设置的配置更改中:
- HTTP KeepAlive 已在服务器上切换为 ON(以启用持久 TCP 连接)
但是,在较差的 3G/GPRS 区域,线程阻塞问题更为频繁,并已成为一个主要问题 - 在覆盖范围非常差的区域中,这种情况高达 50% 的时间发生。我多次收到 Java 内存不足异常,告诉我应用程序无法派生新线程。此外,在良好的 3G 区域中,我们现在还看到了这个线程阻塞问题,这是以前没有发生过的。
我显然在这个设置中做错了,因为持久的 http 连接和底层 TCP 非常可靠
*我们在没有重新编写应用程序的情况下管理了所有这些更改,但是 10 秒的 http 超时将需要重新编写应用程序。也许这个超时导致了这个问题?
在此先感谢您提供的任何帮助。
【问题讨论】:
标签: java-me tcp persistent gprs httpconnection