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

Heroku中Worker无法读取Web应用文件的原因及解决方法

Heroku部署Streamlit后Worker无法读取Web生成文件的问题解决

问题原因

Heroku的web和worker进程运行在独立的dyno容器中,每个容器都有自己独立的本地文件系统。本地开发时,所有进程共享同一台机器的文件系统,所以worker能读到web生成的CSV;但部署到Heroku后,web dyno生成的CSV只存在于它自己的文件系统里,worker dyno完全无法访问,这就是worker无法推送数据到BigQuery的核心原因。

不影响main.py的解决方案

1. 使用共享云存储中转文件

用Google Cloud Storage(GCS)或AWS S3这类共享存储服务,替代本地文件系统:

  • 修改main.py:生成CSV后,直接通过对应云存储的SDK将文件上传到指定bucket,无需在本地长期保存
  • 修改scheduler.py:从云存储的指定bucket读取CSV文件,再写入BigQuery
  • 优势:完全解耦web和worker的文件依赖,符合云服务分布式架构的设计逻辑

2. 在Web进程中用后台任务直接写入BigQuery

不需要单独维护worker进程,在main.py的按钮点击事件中,把写入BigQuery的任务放到后台线程执行,避免阻塞Streamlit界面:

import concurrent.futures
from google.cloud import bigquery
import streamlit as st

# 定义写入BigQuery的核心逻辑
def write_to_bigquery(csv_content):
    client = bigquery.Client()
    # 此处替换为你的BigQuery写入逻辑,比如加载CSV内容到指定表
    job_config = bigquery.LoadJobConfig(source_format=bigquery.SourceFormat.CSV)
    job = client.load_table_from_string(csv_content, "你的项目ID.数据集ID.表ID", job_config=job_config)
    job.result()

# Streamlit页面按钮逻辑
if st.button("生成并推送数据"):
    # 此处替换为你的CSV生成逻辑
    csv_content = "列1,列2\n值1,值2\n值3,值4"
    # 提交后台任务,不阻塞界面
    with concurrent.futures.ThreadPoolExecutor() as executor:
        executor.submit(write_to_bigquery, csv_content)
    st.success("推送任务已提交,后台处理中")
  • 优势:改动最小,无需额外维护worker进程,适合轻量级数据推送场景

3. 用消息队列传递数据

引入Redis这类消息队列,web进程把CSV数据(或文件的云存储地址)发送到队列,worker进程监听队列并处理写入BigQuery的任务:

  • 配置Heroku的Redis Add-on,安装rq(Redis Queue)库
  • main.py中生成CSV后,将数据或存储地址封装成任务发送到Redis队列
  • scheduler.py作为队列消费者,持续监听并执行写入BigQuery的任务
  • 优势:适合高并发场景,能更好地控制任务执行顺序、数量和重试机制

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 22:05:40