Обслуживание изображений с изменением размера на лету

Моя компания недавно начала испытывать проблемы с обработкой изображений для наших веб-сайтов.

У нас есть несколько веб-сайтов (развлекательные программы для взрослых), которые отображают изображения, такие как обложки DVD, снимки и т.д. У нас около 100 000 фильмов, и для каждого фильма у нас есть в среднем 30 снимков + обложки. Почти у каждого изображения есть дополнительная версия с размытием и наложением для нечленов, это приводит к примерно 50 изображениям на фильм или в общей сложности 5 миллионов базовых изображений. Каждое из изображений доступно в нескольких версиях, в зависимости от того, где оно размещено на странице (эскиз, оригинал, небольшой предварительный просмотр, не очень маленький просмотр, небольшое изображение в верхнем списке и т.д.), Что приводит к большему количеству изображений, чем Мне было интересно подсчитать.

Теперь у меня возникла идея использовать сервер для генерации изображений "на лету", так как он стал довольно неуклюжим, чтобы генерировать все разные изображения для всех разных страниц (так как разные страницы иногда даже нуждаются в разных размерах изображения в основном та же задача).

Кто-нибудь знает о сервере обработки изображений, который может масштабировать изображения "на лету", поэтому нам нужно только предоставить исходные изображения, и веб-ребята могут просто запросить нужный размер?

Требования:

  • Очень высокая производительность (несколько тысяч пользователей в день)
  • Создание размытия и наложения на лету
  • Изменение размера на лету (с сохранением пропорций и без него)
  • Может обрабатывать миллионы изображений
  • Должен быть в состоянии читать JPG, GIF, PNG и BMP и конвертировать между ними

