云 运行 从 GCS 下载文件非常慢

Cloud Run downloading a file from GCS is insanely slow

我有一个 Go 云 运行 应用程序,当它启动时,它会从 GCS 下载一个 512mb 的文件(程序需要这个文件)。在我没什么特别的家庭连接上,这在本地工作正常,并且会在几秒钟内下载,但是当我将其部署到云 运行 时,它会像蜗牛一样下载。我不得不增加超时并记录一个进度计数器,以确保它正在做某事(确实如此)。它可能以大约 30Kb/s 的速度下载,这是行不通的。

云 运行 实例和 GCS 区域存储桶都在 us-east4 中。似乎没有任何我可以使用的旋钮来让它工作,而且我没有看到这个 issue/constraint 记录。

有人知道可能是什么问题吗?

这是执行下载的代码,以及大量的日志记录,因为一开始我无法判断它是否在做任何事情:

func LoadFilter() error {
    fmt.Println("loading filter")
    ctx := context.Background()
    storageClient, err := storage.NewClient(ctx)
    if err != nil {
        return err
    }
    defer storageClient.Close()

    ctx, cancel := context.WithTimeout(ctx, time.Minute*60)
    defer cancel()

    obj := storageClient.Bucket("my_slow_bucket").Object("filter_export")
    rc, err := obj.NewReader(ctx)
    if err != nil {
        return err
    }
    defer rc.Close()

    attrs, err := obj.Attrs(ctx)
    if err != nil {
        return err
    }
    progressR := &ioprogress.Reader{
        Reader: rc,
        Size:   attrs.Size,
        DrawFunc: func(p int64, t int64) error {
            fmt.Printf("%.2f\n", float64(p)/float64(t)*100)
            return nil
        },
    }

    fmt.Println("reading filter...")
    data, err := ioutil.ReadAll(progressR)
    if err != nil {
        return err
    }

    fmt.Println("decoding filter...")
    filter, err := cuckoo.Decode(data)
    if err != nil {
        return err
    }

    fmt.Println("filter decoded")

    cf = filter

    fmt.Println("initailized the filter successfully!")

    return nil
}

确实@wlhee 说的完全正确。如果您有任何 运行 外部或请求管道的活动,这些活动将无法访问提供给您的实例的完整 CPU。正如文档所说:

When an application running on Cloud Run finishes handling a request, the container instance's access to CPU will be disabled or severely limited. Therefore, you should not start background threads or routines that run outside the scope of the request handlers.

Running background threads can result in unexpected behavior because any subsequent request to the same container instance resumes any suspended background activity.

我建议您 运行 根据对您的服务的请求,通过点击您应用中的某个启动端点,从云存储 activity 下载此文件,完成下载,然后 return 响应表示请求结束。

请查看此文档以获得 tips on Cloud Run