在GCP中调度任务:将SFTP服务器数据同步至GCS存储桶
方案可行性说明
你的方案完全可以在GCP实现,并且不需要用到Cloud Function——你已有的带白名单静态IP的Compute Engine实例是更合适的执行载体:一方面它不受Cloud Function的9分钟执行时长限制(同步大量文件时更稳定),另一方面无需额外配置网络即可访问SFTP服务器。
实操指导
1. 配置Compute Engine实例的同步环境
1.1 安装必要工具
登录到你的Compute Engine实例,执行以下命令安装同步所需工具(以Debian/Ubuntu系统为例):
sudo apt update && sudo apt install -y openssh-client rsync google-cloud-sdk
1.2 配置SFTP免密登录
为了自动化执行同步,需要设置无需手动输入密码的SFTP登录方式:
- 生成SSH密钥对(不设密码):
ssh-keygen -t ed25519 -f ~/.ssh/sftp_sync_key -N "" - 将生成的公钥
~/.ssh/sftp_sync_key.pub内容,添加到SFTP服务器目标用户的~/.ssh/authorized_keys文件中 - 测试免密登录:
确认能成功登录且无需输入密码。sftp -i ~/.ssh/sftp_sync_key sftp-user@sftp-server-ip
1.3 编写同步脚本
创建同步脚本/home/your-user/sync_sftp_to_gcs.sh,替换脚本中的参数为你的实际信息:
#!/bin/bash # 配置参数 SFTP_USER="你的SFTP用户名" SFTP_SERVER="SFTP服务器IP/域名" SFTP_KEY="/home/your-user/.ssh/sftp_sync_key" SFTP_BASE_DIR="SFTP上要同步的根文件夹路径" GCS_BUCKET="gs://sftp-data" LOCAL_TEMP_DIR="/tmp/sftp_sync_temp" # 创建临时目录 mkdir -p $LOCAL_TEMP_DIR # 从SFTP同步到本地(只同步新增/修改文件,保持文件夹结构) rsync -avz -e "ssh -i $SFTP_KEY" --delete $SFTP_USER@$SFTP_SERVER:$SFTP_BASE_DIR/ $LOCAL_TEMP_DIR/ # 从本地同步到Cloud Storage,保持结构一致 gsutil rsync -r $LOCAL_TEMP_DIR/ $GCS_BUCKET/ # 清理临时目录(可选,避免占用磁盘空间) rm -rf $LOCAL_TEMP_DIR/*
给脚本添加执行权限:
chmod +x /home/your-user/sync_sftp_to_gcs.sh
手动运行脚本测试,确认文件能同步到Cloud Storage且结构一致。
2. 配置Cloud Scheduler定时触发
我们用Cloud Scheduler + Pub/Sub的组合来触发同步任务,避免直接SSH调用的权限复杂度:
2.1 创建Pub/Sub主题
在GCP控制台打开Pub/Sub服务,创建一个主题,名称设为sftp-gcs-sync-trigger。
2.2 在Compute Engine上配置Pub/Sub监听脚本
- 安装Pub/Sub Python客户端:
sudo apt install -y python3-pip && pip3 install google-cloud-pubsub - 创建监听脚本
/home/your-user/pubsub_listener.py,替换your-gcp-project-id为你的项目ID:import os from google.cloud import pubsub_v1 def sync_sftp_to_gcs(): os.system("/home/your-user/sync_sftp_to_gcs.sh") def callback(message): print("收到同步触发消息,开始执行同步") sync_sftp_to_gcs() message.ack() if __name__ == "__main__": project_id = "your-gcp-project-id" subscription_name = "sftp-sync-subscription" subscriber = pubsub_v1.SubscriberClient() subscription_path = subscriber.subscription_path(project_id, subscription_name) # 创建订阅(若已存在则忽略) try: subscriber.create_subscription(name=subscription_path, topic=f"projects/{project_id}/topics/sftp-gcs-sync-trigger") except Exception as e: print(f"订阅已存在: {e}") future = subscriber.subscribe(subscription_path, callback=callback) print("正在监听同步触发消息...") try: future.result() except KeyboardInterrupt: future.cancel() - 设置脚本开机自启(用systemd):
创建/etc/systemd/system/sftp-sync-listener.service文件:
启用并启动服务:[Unit] Description=SFTP到GCS同步的Pub/Sub监听服务 After=network.target [Service] User=your-user ExecStart=/usr/bin/python3 /home/your-user/pubsub_listener.py Restart=always [Install] WantedBy=multi-user.targetsudo systemctl daemon-reload sudo systemctl enable sftp-sync-listener.service sudo systemctl start sftp-sync-listener.service
2.3 创建Cloud Scheduler定时任务
在GCP控制台打开Cloud Scheduler服务,点击「创建任务」:
- 任务名称:
sftp-gcs-sync-hourly - 频率:
0 * * * *(每小时整点执行) - 时区:选择你的实际时区(如Asia/Shanghai)
- 目标:选择「Pub/Sub」
- 主题:选择之前创建的
sftp-gcs-sync-trigger - 消息正文:可留空或填写
"sync" - 点击「创建」完成配置
可选优化
- 给同步脚本添加日志记录,比如在脚本中加入
>> /var/log/sftp_sync.log 2>&1,方便排查问题 - 若只需同步.csv文件,可在rsync命令中添加
--include="*.csv" --exclude="*"过滤文件类型 - 使用
gsutil rsync -c选项校验文件完整性,确保同步的文件无损坏
内容的提问来源于stack exchange,提问作者Berra
相关产品推荐
相关产品推荐

