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

Heroku生产环境无法连接Google Cloud Bucket但本地正常的问题求助

Heroku生产环境无法连接Google Cloud Bucket但本地正常的问题求助

问题描述

我手里有个Rails应用,用Rake任务来访问Google Cloud Bucket。本地跑这个任务完全没问题,但部署到Heroku生产环境后就报错了,错误信息如下:

/app/vendor/ruby-3.1.2/lib/ruby/3.1.0/socket.rb:1214:in __connect_nonblock': Failed to open TCP connection to 169.254.169.254:80 (Operation already in progress - connect(2) for 169.254.169.254:80) (Errno::EALREADY)

我已经确认服务账号密钥加载正常,甚至在Cloud Console的Bucket面板里能看到请求确实打到了Bucket上,但就是会抛出这个错误,实在摸不着头脑。ChatGPT提示这可能和Google的元数据服务器有关?

附上相关的服务代码片段:

require "base64"
require "google/cloud/storage"

class GoogleCloudBucketService
  def initialize(bucket_name)
    @bucket_name = bucket_name
    decoded_json_key = Base64.decode64(ENV['GCP_SERVICE_ACCOUNT_KEY'])
    # 后续的初始化逻辑
  end
  # 其他相关方法
end

问题分析与解决建议

你猜的没错,169.254.169.254就是Google云的元数据服务器地址。Google的SDK默认会自动尝试从这个地址获取凭证,哪怕你已经手动提供了服务账号密钥。在Heroku环境里,这种自动检测逻辑和你手动加载密钥的操作撞车了,导致重复发起连接请求,就触发了Errno::EALREADY这个错误。

给你几个可以尝试的解决方向:

  • 显式禁用自动凭证检测
    在初始化Google::Cloud::Storage的时候,明确指定使用你解码后的服务账号密钥,同时加上disable_gce_metadata: true参数,直接阻止SDK去访问元数据服务器。修改后的初始化代码大概是这样:

    def initialize(bucket_name)
      @bucket_name = bucket_name
      decoded_json_key = Base64.decode64(ENV['GCP_SERVICE_ACCOUNT_KEY'])
      @storage = Google::Cloud::Storage.new(
        credentials: JSON.parse(decoded_json_key),
        disable_gce_metadata: true
      )
      @bucket = @storage.bucket(@bucket_name)
    end
    
  • 排查Heroku网络限制
    虽然你能看到请求记录,但Heroku的网络环境本来就访问不了Google的内部元数据服务器,SDK反复尝试连接这个地址就会出问题。你可以在Heroku上跑个命令测试下:heroku run curl 169.254.169.254,大概率是访问不通的,这也验证了我们的推测。

  • 确认服务账号权限完整性
    有时候哪怕请求能到Bucket,但如果部分操作权限不足,SDK会自动 fallback 去元数据服务器尝试获取其他凭证,进而引发连接错误。你可以检查下服务账号是否拥有Bucket所需的完整权限,比如storage.objects.get、storage.objects.create这些核心权限。

备注:内容来源于stack exchange,提问作者Kyle Pendergast

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.17 08:59:49