пятница, 17 августа 2018 г.

[prog.c++] Завершение(?) серии статей про Shrimp на Хабре

Сегодня мы опубликовали очередную статью на Хабре про свой демо-проект Shrimp: "Делаем Shrimp еще полезнее: добавляем перекодирование картинок в другие форматы". Статья, вероятно, заключительная в серии. Ибо дальнейшее развитие Shrimp-а возможно разве что при выполнении одного из следующих условий:

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

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

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

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

Остальные факторы, т.к. интеграция с существующим C/C++ кодом и асинхронная обработка запросов -- это необходимые условия. Но таким условиям удовлетворяют и другие задачи, скажем, агрегация какой-нибудь статистической информации и выдача ее частей в том или ином формате по запросу. А вот масштабирование картинок при всем этом обладает еще и отличной наглядностью.

Так вот, лишь слегка погрузившись в проблему масштабирования и перекодирования картинок на стороне Web-сервера, у меня лично сложилось впечатление, что не выгодно масштабировать картинки "на лету" при обслуживании запросов. По крайней мере, если обеспечить высокую отзывчивость сайта, т.е. если нужно минимизировать время, за которое сайт отдает весь контент клиенту. Особенно, если исходные картинки на сервере лежат в более-менее приличном качестве (скажем от 2000px по длинной стороне и больше). Резайзинг таких картинок занимает пару сотен миллисекунд (оптимистично) и примерно столько же может занимать перекодирование в другой формат. Хотя мы, конечно же не на мощных Xeon-ах тесты гоняем...

И лично у меня сложилось ощущение, что если требуется обеспечить высокую скорость отдачи картинок в разных разрешениях и разных форматах, то вместо обработки изображений "на лету", намного перспективнее выглядела бы предварительная обработка картинок. Т.е. если бы у меня спросили, как бы следовало делать более продвинутый Shrimp-2.0, то я бы предложил рассматривать следующую схему работы:

  • есть некий каталог, куда складываются новые изображения, которые должны стать доступны через Web-сервер;
  • сервис картинок сканирует этот каталог, забирает новые изображения и раскидывает их по специальным служебным каталогам, в которых изображения:
    • хранятся отмасштабированными в наиболее ходовые разрешения;
    • хранятся перекодированными в нужные форматы.
    Например, закинули новую картинку example.jpg, она превратилась в набор картинок example_200px.jpg, example_640px.jpg, example_800px.jpg, ..., example_200px.webp, example_640px.webp, example_800px.webp, ...
  • сервис выполняет масштабирование изображения "на лету" только если нет готового изображения нужного размера. Скажем, запросили 700px по длинной стороне, а у нас лежат 640px и 800px. При этом в качестве основы берется не исходное изображение в полном размере (которое может весить десятки мегабайт), а наиболее близкое. В данном случае example_640px.

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

Впрочем, уверен, крупные сервисы, которые вынуждены сталкиваться с такого рода задачами (как то: VK, FB, Amazon, Flickr и пр.) уже давным-давно все это у себя сделали наилучшим образом (переделав до этого по много раз). А мелким интернет-магазинчикам на такие проблемы можно, наверное, и не заморачиваться.


Ну вот как-то так. Интересная и полезная оказалась демо-задачка. Надеюсь, что нам удалось это показать и в коде, и в своих статьях.

Хочется отдельно поблагодарить всех, кто нашел время высказать свой фидбек и помогал нам советами, соображениями, ссылками и примерами. В частности, отдельное спасибо Анатолию "Aen Sidhe" Попову.

Комментариев нет: