【问题标题】:How can I use a Google Cloud Function to push a file from a Cloud Storage bucket into an instance?如何使用 Google Cloud Function 将文件从 Cloud Storage 存储桶推送到实例中?
【发布时间】:2019-06-14 22:43:10
【问题描述】:

我有一个任务分配给我,想办法在 GCP 中设置一个云功能,该功能执行以下操作:

  • 监控 Google Cloud Storage 存储桶中的新文件

  • 检测到存储桶中有新文件时触发

  • 将该文件复制到计算实例 (Ubuntu) 内的目录中

我一直在做一些研究,结果一无所获。我知道我可以轻松设置一个 cron 作业,每分钟同步存储桶/目录或类似的东西,但我们正在构建的系统的设计理念之一是操作触发器而不是计时器。

我问的可能吗?

【问题讨论】:

    标签: python-3.x google-cloud-platform google-cloud-storage google-cloud-functions google-compute-engine


    【解决方案1】:

    您可以trigger a Cloud Function from a Google Cloud Storage bucket,通过选择Event Type为Finalize/Create,每次在bucket中上传文件,都会调用Cloud Function。

    每次在存储桶中创建新对象时,云函数都会收到带有Cloud Storage object format 的通知。

    现在,进入第二步,我找不到任何可以将文件从云存储上传到实例 VM 的 API。但是,我做了以下解决方法,假设您的实例 VM 配置了可以接收 HTTP 请求的服务器(例如 Apache 或 Nginx):

    ma​​in.py

    import requests
    from google.cloud import storage
    
    def hello_gcs(data, context):
        """Background Cloud Function to be triggered by Cloud Storage.  
        Args:
            data (dict): The Cloud Functions event payload.
            context (google.cloud.functions.Context): Metadata of triggering event.
        Returns:
            None; the file is sent as a request to 
        """
        print('Bucket: {}'.format(data['bucket']))
        print('File: {}'.format(data['name']))
    
        client = storage.Client()
        bucket = client.get_bucket(data['bucket'])
        blob = bucket.get_blob(data['name'])
    
        contents = blob.download_as_string()
    
        headers = {
            'Content-type': 'text/plain',
        }
    
        data = '{"text":"{}"}'.format(contents)
        response = requests.post('https://your-instance-server/endpoint-to-download-files', headers=headers, data=data)
        return "Request sent to your instance with the data of the object"
    

    requirements.txt

    google-cloud-storage
    requests
    

    最好将对象名称和存储桶名称发送到您的服务器端点,然后使用Cloud Client Library 从那里下载文件。

    现在你可能会问...

    如何制作 Compute Engine 实例来处理请求?

    1. 创建一个 Compute Engine 实例虚拟机。确保它与云函数位于同一区域,并在创建它时允许对其进行 HTTP 连接。 Documentation。我在这个测试中使用了debian-9 图片。

    2. SSH 进入实例,并运行以下命令:

      • 安装apache服务器

        sudo apt-get update
        sudo apt-get install apache2
        sudo apt-get install libapache2-mod-wsgi
        
      • 也安装这个 python 库:

        sudo apt-get install python-pip
        sudo pip install flask
        
    3. 为您的应用程序设置环境:

      cd ~/
      mkdir app
      sudo ln -sT ~/app /var/www/html/app
      

    最后一行应该指向 apache 提供 index.html 文件的文件夹路径。

    1. /home/<user_name>/app中创建您的应用程序:

    ma​​in.py

    from flask import Flask, request
    app = Flask(__name__)
    
    @app.route('/', methods=['POST'])
    def receive_file():
        file_content = request.form['data']
        # TODO
        # Implement process to save this data onto a file
        return 'Hello from Flask!'
    
    if __name__ == '__main__':
      app.run()
    
    1. 在同一目录中创建 wsgi 服务器入口点:

    ma​​in.wsgi

    import sys
    sys.path.insert(0, '/var/www/html/app')
    
    from main import app as application
    
    1. 将以下行添加到/etc/apache2/sites-enabled/000-default.conf,在DocumentRoot 标记之后:

          WSGIDaemonProcess flaskapp threads=5
          WSGIScriptAlias / /var/www/html/app/main.wsgi
      
          <Directory app>
                  WSGIProcessGroup main
                  WSGIApplicationGroup %{GLOBAL}
                  Order deny,allow
                  Allow from all
          </Directory>
      
    2. 运行sudo apachectl restart。您应该能够将发布请求发送到您的应用程序,发送到 VM 实例的内部 IP(您可以在控制台的 Compute Engine 部分中看到它)。一旦你有了它,在你的云函数中,你应该将响应行更改为:

      response = requests.post('<INTERNAL_INSTANCE_IP>/', headers=headers, data=data)
      
      return "Request sent to your instance with the data of the object"
      

    【讨论】:

    • 感谢您的回复 Joan - 抱歉,我对 GCP 很陌生,想知道如何找出我的服务器端点是什么,以及如何向它发送对象?
    • 非常值得商榷,但您可以将对象事件发布到 pub/sub topic 并让它调用,而不是维护两段代码(一段用于云功能,另一段用于端点下载文件) (订阅)https://your-instance-server/endpoint-to-download-files 并在服务器上下载文件。
    • 我编辑了解释如何在 Compute Engine 实例中设置端点的答案。如果我遗漏了什么,或者您有任何问题,请告诉我。
    • 有没有其他方法可以从云 func 调用计算引擎中的 func,而不必在计算引擎中创建服务器端点?
    猜你喜欢
    • 2020-05-05
    • 1970-01-01
    • 2017-11-29
    • 2018-06-18
    • 2023-04-08
    • 2023-03-02
    • 2021-04-25
    • 1970-01-01
    • 2017-07-06
    相关资源
    最近更新 更多