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

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

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

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

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

Требования:

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

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

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

Заранее спасибо за любые предложения Вы имеете.

23
задан Kara 11 September 2013 в 17:27
поделиться

5 ответов

Вам совершенно не нужно wchar _ t для поддержки Юникода в программном обеспечении, фактически использование wchar _ t делает это еще труднее, потому что вы не знаете, является ли «широкий ряд» UTF-16 или UTF-32 - это зависит от ОС: под окнами utf-16 все остальные utf-32.

Однако utf-8 позволяет легко писать ПО с поддержкой Юникода (*)

См.: https://stackoverflow.com/questions/1049947/should-utf-16-be-considered-harmful

(*) Примечание: в Windows по-прежнему необходимо использовать wchar _ t , поскольку он не поддерживает языковые стандарты utf-8, поэтому для Windows с поддержкой Юникода необходимо использовать API на основе wchar.

-121--1352236-

Если выполнить

propertyArray.each do |property|
  item.send(property).should be_nil
end

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

describe item, "Testing the Item" do

  before(:each) do
    @item = Item.new
  end

  propertyArray.each do |property|

    it "should have a null value for #{property} to start" do
      @item.send(property).should be_nil
    end

  end

end

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

-121--4859477-

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

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

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

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

27
ответ дан 29 November 2019 в 01:58
поделиться

На основе

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

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

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

Что касается аспекта «Изменение размера на лету» - насколько важна для вас пропускная способность? Я бы хотел предположить, что вы так много переживаете с фильмами, что несколько дополнительных килобайт изображений на запрос не причинят слишком большого вреда. В этом случае вы можете просто использовать изображения большего размера и установить ширину и высоту, а браузер выполнит масштабирование за вас.

7
ответ дан 29 November 2019 в 01:58
поделиться

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

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

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

0
ответ дан 29 November 2019 в 01:58
поделиться

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

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

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

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

Если php слишком медленный, вам следует рассмотреть возможность использования 2D графических библиотек из Java или .NET, поскольку они очень богаты и могут поддерживать все ваши требования. Чтобы получить представление о графическом API, вот метод в .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;
}
2
ответ дан 29 November 2019 в 01:58
поделиться

Решения ImageCache и Image Exact Sizes от сообщества Drupal могут сделать это, и как большинство решений OSS используют библиотеки от ImageMagik

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

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

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

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

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

Google берет только 5 долларов США в год за 20 ГБ. Есть полный API для загрузки документов и т.д.

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

4
ответ дан 29 November 2019 в 01:58
поделиться
Другие вопросы по тегам:

Похожие вопросы: