У меня есть задание в Golang, которое выполняется каждые десять минут и загружает изображения из списка ссылок, предоставленных в Firebase Storage. Эти ссылки очищаются с использованием сервера go-colly
. При загрузке происходит переполнение памяти, а приложение уничтожается сервером.
Ниже приведен фрагмент кода, поскольку удаление этой функции устраняет проблему.
func UploadToStorageFromLink(storage *storage.Client, link string) error {
cfg := config.ReadConfig()
bucket, err := storage.Bucket(cfg.BucketName)
if err != nil {
return err
}
uniqueID := model.UniqueIDForString(link)
obj := bucket.Object(uniqueID)
// This is causing the memory bloat.
writer := obj.NewWriter(context.Background())
resp, err := http.Get(link)
if err != nil {
return err
}
defer resp.Body.Close()
_, err = io.Copy(writer, resp.Body)
if err != nil {
return err
}
if err := writer.Close(); err != nil {
return err
}
// Make the file public for mobile usage.
if err := obj.ACL().Set(context.Background(), cstorage.AllUsers, cstorage.RoleReader); err != nil {
return err
}
return nil
}
Если быть точным, создание NewWriter
вызывает проблемы. Почему новая память выделяется каждый раз, когда я даю новое задание на загрузку вместо использования уже выделенной памяти?
Я использую вышеуказанную функцию в контексте сканера go-colly
. Это задание сканера вызывается с использованием конечной точки REST. И он вызывается каждые 10 минут. Искатель настроен на использование режима Async
с параллелизмом, ограниченным 2.
c := colly.NewCollector(
colly.AllowedDomains("www.example.com"),
colly.MaxDepth(1),
)
// Disabling this also works.
c.Async = true
c.Limit(&colly.LimitRule{
DomainGlob: "*",
Parallelism: 2,
})
Запуск обхода в не асинхронном режиме c также устраняет проблему с памятью.
Что происходит при использовании асин c режима, когда память не освобождается во время сбора мусора между несколькими запросами на сканирование? Почему комбинация Async
из go-colly
и загрузки Firebase Storage вызывает эту проблему?