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

Spring Boot中如何基于WebSocket事件正确配置@Scheduled任务

问题诊断

你当前的实现逻辑是错误的,核心问题是对该币安SDK的WebSocket API行为理解有误:

  • BinanceApiWebSocketClient的onCandlestickEvent方法不是单次拉取事件的方法,每调用一次就会新建一条独立的WebSocket长连接,向币安服务器发起一次K线流订阅。只要连接不中断,后续新的K线事件产生时,服务器会主动推送到你注册的回调函数,完全不需要重复调用该方法。
  • 你把订阅逻辑放在了每秒执行一次的@Scheduled定时任务里,相当于每秒都会新增一条重复的K线订阅连接,旧连接从未被关闭。每一条连接都会推送订阅生效后的所有K线事件,运行时间越长,冗余连接越多,自然会出现事件大量堆积、重复打印的问题,还会产生无意义的带宽和内存损耗。
正确实现方案

WebSocket本身就是事件驱动的长连接协议,不需要任何定时轮询逻辑,只需要在应用启动时初始化一次订阅,事件实际产生时会自动触发回调,不会有堆积问题。

修正后的监听器代码

你可以直接删除原来带@Scheduled的监听类,换成下面的实现:

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;

@Component
@Slf4j
public class BinanceCandlestickListener {

    private final BinanceApiWebSocketClient webSocketClient;

    // 构造器注入,比字段@Autowired更符合Spring最佳实践
    public BinanceCandlestickListener(BinanceApiWebSocketClient webSocketClient) {
        this.webSocketClient = webSocketClient;
    }

    /**
     * 应用启动完成后仅执行一次,初始化K线订阅
     */
    @EventListener(ApplicationReadyEvent.class)
    public void initKlineSubscription() {
        // 仅调用一次订阅方法,建立长连接
        webSocketClient.onCandlestickEvent(
                "ethbtc",
                CandlestickInterval.ONE_MINUTE,
                event -> {
                    // 此处编写K线事件的业务处理逻辑,事件到达时会自动触发
                    log.info("收到ETH/BTC 1分钟K线推送: {}", event);

                    // 如果只需要处理收盘完成的K线,加这个判断即可过滤K线形成过程中的中间推送
                    if (event.getBarFinal()) {
                        log.info("K线收盘,触发交易逻辑: {}", event);
                    }
                }
        );
        log.info("币安K线WebSocket订阅初始化完成");
    }
}

关键注意事项

  • 订阅逻辑全局只需要执行一次,不要放在定时任务、HTTP接口、重复触发的业务方法里,避免产生冗余连接
  • 你之前定义的WebSocketConfig配置类不需要修改,可以正常用来实例化客户端Bean
  • 如果需要订阅多个交易对、多时间周期的K线,在initKlineSubscription方法内依次调用onCandlestickEvent传入不同参数即可,不要重复订阅相同参数的流
  • 如果需要实现断线重连,可以在订阅时传入连接异常的回调,在连接意外断开时重新执行订阅逻辑即可,不需要靠定时任务轮询重建

补充:你之前观察到的定时节点收到堆积事件的现象,本质是每新建一个订阅,币安服务器会首先推送当前未收盘K线的最新状态,每秒新建一个连接就会多收到一份推送,运行越久冗余连接越多,延迟和堆积就越明显,调整为启动时单次订阅后该问题会完全消失。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 03:39:27