Безопасность не вызывает большой озабоченности, так как безразличные изображения уже могут быть достигнуты с помощью манипуляции с URL-адресами, и больше безопасности было бы неплохо, но это не требовалось, и, честно говоря, я перестала заботиться (после того, как я не смог войти в своих коллег, почему (для наша небольшая страница реселлера), плохая идея использовать http://example.com/view_image.php?filename=/data/images/01020304.jpg для отображения изображений).

Мы попробовали PHP-скрипты для этого, но производительность была слишком медленной для многих пользователей.

Заранее благодарим за любые ваши предложения.

8 ответов

Я предлагаю вам настроить выделенный веб-сервер для обработки изменения размера изображения и выполнения конечного результата. Я сделал что-то подобное, хотя и в гораздо меньших масштабах. Это в основном устраняет процесс проверки кеша.

Он работает следующим образом:

  • вы запрашиваете изображение, добавляющее требуемый размер к имени файла, например http://imageserver/someimage.150x120.jpg
  • Если изображение существует, оно будет возвращено без какой-либо другой обработки (это основная точка, проверка кеша неявно)
  • Если изображение не существует, обработайте 404, не найденный через .htaccess, и перенаправляйте запрос на script, который генерирует изображение требуемого размера
  • в script укажите список разрешенных размеров, чтобы избежать атак, таких как скрипты, запрашивающие все возможные размеры, чтобы закрыть ваш сервер.
  • сохранить это в cookieless домене, чтобы свести к минимуму ненужный трафик.

EDIT: я не думаю, что сам PHP очень сильно замедлит процесс, так как PHP-скрипты в этом случае сводятся к минимуму: масштабирование изображения выполняется встроенной библиотекой, написанной на C. Что бы вы ни делали, должны использовать такую ​​библиотеку (GD или libmagick или так), чтобы это было неизбежно. С моей системой, по крайней мере, вы полностью пропускаете накладные расходы на проверку кеша, тем самым еще более уменьшая взаимодействие с PHP. Вы можете реализовать это на своем существующем сервере, поэтому я предполагаю, что это решение хорошо подходит для вашего бюджета.


Основываясь на

Мы попробовали PHP-скрипты для этого, но производительность была слишком медленной для многих пользователей.

Я собираюсь предположить, что вы не кэшировали результаты. Я бы рекомендовал кэшировать результирующие изображения в течение дня или двух (т.е. Проверив script, чтобы увидеть, был ли эскиз уже сгенерирован, если он его использует, если он не генерирует его на лету).

Это значительно улучшило бы производительность, поскольку я предполагаю, что главная/стартовая страница, вероятно, имеет намного больше ударов, чем случайное видео X, поэтому при просмотре главной страницы изображения не должны создаваться по мере их кэширования. Когда пользователь Y просматривает Movie X, они не будут замечать задержку так же сильно, поскольку просто нужно создать эту страницу.

Для аспекта "On-the-fly resize" - насколько важна пропускная способность для вас? Я хотел бы предположить, что вы так много переживаете с фильмами, что несколько лишних килобайт в изображениях за один запрос не нанесут большого вреда. В этом случае вы можете просто использовать большие изображения и установить ширину и высоту и позволить браузеру делать масштабирование для вас.


ImageCache и Изобразительные точные размеры решения сообщества Drupal могут сделать это, и, как и большинство решений, OSS использует библиотеки из ImageMagik

Есть некоторые изображения AMI для службы Amazons EC2 для масштабирования изображения. Он использовал Amazon S3 для хранения изображений, оригинала и весов и мог доставить их до службы Amazons CDN (Cloud Front). Проверьте сайт EC2 для доступных

Другой вариант - Google. Документы Google теперь поддерживают все типы файлов, поэтому вы можете загружать изображения в папку документов Google и обмениваться папкой для общего доступа. URL-адрес длинный, например.

http://lh6.ggpht.com/VMLEHAa3kSHEoRr7AchhQ6HEzHVTn1b7Mf-whpxmPlpdrRfPW216UhYdQy3pzIe4f8Q7PKXN79AD4eRqu1obC7I

Добавьте параметр = s для масштабирования изображения, классно! например для ширины 200 пикселей

http://lh6.ggpht.com/VMLEHAa3kSHEoRr7AchhQ6HEzHVTn1b7Mf-whpxmPlpdrRfPW216UhYdQy3pzIe4f8Q7PKXN79AD4eRqu1obC7I=s200

Google взимает только USD5/год за 20 ГБ. Существует полный API для загрузки документов и т.д.

Другие ответы на SO Как изменить размер изображений без сервера


Хорошо, первая проблема заключается в том, что изменение размера изображения с любого языка занимает немного времени обработки. Итак, как вы поддерживаете тысячи клиентов? Мы будем кэшировать его, поэтому вам нужно только создать изображение один раз. В следующий раз, когда кто-то попросит об этом изображении, проверьте, не был ли он уже сгенерирован, если он только что вернулся. Если у вас несколько серверов приложений, вам нужно будет кэшировать центральную файловую систему, чтобы увеличить коэффициент кэширования и уменьшить объем пространства, в котором вы будете нуждаться.

Чтобы правильно кэшировать, вам необходимо использовать предсказуемое соглашение об именах, которое учитывает все различные способы отображения вашего изображения, то есть использовать что-то вроде myimage_blurred_320x200.jpg, чтобы сохранить jpeg, который был размытым и изменен до 300 ширина и высота 200 и т.д.

Другой подход заключается в том, чтобы разместить ваш сервер изображений за прокси-сервером таким образом, что вся логика кэширования выполняется автоматически для вас, а ваши изображения обслуживаются быстрым, родным веб-сервером.

Вы не сможете обслуживать миллионы измененных изображений любым другим способом. Благодаря тому, как это делают карты Google и Bing, они заранее генерируют все изображения, которые им нужны для мира, в разных заранее заданных экстентах, чтобы они могли обеспечить адекватную производительность и иметь возможность возвращать предварительно созданные статические изображения.

Если PHP слишком медленный, вы должны рассмотреть возможность использования 2D графических библиотек с Java или .NET, поскольку они очень богаты и могут поддерживать все ваши требования. Чтобы получить аромат API-интерфейса Graphics, здесь приведен метод .NET, который изменит размер любого изображения на указанную новую ширину или высоту. Если вы опустите высоту или ширину, она изменит размер, сохраняя правильное соотношение сторон. Примечание. Изображение может быть создано из JPG, GIF, PNG или BMP:

// Creates a re-sized image from the SourceFile provided that retails the same aspect ratio of the SourceImage. 
// - If either the width or height dimensions is not provided then the resized image will use the 
// proportion of the provided dimension to calculate the missing one.
// - If both the width and height are provided then the resized image will have the dimensions provided 
// with the sides of the excess portions clipped from the center of the image.
public static Image ResizeImage(Image sourceImage, int? newWidth, int? newHeight)
{
 bool doNotScale = newWidth == null || newHeight == null; ;
 if (newWidth == null)
 {
 newWidth = (int)(sourceImage.Width * ((float)newHeight / sourceImage.Height));
 }
 else if (newHeight == null)
 {
 newHeight = (int)(sourceImage.Height * ((float)newWidth) / sourceImage.Width);
 }
 var targetImage = new Bitmap(newWidth.Value, newHeight.Value);
 Rectangle srcRect;
 var desRect = new Rectangle(0, 0, newWidth.Value, newHeight.Value);
 if (doNotScale)
 {
 srcRect = new Rectangle(0, 0, sourceImage.Width, sourceImage.Height);
 }
 else
 {
 if (sourceImage.Height > sourceImage.Width)
 {
 // clip the height
 int delta = sourceImage.Height - sourceImage.Width;
 srcRect = new Rectangle(0, delta / 2, sourceImage.Width, sourceImage.Width);
 }
 else
 {
 // clip the width
 int delta = sourceImage.Width - sourceImage.Height;
 srcRect = new Rectangle(delta / 2, 0, sourceImage.Height, sourceImage.Height);
 }
 }
 using (var g = Graphics.FromImage(targetImage))
 {
 g.SmoothingMode = SmoothingMode.HighQuality;
 g.InterpolationMode = InterpolationMode.HighQualityBicubic;
 g.DrawImage(sourceImage, desRect, srcRect, GraphicsUnit.Pixel);
 }
 return targetImage;
}


В то время, когда был задан этот вопрос, появилось несколько компаний, которые столкнулись с этой проблемой. Это не проблема, которая изолирована от вас или вашей компании. Многие компании достигают точки, в которой им необходимо искать более постоянное решение для своих потребностей в обработке изображений.

Такие службы, как imgix, служат в качестве прокси-сервера и CDN для операций с изображениями, таких как изменение размера и применение наложений. Управляя URL-адресом, вы можете применять различные преобразования к каждому изображению. imgix обслуживает миллиарды запросов в день.

Вы также можете самостоятельно поддерживать свои услуги и помещать их в CDN. Проекты с открытым исходным кодом, такие как imageproxy, хороши для этого. Это ставит бремя обслуживания в вашу операционную команду.

(Отказ от ответственности: я работаю для imgix.)


То, что вы ищете, лучше всего соответствует Thumbor http://thumbor.readthedocs.org/en/latest/index.html, который является открытым исходным кодом, при поддержке огромной компании (означает, что он будет не исчезают завтра), и поставляется с множеством приятных функций, таких как определение того, что важно для изображения при обрезке.

Для недорогих плюс CDN я бы предложил объединить его с Cloudfront и AWS-хранилищем или сопоставимым решением с бесплатным CDN, таким как Cloudflare. Они могут быть не самыми эффективными поставщиками CDN, но, по крайней мере, по-прежнему работают лучше, чем один сервер, а также разгружают ваш графический сервер по дешевке. Кроме того, он сэкономит вам стоимость трафика TON.


Если каждое другое изображение однозначно идентифицируется по одному URL-адресу, я просто использую CDN, такой как AKAMAI. Пусть ваш PHP script выполняет задание и позволяет AKAMAI обрабатывать нагрузку.

Поскольку этот вид бизнеса обычно не имеет бюджетных проблем, это будет единственное место, на которое я бы посмотрел.

Изменить: это работает, только если вы найдете CDN, который будет обслуживать этот контент для вас.


Эта же проблема теперь решается службами изменения размера, предназначенными для этой задачи. Они обеспечивают следующие функции:

  • В встроенном CDN - вам не нужно беспокоиться о распределении изображений
  • Изменение размера изображения на лету - любой необходимый размер доступен
  • Нет необходимости в хранении - вы просто сохраняете базовое изображение, и все варианты обрабатываются службой
  • Библиотеки экосистем - вы можете просто включить javascript, и ваша работа будет выполнена для всех устройств и всех браузеров.

Одна такая услуга Gumlet. Вы также можете попробовать альтернативу с открытым исходным кодом, такую ​​как плагин nginx, который также может изменять размер изображения на лету.

(Я работаю для Gumlet.)

licensed under cc by-sa 3.0 with attribution.