[ { "id": 1, "label": "100%×150_Branding_desktop", "provider": "adfox", "adaptive": [ "desktop", "tablet" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "cndo", "p2": "ezfl" } } }, { "id": 2, "label": "1200х400", "provider": "adfox", "adaptive": [ "phone" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "cndo", "p2": "ezfn" } } }, { "id": 3, "label": "240х200 _ТГБ_desktop", "provider": "adfox", "adaptive": [ "desktop" ], "adfox": { "ownerId": 228129, "params": { "pp": "i", "ps": "cndo", "p2": "fizc" } } }, { "id": 4, "label": "240х200_mobile", "provider": "adfox", "adaptive": [ "phone" ], "adfox": { "ownerId": 228129, "params": { "pp": "i", "ps": "cndo", "p2": "flbq" } } }, { "id": 5, "label": "300x500_desktop", "provider": "adfox", "adaptive": [ "desktop" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "cndo", "p2": "ezfk" } } }, { "id": 6, "disable": true, "label": "1180х250_Interpool_баннер над комментариями_Desktop", "provider": "adfox", "adaptive": [ "desktop", "tablet" ], "adfox": { "ownerId": 228129, "params": { "pp": "h", "ps": "clmf", "p2": "ffyh" } } }, { "id": 7, "label": "Article Footer 100%_desktop_mobile", "provider": "adfox", "adaptive": [ "desktop", "tablet", "phone" ], "adfox": { "ownerId": 228129, "params": { "p1": "byswn", "p2": "fjxb" } } }, { "id": 8, "label": "Fullscreen Desktop", "provider": "adfox", "adaptive": [ "desktop", "tablet" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "cndo", "p2": "fjoh" } } }, { "id": 9, "label": "Fullscreen Mobile", "provider": "adfox", "adaptive": [ "phone" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "cndo", "p2": "fjog" } } }, { "id": 10, "disable": true, "label": "Native Partner Desktop", "provider": "adfox", "adaptive": [ "desktop", "tablet" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fmyb" } } }, { "id": 11, "disable": true, "label": "Native Partner Mobile", "provider": "adfox", "adaptive": [ "phone" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fmyc" } } }, { "id": 12, "label": "Кнопка в шапке", "provider": "adfox", "adaptive": [ "desktop", "tablet" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "cndo", "p2": "fdhx" } } }, { "id": 13, "label": "DM InPage Video PartnerCode", "provider": "adfox", "adaptive": [ "desktop", "tablet", "phone" ], "adfox_method": "create", "adfox": { "ownerId": 228129, "params": { "pp": "h", "ps": "cndo", "p2": "flvn" } } }, { "id": 14, "label": "Yandex context video banner", "provider": "yandex", "yandex": { "block_id": "VI-223677-0", "render_to": "inpage_VI-223677-0-101273134", "adfox_url": "//ads.adfox.ru/228129/getCode?p1=byaeu&p2=fpjw&puid1=&puid2=&puid3=&puid4=&puid8=&puid9=&puid11=&puid12=&puid13=&puid14=&puid21=&puid22=&puid31=&fmt=1&pr=" } } ]
{ "author_name": "Ilya Chekalsky", "author_type": "self", "tags": ["tjdev"], "comments": 65, "likes": 54, "favorites": 11, "is_advertisement": false, "section_name": "blog", "id": "17139" }
Ilya Chekalsky
2 400
Блоги

Как работает система раздачи картинок на TJournal

Я хочу рассказать, как мы отдаём статику (картинки) всем посетителям TJournal. И заодно протестировать новый редактор в «боевом» режиме.

С самого начала все загружаемые на TJ картинки были вынесены отдельно, чему мы много раз радовались при переезде с сервера на сервер, потому что копировать по сети гигабайты и гигабайты картинок, каждая из которых весом максимум пара сотня килобайт — то ещё мучение.

Поделиться

В избранное

В избранном

Статистика по объёму трафика на одном из серверов TJ

