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

Flask+Oracle并行查询在Bokeh脚本调用时失效问题排查

问题分析:Flask路由并发 vs Bokeh服务器调用并发的差异

这两种场景的核心差异在于请求处理的线程/进程模型以及Bokeh服务器的执行方式,我来拆解一下:

一、纯Flask路由能并行查询的原因

Flask默认使用的Werkzeug服务器(app.run()默认启动的)是多线程模式(从Flask 2.0开始默认开启)。当同时收到两个请求时:

  • 每个请求会被分配到单独的线程中处理
  • 每个线程可以独立从Oracle连接池获取连接(或者新建连接),数据库查询可以并行执行
  • 线程之间互不阻塞,所以两个请求都能正常返回结果

二、调用Bokeh服务器时卡住的可能原因

你遇到的问题大概率出在Bokeh服务器的并发处理能力或者Flask调用Bokeh的方式上,常见的几个点:

1. Bokeh服务器默认是单线程单进程处理请求

Bokeh服务器的默认配置是单线程的,它会串行处理所有 incoming 的请求(包括WebSocket连接和HTTP请求)。如果你的两个Flask路由同时调用Bokeh服务器的接口,第二个请求必须等待第一个请求的数据库查询完成才能被处理,导致页面持续加载。

2. Flask路由在请求时才启动Bokeh服务器

如果你的Flask代码是在收到请求后才启动Bokeh服务器(比如用subprocess.run()或者直接调用bokeh serve的Python API),那第一个请求会阻塞在启动Bokeh的步骤上,第二个请求尝试再次启动时会因为端口被占用而卡住,或者等待第一个启动流程完成,最终导致两个请求都无法正常响应。

3. Bokeh代码中使用了全局Oracle连接对象

如果你的Bokeh脚本里用了全局的Oracle连接(比如在脚本顶部就创建了连接,而不是在每个请求/会话中获取),那当两个并发请求到达Bokeh服务器时,会竞争同一个连接资源——Oracle连接一般是单线程使用的,多个线程同时操作会导致阻塞甚至报错。

三、解决方案

针对这些问题,你可以按以下步骤排查修复:

  • 提前独立启动Bokeh服务器:不要在Flask请求中动态启动Bokeh服务,而是在Flask启动前,用命令行(bokeh serve --allow-websocket-origin=your-flask-domain:port your_script.py)或者后台进程启动Bokeh,Flask只负责跳转到Bokeh的URL或者做反向代理。
  • 配置Bokeh服务器支持并发:启动Bokeh时加上--num-procs N参数(N是进程数),或者--workers N(针对新版本Bokeh),让Bokeh用多进程处理请求;也可以配置--threaded开启多线程模式。
  • 在Bokeh中使用Oracle连接池:在Bokeh脚本里初始化一个Oracle连接池(比如用cx_Oracle.SessionPool),每个会话/请求从连接池获取独立的连接,用完后归还,避免线程竞争。
  • 检查Flask调用Bokeh的方式:如果是用HTTP请求调用Bokeh接口,确保不要在Flask线程中做不必要的阻塞操作;如果是嵌入Bokeh组件,推荐用Bokeh的server_document()方法,它会通过WebSocket和Bokeh服务器通信,效率更高且支持并发。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 09:10:06