DEBUG.WIKI
OnlineSIM:在线接收短信,虚拟号码租用
RackNerd;$21.99/年 · 1GB KVM
IPPeak:从目标地区访问网页,住宅代理、SEO 监测、广告验证

Vert.x 把 WebSocket 上限设为 MAX_VALUE,普通 HTTP 连接也断开

Vert.x 5.2.1 的压缩初始化会给消息上限加 512,Integer.MAX_VALUE 因溢出变负。采用 5.2.2 修正或明确、有限的业务上限。

服务器能监听端口,普通 HTTP 请求却刚连上就断开,业务 requestHandler 和应用异常处理都没有收到请求。如果近期把 maxWebSocketMessageSize 设成了 Integer.MAX_VALUE,先检查 WebSocket 压缩扩展的初始化,不必等到真的发出一条巨大 WebSocket 消息。

Vert.x 5.2.1 的服务端路径在启用相应压缩扩展时,会用 maxMessageSize + 512 或 maxFrameSize + 512 计算解压分配上限。加法使用 int;接近整数最大值的配置会溢出为负值,导致连接管线建立失败。压缩处理器在普通连接的初始化阶段就会安装,所以影响可以早于业务路由和 WebSocket 握手。

检查消息上限,也检查帧上限

Java 的 Integer.MAX_VALUE 是 2147483647,并不代表框架里的“无限制”。加上 512 后,结果不能再用正的 int 表达。只有扩大配置值而不检查后续计算,可能把原本正常的小请求也挡住。

如果应用不需要接收接近 2 GiB 的消息,可在原配置入口设置符合业务需要的有限值。例如,下面只是将消息上限设为 8 MiB 的配置片段,HttpServerOptions 来自 io.vertx.core.http:

var options = new HttpServerOptions()
    .setMaxWebSocketMessageSize(8 * 1024 * 1024);

创建服务器时要把这个 options 对象传给 vertx.createHttpServer(options),并保留原来的 handler、TLS、认证和监听配置。另查每帧上限有没有同样使用最大整数;仅修消息上限,不会自动修正另一条压缩配置。

8 MiB 是示例,不是所有服务都应该采用的值。减小上限会拒绝此前允许的大消息,应依据真实载荷和资源预算选择,并提前明确客户端能看到的拒绝行为。

5.2.2 已在正式实现中修正加法

Vert.x 5.2.2 的正式实现改为先按 long 相加,再以 Integer.MAX_VALUE 封顶,避免这两处计算变负;对应的正式 Maven 产物也已发布。采用该修正时,应沿用项目的依赖平台更新相关 Vert.x 模块,确认部署中的 core 确实是新版本。

临时将值限制在 Integer.MAX_VALUE - 512 之内,可以避开这次整数溢出,但它仍允许极大的输入,不适合作为默认资源策略。升级也不会替应用决定合理的帧大小、消息大小和解压资源上限。

这条故障针对启用了相关压缩扩展的受影响初始化路径。没有相同配置、当前实现已包含修正,或请求已经进入业务 handler 后才失败,都应另行定位;不能把所有连接重置都归到这里。

部署前保存原有依赖和配置,在隔离入口同时检查普通 HTTP、WebSocket 握手、正常消息,以及超过业务上限的消息。正常请求应能进入 handler,超限输入则按预定规则被拒绝,不能以关闭压缩或绕过认证来换取一次握手成功。