Сначала мы использовали Amazon S3 (старые статьи до сих пор хранят ссылки на амазоновское облако) и до сих продолжаем платить примерно $10 в месяц за хранение и трафик оставшихся там картинок. Затем, как только у Selectel появился аналогичный сервис, перешли на него, чтобы сократить стоимость и увеличить скорость загрузки.

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

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

Наверное, где-то тут несколько наших серверов

Тогда оставалось решить только две проблемы — научить сервер принимать картинки и научить его их эффективно раздавать. Впрочем, второе — вовсе не проблема, настройка nginx для раздачи статики довольна тривиальна, главное, не забывать о клиентском кэшировании.

А вот чтобы загружать файлы на сервер, пришлось поднимать apache и настраивать там webdav. Это классический API, им пользуются, например, в Яндекс.Диске.

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

Можно было докупить ещё 100 мегабит, но выгоднее оказалось арендовать сервер на распродаже (и ещё 100 мегабит в комплекте). Теперь проблема заключалась в том, чтобы загружать картинки надо было только на один сервер, а раздавать сразу с двух.

Также надо было распределить раздачу картинок равномерно между двумя серверами. В этот момент мы уже понимали, что серверов может быть и два, и три и пять. Классическим решением этой задачи является Round Robin DNS — каждому домену для статики присваивается несколько ip-адресов, каждый из которых готов обслужить запрос. DNS-сервер отдаёт клиентам эти адреса в случайном порядке, обеспечивая равномерное распределение (на каждый сервер трафик льётся пропорционально).

На помощь пришёл lsyncd и этот пост на Хабре. Lsyncd — это такая программа, которая мгновенно синхронизирует файлы между серверами. На самом деле всем понятно, что не мгновенно, поэтому надо что-то отдавать в тот момент, когда пользователь запросил картинку с сервера, который её ещё не получил. В таком случае мы заставляем этот сервер пойти и самому забрать картинку с главного.

Ещё один важный момент — количество одновременных запросов к одному домену — многие браузеры ограничиваются максимум восемью, то есть если использовать один домен для всех картинок, они будут загружаться пачками по несколько штук. Не круто.

Поэтому мы научили nginx отвечать на любой запрос к доменам типа static34.cmtt.ru, где 34 — случайное число, генерируемое при загрузке картинки. Таким образом мы заставляем браузер загружать все картинки на странице одновременно.

Сейчас посетителей TJ обслуживают три маломощных сервера (Intel Core2Duo E8400 3.0 ГГц, 6 ГБ DDR3) под кодовыми именами Джиф-1, Джиф-2 и Джиф-3.

Третий нам пришлось поднимать в авральном режиме во время одной из трансляций презентации Apple, когда хлынувший поток желающих следить за фотографиями новых айфонов превысил 300-400 мегабит.

Несколько раз к нам обращались представители различных CDN-сервисов, но услышав, что трафик в 150-250 мегабит в секунду мы обслуживаем за 8 000 рублей в месяц, они разворачивались и уходили.

#tjdev

Популярные материалы
Показать еще
{ "is_needs_advanced_access": true }

Лучшие комментарии

Дискуссии по теме
доступны только владельцам клубного аккаунта

Купить за 75₽
Авторизоваться

Преимущества
клубного аккаунта

  • отсутствие рекламы
  • возможность писать комментарии и статьи
  • общение с членами клуба
Подробнее

Преимущества
клубного аккаунта

  • отсутствие рекламы
  • возможность читать и писать комментарии
  • общение с членами клуба
  • возможность создавать записи

Сколько это стоит?

Членство в клубе стоит всего 75₽ в месяц. Или даже дешевле при оплате за год.

Что такое клуб?

Клуб ТЖ это сообщество единомышленников. Мы любим читать новости, любим писать статьи, любим общаться друг с другом.

Вступить в клуб

Комментарии Комм.

Популярные

По порядку

0

Прямой эфир

Вы не против подписаться на важные новости от TJ?

Нет, не против