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

Cloud Scheduler触发Cloud Function返回500内部错误求助

问题:Cloud Scheduler触发Cloud Function报500内部错误

配置信息

  • 触发频率:0 9 1 * *
  • 目标类型:HTTP
  • 目标URL:https://europe-west2-project_name.cloudfunctions.net/xxxxx

已完成配置:

  • 添加OIDC令牌
  • 创建用于调用Cloud Function的服务账号

手动运行Cloud Scheduler失败,返回500内部错误,日志如下:

{
  "httpRequest": {
    "status": 500
  },
  "insertId": "132gtrbf1pw9rq",
  "jsonPayload": {
    "@type": "type.googleapis.com/google.cloud.scheduler.logging.AttemptFinished",
    "jobName": "projects/project_name/locations/europe-west2/jobs/cloud-scheduler-job",
    "status": "INTERNAL",
    "targetType": "HTTP",
    "url": "https://europe-west2-project_name.cloudfunctions.net/xxxx"
  },
  "logName": "projects/project_name/logs/cloudscheduler.googleapis.com%2Fexecutions",
  "receiveTimestamp": "2023-06-28T07:37:31.684339045Z",
  "resource": {
    "labels": {},
    "type": "cloud_scheduler_job"
  },
  "severity": "ERROR",
  "timestamp": "2023-06-28T07:37:31.684339045Z"
}

更新内容:审计日志

{
  "insertId": "-r6s7cscbc",
  "logName": "projects/project-name/logs/cloudaudit.googleapis.com%2Fdata_access",
  "protoPayload": {
    "@type": "type.googleapis.com/google.cloud.audit.AuditLog",
    "authenticationInfo": {
      "principalEmail": "service-1234567890@gcf-admin-robot.iam.gserviceaccount.com"
    },
    "requestMetadata": {
      "requestAttributes": {
        "time": "2023-06-27T18:17:21.627074Z",
        "auth": {}
      },
      "destinationAttributes": {}
    },
    "serviceName": "cloudfunctions.googleapis.com",
    "methodName": "google.cloud.functions.v1.CloudFunctionsService.GetFunction",
    "authorizationInfo": [
      {
        "resource": "projects/project-name/locations/europe-west2/functions/cloud-function-name",
        "permission": "cloudfunctions.functions.get",
        "granted": true,
        "resourceAttributes": {}
      }
    ],
    "resourceName": "projects/project-name/locations/europe-west2/functions/cloud-function-name",
    "resourceLocation": {
      "currentLocations": [
        "europe-west2"
      ]
    }
  },
  "receiveTimestamp": "2023-06-27T18:17:21.927721083Z",
  "resource": {
    "labels": {
      "function_name": "cloud-function-name",
      "project_id": "project-name",
      "region": "europe-west2"
    },
    "type": "cloud_function"
  },
  "severity": "INFO",
  "timestamp": "2023-06-27T18:17:21.556303Z"
}

更新内容:Cloud Function Python代码

from google.cloud import storage
import zipfile
import datetime
import os

def move_files(data, context):
    source_bucket_name = 'source-input'
    destination_bucket_name = 'destination-input'
    client = storage.client()

    source_bucket = client.get_bucket(source_bucket_name)
    destination_bucket = client.get_bucket(destination_bucket_name)

    three_month_file = datetime.datetime.now() - datetime.timedelta(days=90)

    for blob in source_bucket.list_blobs(prefix='files/data/document'):
        blob_updated = blob.updated
        if blob_updated < three_month_file:
            #Create temporary local directory to store the zipped file
            temp_dir = 'temp'
            os.makedirs(temp_dir,exist_ok=True)

            #Store the file to the temporary local directory
            blob.store_filename(os.path.join(temp_dir,blob.name))
            #Zip the file
            zip_Name = os.path.join(temp_dir,f"{blob.name}.zip")
            with zipfile.ZipFile(zip_Name,'w') as zipfile_obj:
                zipfile_obj.write(os.path.join(temp_dir,blob.name),blob.name)

            #move the zipeed file to destination bucket
            destination_blob = destination_bucket.blob(f"{blob.name}.zip")
            destination_blob.upload_files(zip_Name)

            #Delete the original file and zipped file
            os.remove(os.path.join(temp_dir,blob.name))
            os.remove(zip_Name)

            #Delete the original from the source bucket
            blob.delete()
        #Remove the temporary local directory
        os.rmdir(temp_dir)

排查与修复方案

1. 代码错误修复

你的Python代码存在多个API调用错误和逻辑问题,直接导致Cloud Function执行失败返回500错误:

  • 错误方法调用:blob.store_filename → 替换为blob.download_to_filename;destination_blob.upload_files → 替换为destination_blob.upload_from_filename
  • 时区问题:datetime.datetime.now()改为datetime.datetime.utcnow(),避免本地时间与Cloud Function UTC时间偏差
  • 目录清理错误:os.rmdir(temp_dir)放在循环内会重复执行,且无法删除非空目录,改用shutil.rmtree并移到finally块确保无论执行结果如何都清理
  • 路径处理优化:避免使用完整blob路径作为本地文件名,改用os.path.basename(blob.name)防止目录结构冲突

修正后的代码:

from google.cloud import storage
import zipfile
import datetime
import os
import shutil

def move_files(data, context):
    source_bucket_name = 'source-input'
    destination_bucket_name = 'destination-input'
    client = storage.Client()

    source_bucket = client.get_bucket(source_bucket_name)
    destination_bucket = client.get_bucket(destination_bucket_name)

    # 使用UTC时间避免时区偏差
    three_month_ago = datetime.datetime.utcnow() - datetime.timedelta(days=90)
    temp_dir = 'temp'
    
    try:
        os.makedirs(temp_dir, exist_ok=True)
        
        for blob in source_bucket.list_blobs(prefix='files/data/document'):
            # 移除时区信息后比较时间
            blob_updated = blob.updated.replace(tzinfo=None)
            if blob_updated < three_month_ago:
                # 下载文件到临时目录,仅保留文件名
                local_file_name = os.path.basename(blob.name)
                local_file_path = os.path.join(temp_dir, local_file_name)
                blob.download_to_filename(local_file_path)
                
                # 压缩文件
                zip_file_path = os.path.join(temp_dir, f"{local_file_name}.zip")
                with zipfile.ZipFile(zip_file_path, 'w', zipfile.ZIP_DEFLATED) as zip_obj:
                    zip_obj.write(local_file_path, local_file_name)
                
                # 上传压缩文件到目标Bucket,可添加归档前缀分类
                dest_blob = destination_bucket.blob(f"archived/{local_file_name}.zip")
                dest_blob.upload_from_filename(zip_file_path)
                
                # 删除本地临时文件
                os.remove(local_file_path)
                os.remove(zip_file_path)
                
                # 删除源Bucket中的原文件
                blob.delete()
    finally:
        # 确保临时目录被清理
        if os.path.exists(temp_dir):
            shutil.rmtree(temp_dir)

2. 权限配置验证

从审计日志看,cloudfunctions.functions.get权限已授予,但需确保调用Cloud Function的服务账号拥有以下权限:

  • storage.objects.get(读取源Bucket文件)
  • storage.objects.create(写入目标Bucket)
  • storage.objects.delete(删除源Bucket文件)
  • cloudfunctions.functions.invoke(调用Cloud Function)

给服务账号绑定roles/storage.objectAdmin(针对源和目标Bucket)和roles/cloudfunctions.invoker(针对目标Cloud Function)角色即可。

3. Cloud Scheduler配置检查

  • 确认OIDC令牌使用的服务账号已被授予roles/cloudfunctions.invoker角色,且绑定到目标Cloud Function
  • 检查目标URL的项目名、函数名、区域完全匹配,无拼写错误
  • 验证Cloud Function已成功部署,在控制台中手动测试函数是否能正常执行

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 00:57:03