大胆猜想,小心求证

阅读 17

随着编程经验的增加,我越来越觉得调试BUG的过程和侦探查案类似,需要:大胆猜想,小心求证

昨天给用户上传增加了一个新功能:使用event source来推送当前的上传进度,防止用户一直傻等。结果本地调试一切正常,但是部署到线上就出现进度事件捕获不到的情况。

首先,我问了AI(ChatGPT和Gemini)。不得不承认,AI的缺陷主要有两个:

  • 它的回答从来都是“信心满满”,可能80%的推理下是对的,但是20%的错误反而会误导你;
  • 和AI交互需要清晰明确地描述问题背景,但是有些实际情况很复杂,很难通过语言文字进行表达。

所以,AI绕了一圈,并没有帮我找到问题根源,反而产生了一堆垃圾信息。所以,我又回归到古法编程,变身为Bug侦探

后端使用Spring Boot,我在建立SSE连接时会推送一个open事件:

var emitter = new SseEmitter(30 * 60 * 1000L);

// 立即发送一条建立连接的消息
emitter.send(SseEmitter.event().name("open").data("SSE established: " + key));

这个推送是正常的,前端网页能收到了open事件。但是,上传时的进度却收不到,进度推送的代码如下:

var eventBuilder = SseEmitter.event().name("progress").data(data);
emitter.send(eventBuilder);

两者唯一的区别就是一个使用了open事件,一个使用了progress事件。但我本地开发都能收到,因此,这不是代码的问题,而是部署的问题。本地环境和线上环境的唯一差别就是线上使用了Nginx作为中间代理,又因为event source需要在Nginx中进行额外配置:

# event source 配置
location ^~ /api/orders/excel/uploadProgress/ {
    proxy_pass http://tag_backend;

    # 1. 核心:禁用缓冲,确保数据实时推送
    proxy_buffering off;
    proxy_cache off;
    # 2. 核心:保持长连接,防止协议退化
    proxy_http_version 1.1;
    proxy_set_header Connection "";
    # 3. 核心:延长读取超时时间
    proxy_read_timeout 300s;
}

这个配置也是没有问题的,因为open事件可以收到。

我突然灵光一闪,大胆猜测了一个想法:因为我的页面中有两个event source订阅,我Nginx只配置了一个订阅,另外一个还没有配置,是不是需要两个都配置好才行呢?然后,我就将另外一个event source订阅也在Nginx中进行配置了:

# event source 配置
location ^~ /api/orders/pdfzip/uploadProgress/ {
    proxy_pass http://tag_backend;

    # 1. 核心:禁用缓冲,确保数据实时推送
    proxy_buffering off;
    proxy_cache off;
    # 2. 核心:保持长连接,防止协议退化
    proxy_http_version 1.1;
    proxy_set_header Connection "";
    # 3. 核心:延长读取超时时间
    proxy_read_timeout 300s;
}

一个是对excel上传进度进行配置,一个是对zip文件上传进度进行配置。重新部署后,奇迹出现了,进度推送正常了!

真是奇怪,说真的,底层原理我暂时还没弄清楚,但是这个思维过程让我震撼!

这就是编程的乐趣!不是吗?和侦探查案一样,编程是一个严谨的推理工程,排除法在这里起到了非常关键的作用。另外,更重要的是,我们还需要一些大胆的猜想(想象),甚至推翻直觉

最后编辑于: 2026-04-27

评论(0条)

(必填)
复制成功