You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vert.x高吞吐量下出现‘Cannot assign requested address’错误的解决问询

解决Vert.x高RPS压力测试下"Cannot assign requested address"问题

核心问题分析

出现该错误的本质是本地TCP端口耗尽,结合你的代码和场景,主要诱因有三个:

  1. 每次请求都新建WebClient实例,完全丧失连接复用能力,短时间内产生大量TIME_WAIT状态的TCP连接
  2. 系统默认TCP参数无法支撑10K RPS的高并发请求,端口回收速度跟不上消耗速度
  3. Vert.x的Verticle和线程池配置不合理,加剧资源消耗

解决方案

1. 复用WebClient实例(最关键修复)

WebClient是重量级对象,包含连接池、线程管理等资源,必须在Verticle启动时初始化一次,而非每次请求都创建:

private WebClient httpClient;

@Override
public void start(Promise<Void> startPromise) throws Exception {
    WebClientOptions webClientOptions = new WebClientOptions();
    webClientOptions.setMaxPoolSize(2000);
    // 开启连接复用关键配置
    webClientOptions.setKeepAlive(true);
    webClientOptions.setTcpKeepAlive(true);
    webClientOptions.setReuseAddress(true);
    // 设置请求排队上限,避免内存溢出
    webClientOptions.setMaxWaitQueueSize(5000);

    httpClient = WebClient.create(vertx, webClientOptions);
    vertx.eventBus().consumer(FIRE_GET_METRIC_TO_STATS, this::fire);
    startPromise.complete();
}

private void fire(Message<StatsRequest> message) {
    StatsRequest body = message.body();
    MultiMap multimapHeader = MultiMap.caseInsensitiveMultiMap();

    httpClient.request(HttpMethod.GET, port, "example.com", "/1x1.gif" + "?" + "queryParamsString")
            .followRedirects(false)
            .putHeaders(multimapHeader)
            .timeout(120000)
            .send()
            .onSuccess(response -> {
                logger.info("All good");
            })
            .onFailure(err -> {
                logger.error("Exception: " + err.getMessage());
            });
}

2. 调整系统TCP参数(Linux环境)

编辑/etc/sysctl.conf添加以下配置,扩大端口范围并加速端口回收:

# 扩大本地可用端口范围
net.ipv4.ip_local_port_range = 1024 65535
# 缩短TIME_WAIT状态端口的回收时间
net.ipv4.tcp_fin_timeout = 30
# 允许复用TIME_WAIT状态的端口
net.ipv4.tcp_tw_reuse = 1
# 快速回收TIME_WAIT端口
net.ipv4.tcp_tw_recycle = 1
# 增大连接跟踪表容量
net.netfilter.nf_conntrack_max = 1000000

执行sysctl -p使配置生效。

3. 优化Vert.x部署配置

  • 调整WorkerVerticle数量:当前10个Verticle+每个50线程的配置过于激进,建议根据CPU核心数调整(例如CPU核心数*4),避免线程上下文切换开销过大:
// 修改deployWorker调用的第三个参数,比如调整为4
deployWorker(vertx, injector, StatsHttpVerticle.class, 4)
  • 放宽EventLoop执行时间限制:当前setMaxEventLoopExecuteTime(1)过于严格,会频繁触发EventLoop阻塞告警,建议移除该配置或调整为合理值(如100毫秒):
final VertxOptions vertxOptions = new VertxOptions();
// 移除或调整以下配置
// .setMaxEventLoopExecuteTime(100)
// .setMaxEventLoopExecuteTimeUnit(TimeUnit.MILLISECONDS);

4. 优化EventBus调用方式(可选)

如果不需要接收WorkerVerticle的响应,将eventBus.request()改为eventBus.send(),避免发送端因等待响应产生阻塞:

public void send(Map<String, Object> queryParams, HashMap<String, String> headers, boolean followRedirect, Event eventToFire) {
    StatsRequest statsRequest = new StatsRequest(queryParams, headers, eventToFire, followRedirect);
    eventBus.send(FIRE_GET_METRIC_TO_STATS, statsRequest);
}

内容的提问来源于stack exchange,提问作者Tal Rosentzweig

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 15:25:23