Как стать автором
Обновить

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

Не легче ли при создании пользователя в его запись, в базу, дописывать что-то типа avatar = '/img/default.png', а при обновлении аватара, перезаписывать это значение на url загруженной картинки..?

Если так хочется следовать принципу /img/avatar/$id.gif, то проверка его наличия средствами языка не займет много времени, но в сервер-то зачем лезть?
друзья, уже не 20-й век, используйте сервисы для хранения аватаров, они всегда будут лучше по функциональности загрузки аватаров, чем вы посчитаете нужным делать для своего сайта.
Некоторые сайты не позволяют грузить аватры с веб, вы об этом задумались?
1. и много таких сайтов?

2. грузит их не сайт, а браузер пользователя
Про рефереры не в курсе?
И что в них секретного?
А эти сервисы сами по себе в интернетах возникают и никто их не создаёт?
Их уже создали. Можете кстати еще и свой написать, будет наверно только лучше ;)
Где-то вы правы, gravatar хороший и очень интересный сервис. Однако для меня сделать загрузку своих аватаров не сложнее, чем прицепить граватар. Но вот научить пользователя юзать граватар или быть уверенным, что граватар всегда будет работать быстро и никогда не накроется медным тазом — это спорно.
Согласен, есть риск, но разве нет риска в том, что в кризис сдуется гугл? Хорошая новость здесь в том, что gravatar не единственный, то есть вы можете свои риски снизить за счет использования нескольких провайдеров решения.

И ведь вопрос не просто в тупой загрузке аватаров на файловую систему сервера, нужно еще сделать интерфейс для обрезки фотографии и т.д. и т.п., вот на это тратить время считаю совсем неправильно, нужно пользоваться готовым, ну конечно если загрузка аватара не является центральной функциональностью сайта :)
повторю, подчас подключить сторонний сервис (или несколько, как предлагаете вы) намного затратнее по времени, чем использовать свои готовые наработки
> devprom
вот глупости вы говорите. как говорят: учите матчасть, у предложенного вами метода минусов больше.
Хранить в базе '/img/default.png' не самый удачный вариант. По крайней мере, это лишняя инфа в базе, лишнее место.
А проверять средствами языка программирования несколько накладно. Веб-сервер работает на низком уровне, он в конце концов бинарник, а язык программирования зачастую (в мое случае php) лишь интерпритатор и подобные проверки могут быть «затяжными». Да и потом, зачем делать лишние телодвижения, если это за тебя уже сделал nginx?
Дак делайте все на HTML, чего вам лишний раз напрягать PHP, тем более что это за тебя уже сделал nginx?
Ну если вы за меня будете генерить html, то я только за.
У вас просто аргументация какая-то смешная. Вы не хотите избавить ваш сервер от лишнего HTTP запроса и пользователя от лишней картинки в кеше с дублируешимся содержимым, только потому что вам придется поставить лишний if в php.
nginx не жалуется, а картинка не будет закеширована. А вот php с этой задачей на больших нагрузках справляется не очень хорошо.
Одно ветвление в программе, один http запрос. Одно ветвление, один запрос… Подумайте на досуге, что для сервера проще.
=) и в моем и в вашем случае запрос к http будет. И, еще раз повторю, для nginx`а это НЕ проблема.
Не будет 100 лишних запросов к вебсерверу в случае с предварительной проверкой одного бита в php. В вашем случае — эти запросы будут. А работа с TCP затратнее, чем одно сравнение регистров процессором.
Я долго пытался быть адекватным, но в данном случае адекватная реакция будет такой:
Вы тупите и чушь мелите.
Когда вы проверяете существование аваторки при формировании страницы, это вам вообще ничего не стоит, проверка на пустую строку бесплатна. А 50 лишних запросов на каждую страницу стоят рессурсов сети. А если ваш посетитель на модеме, или в другом конце света, то это ему стоит еще и минуты времени. А еще вы предлагаете не загруженные аваторки защищать от кеша и загружать при каждой загрузке страницы.
Загрузить дефолтовую аватарку в вашем случае не будет http запросом?
Вы серьезно в упор не видете разницы между одним намертво закешированным запросом и 50 запросами на каждой странице?
Не убивайте во мне веру в людей.
не тормозите. тут речь идет о том что на странице если есть 50 пользователей и у них не загружены 50 аватарок, то все ссылки будут идти в случае проверки на /avatart/default.jpg. А в случае отсутствия таковой на 50 разных мест: /avatart/1.jpg, /avatart/2.jpg…
В первом случае реально выполнится один запрос, а во втором 50.

имхо и то и другое смешные нагрузки чтоб о них напрягаться. Все равно не загруженный аватар — это исключение: пользователи любят аватары -)
да вы тоже глупсти морозите.
ну запросится 50 несуществующих автарок, что с ними будет? прально они попадут в кеш. Нагрузка мизерная вообще чтоб за нее так человека обижать. Реально такое решение имеет право на существование — избавляет от лишних строк кода с проверками.

Другое дело что лично я конечно предпочту сделать проверку в PHP скрипте.
причины:/avatar/1.jpg — если это дает неожидаемые данные, то это парадокс системы — что не есть верно.
во вторых дефолтная /avatar/1.jpg может и будет закеширована, а когда появится истинная, то она может не быть загружена.
Может у Вас какой-то неправильный PHP?
На каких нагрузках PHP начинает тормозить на битовых операциях?
Расскажите поподробнее, если владеете сокровенными знаниями.
не могу поделиться честными цифрами, но по опыту php работает медленно с файловой системой. По крайней мере медленнее, чем это делает nginx.
А при чем в данном случае работа PHP с файловой системой?
Вам на пхп всего один бит проверять-то в данном случае.
Никаких операций с файлами.
Я видимо ошибся, перечитал ветку, речь идет о проверке инфы из базы, я был уверен, что о проверки наличия файла.
Moe решение на js, работает во всех популярных браузерах. Мне нужно было только в одном месте

<img src="/avatar/%user_id%.png" onerror="this.onerror=null;this.src='/server/images/avatar_bg.png';">


При желании эту проблему можно еще решить красиво через цсс чтобы в бекграунде картинки по дефолту грузился фон «avatar_bg.png», но джаваскрипт все равно пригодится, чтобы крестик не показывать в недоразвитых браузерах.

$('img').bind('error',showDefaultImg);
function showDefaultImg(ev){
with(ev.targe){
onerror=null;
src='default.gif';
}
}
with(ev.target){ // так вернее
это создаст много 404 ошибок в логах
Решение на js. Алё. Вы предлагаете делать полноценный запрос с генерацией 404 страницы средствами CMS да еще и не кешируемый. Это НЕ решение.
Одни домыслы.
+ пятьсот
Решение обламывается если нет доступа к конфигам. Если уж хочется сильно, имхо лучше в конфиге своего веб-приложения писать дефолтный аватар.
Если ваши проекты крутятся не на вашем или арендованом сервере, а тусуются на хостинге, то действительно вам это решение не подойдет =))) А много осталось людей, кто предпочитают хостинг? VDS и дедики ведь не дорогие совсем.
Решение обламывается на том моменте, когда пользователь хочет поменять аватар на другой. А старый продолжает грузиться у половины людей из кеша. Именно по этому удобно менять имя файла каждый раз (отключать кеширование графики — идея не из лучших). И именно поэтому придется это имя всё равно хранить в базе.
НЛО прилетело и опубликовало эту надпись здесь
Очень спорно. Интернет у всех давно шустрый, за трафик никто не платит. А что со стороны сервера, опять же для nginx`а не возникает никаких трудностей отдавать статику. С моей точки зрения как раз спорно писать в базу лишнюю инфу. Хотя это тоже, в общем-то, не накладно
Интернет у всех давно шустрый, за трафик никто не платит.

Не все живут в столицах.

Поинтересуйтесь, сколько стоит анлим, например, в Хабаровске.
В Хабаровске проживет 0,8% русского интернета
www.liveinternet.ru/stat/ru/regions.html
овчинка выделки не стоит, не в обиду жителям Хабаровска.
Не в Москве и не в Санкт-Петерббурге живут 48,7% пользователей интернета.
При небольшом размахе сайта не вижу проблемы в хранении имени файла в базе — как работало шустро, так и будет, и в Хабаровске все довольны.
При огромном сайте (тот же Хабр будет хорошим примером) экономии места в базе противостоит огромная загрузка канала. Что же это будет, если в комментариях к каждому посту по новой грузить все замылившие глаза аватары. Особенно, когда на одной странице стопятсот комментов.
Так что позвольте не согласиться, в любом случае именовать файлы выгоднее.
да есть такой вот облом. можно кстати спецова попросить загрузить файл и получить нужные заголовки.
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
в чем его не верность? человеческое время в разы дороже машинного.
НЛО прилетело и опубликовало эту надпись здесь
товарисч, идите на йух. Договоритесь с администрацией хабра, пусть всю мою карму вам переведут.
Делать пометки в базе каждый раз + подгонять скрипты однозначно «проще», чем дописать в конфиг 3 строчки.
НЛО прилетело и опубликовало эту надпись здесь
Чтоб не грузить по 10 раз — выдавайте не перманентный редирект, а не сам объект, например.
Хорошее highload-решение! Для тривиальных проектов оно, конечно, врядли нужно.
Простите, но в чем оно хорошее? Чуть выше точно написали: «10 раз грузим одну и ту же картинку, только по разным урлам» (с) т.е. к серверу происходит 10 обращений, вместо одного.
Хорошо если 10, а может быть и все 100!
не хорошее решение для хайлоада) в случае большого количества картинок, их хранение в одной папке не допустимо.
этот способ не отменяет /img/avatar/1/2/3/4/5.jpg, собственно, у меня все так и робит.
А что до хайлоада, то ошибаетесь. Фронт, тем более nginx, никогда не жрет больше Бэка или базы или мемкеша.
Не уверен. Ваш nginx работает с диском(в некоторых случаях сработает кэш ОС), а а бэк или база работают с оперативной памятью(в идеале). В общем спорный вопрос :) надо проверять эксперементально.
Вот как раз идеалогия nginx`а — таскать статику из оперы. А не бэка =) редкий бэк это умеет.
а /1/2/3/4/5 надо еще сформировать)… для этого надо лезть в базу например. Может я что то не допонимаю, но я думал что пользователь достает аватарки по нику или id просто.
есть много способов форматирования подобных директорий. На мой взгляд самый дейтсвенный — бить id по 2 или 3 символа. Типа аватар пользователя с id == 12345 Будет лежать в /img/avatar/12/34/5.jpg. Соответственно не надо лезть в базу и, опять же, делать какие-то лишние телодвижения.
Немного режет глаза количество грамматических ошибок. Но за материал спасибо.
Принципиально не вижу ничего хорошего в том, чтобы плодить ссылки на несуществующие файлы. Те же поисковые роботы засчитают это как ошибку на сайте, обилие таких ошибок — может негативно сказаться на позициях.
Не понял, в чем ошибка?
А что сервер отдает при запросе не существующей аватары? 404 или 200.

Если 404 — это будет расцениваться Яндексом как ошибка.
200. Там же написано, 404 не возникает.
error_page 404 = 200
Будет 200.
кстати, надо не
error_page 404 = 200
а именно
error_page 404 =200

nginx к пробелам очень категоричен.
В цикле.

$ava='';
if (file_exists('upload/useravatar/'.$mas['_id'].'/15avatar.png')){
$ava='<img class=«avatar15» src="/upload/useravatar/'.$mas['_id'].'/15avatar.png"&rt; ';
}
$t->replace_tags(array('ava',$ava),'usersmall');

Если нужно дефоулт аву, заменяем $ava='';
тоже одно из решений «в лоб». При более менее средней нагрузки изживет себя, т.к. php будет очень медленно работать.
И не стыдно вам сюда такую гадость писать?
file_exisits() — вы создаете bottleneck, не говоря уже о каше из php- и HTML-кода
НЛО прилетело и опубликовало эту надпись здесь
Решение «в лоб» будет тоже простым — писать в базу, загрузил пользователь аватар или нет. Но это потребует каждый раз обращаться в базу.
потому что вы работаете с БД как с массивом. Типичная беда многих начинающих «web-разработчиков».
О, а научите меня работать с базой пожалуйста.
В данном конкретном случае, информация об аватарке так или иначе присутствует в таблице с пользовательским профилем — или явно указано имя файла; либо если в качестве имени используется ID пользователя, всё равно необходимо хранить тип изображения (jpeg, gif, png). На мой взгляд — «решение в лоб»: при отсутствии аватары оставлять в таблице неопределённое значение — NULL.
А в операторе выборки использовать ifnull:
  select
    nick_name, ifnull(avatar,'аватарка по умолчанию'), title, message
    from users
    inner join messages on users.id=messages.user_id
    where 'условие выборки сообщений'
Точно так же можно «заполнить» другие поля: например, если не указан ник, показывать реальное имя, а если нет и его — логин:
  select ifnull(nick_name,ifnull(real_name,login)), ...  from ...
Если используется 5ый MySQL — лучше вообще создать представление (view) для выборки основных данных пользователя.
ifnull

В стандарте SQL есть coalesce. Что за страсть пользоваться говнофункциями, делающими то же самое?

лучше вообще создать представление

Чем лучше? По-моему ничем.

Честно говоря, не слежу за эволюциями ANSI SQL по двум основным причинам:
1. Если брать серьёзные сервера БД — стандарт безбожно отстаёт от полезных и эффективных инноваций реальных разработок. Если брать массовые SQlite и MySQL (у многих хостеров ещё 4ая версия стоит) — то уже они отстают от актуальной версии стандарта. Т.е. толку от него как от «семиуровневой модели OSI» — чисто академический, т.е. слабо применимый на практике.
2. Он закрыт — почитать можно только за денежку.

Вьюха позволяет разработчику абстрагироваться от реализации — он просто знает, что в запросе к ней получит отображаемое имя автора, путь к аватарке (ещё какие-то основные данные), а из каких таблиц-полей это всё берётся на самом деле — не важно. Можно вносить изменения в БД не перелопачивая весь приложения.
не слежу за эволюциями ANSI SQL
coalesce входил в стандарт, когда Вы еще в школе учились и вряд ли помышляли об SQL'е.

толку от него как от «семиуровневой модели OSI» — чисто академический, т.е. слабо применимый на практике.
Зачем придумывать отговорки? Так и скажите — никогда не знал про coalesce и мануал не читал.
Большинство широкоиспользуемых СУБД этот стандарт в основных моментах поддерживают. Но нет же, надо обязательно брать решение, которое поддерживается не всеми.

Он закрыт — почитать можно только за денежку.
Пользуйтесь, это бесплатно.

Вьюха позволяет разработчику абстрагироваться от реализации
Да что Вы говорите? Следующие Ваши слова, видимо, будут про ORM.
Для выборки основных данных пользователя Вы так и так будете использовать один основной запрос.
Но нет же, зачем-то нужно вводить промежуточную вьюху.
Спасибо, я знаю что такое варез и где им можно разжиться ;-)
Что вы докопались до этой функции? ifnull запоминается на раз и гораздо точнее отображает суть процесса. Поэтому код с ним нагляднее. Признаю, в примере coalescue был бы уместнее чем два ifnull, зато пришлось бы ещё комментировать, а так — всё понятно без дополнительных объяснений.
Слив засчитан :)
Об этом судить не вам ;)

В любом случае: не ошибается тот, кто ничего не делает. Я пытался в нескольких строчках показать как можно упростить разработку, расширив применяемый синтаксис SQL. А что делали вы? ;)
Я достаточно написал в комментариях к этому посту, чтобы донести основную мысль, что варианты решения вопроса могут быть и должны быть разными.

А Вас я поправил исключительно для того, чтобы те, кто будет читать всё это, не повторяли Ваших ошибок. И читали мануалы.
скажите пожалуйста, чем отличается мой предложенный «в лоб» способ от вашего? Я же не написал реализации sql запрос, я сказал что инфу можно хранить в базе и это не совсем верно с моей точки зрения. Вы же говорите что я начинающий разработчик и делаете то же самое, о чем говорил я.
Так же, хранить аватары приходится все равно в сжатом виде, терпеть не могу сервисы, которые просят залить 100x100 аватары и не шагу вправо-влево. При «пережиме» аватара его сохранять все равно в jpg, ибо жатая картинка в gif или png весит значительно больше, а значит хранить тип файла ни к чему. Как и наличие или отсутствие аватара.
Мой способ самодостаточен. Он не требует изменений в БД и не зависит от неё, id или login у пользователей в таблице будет как не крути.
ваша формулировка подразумевает лишнее обращение к БД каждый раз — я показал, что получение этой же информации из БД практически не требует никаких дополнительных телодвижений.
А я терпеть не могу сервисы, которые пережимают нормальные аватарки независимо от их размера и разрешения ;-) На самом деле — это ваша политика более жёсткая по отношению к пользователю. То что png будет больше чем jpeg — это заблуждение. В случае фотографии — да; но аватарки чаще рисованные — png получится меньше, качество картинки будет выше. Ваш способ менее универсален; более расточителен в плане ресурсов; не настолько дружественный для пользователя, как мог бы быть.
привидите мне в пример современный сервис, который не пережимает картинки аватарные, а если и делает это — сохраняет их в png. С ваших слов, вы тепреть не можете хабр, ННМ и далее по списку.
От других сервисов надо перенимать лучшие стороны, а не бездумно копировать функционал. На счёт «терпеть не могу» — я лишь перефразировал вашу фразу, чтобы вам же продемонстрировать просто возможность существования других мнений. Не надо передёргивать — никто из других читателей не подумал, то мы (вы и я) оцениваем сайт по аватаркам.
Я не говорил, что нужно отказаться от других форматов в пользу png — я лишь пояснил вам, что jpeg — не панацея. Ну и прежде чем что-то утверждать — неплохо бы это проверить ;-) На NNM аватарки не только в jpeg; а текущая ситуация с аватарками на хабре — вообще отдельный разговор ;)
Да, на ННМе аватарки не жмутся в том случае, если они не больше 60x60, делал я это специально, чтобы люди могли заливать анимацию и только. Смухлевал, вспомнив ННМ, просто ничего другое на ум не пришло.
png24 способно жрать меньше места, когда мы говорим о маленьких аватарах. Аватары 64x64 в png24 уже будут хавать по 5 килобайт, против 1 в jpg.
Если не хотите чтобы я вас передергивал и придирался к словам — не надо обезьянничать и попугайничать =) придумывайте свои формулировки, с карточными играми и непристойными девушками.
И по поводу бездумно копировать функционал. Приведенный мной пример в данном посту, который уже окрестили «вредным советом» как раз является относительно новым способом отображения аватаров, а не тупо скопированным с общепринятых. Я люблю изобретать велосипеды.
Если в конфигурации есть строка

if ($request_uri ...) {

это означает, что конфигурация неправильная. Для этого была специально была придумана и оптимизирована директива location:

location ^~ /img/avatar/ {
    error_page 404 =200 /img/avatar/default.gif;
    expires -1;
    access_log off;
}

location ~* ^.+\.(jpg|jpeg|gif|png|js|txt|css|ico|zip|rar|xml|swf)$ {
    expires 7d;
    access_log off;
}

Можно выделить отдельный

location = /img/avatar/default.gif {
    expires -1;
    access_log off;
}

если, например, нужно поставить expires, отличный от /img/avatar/.
Ого, Игорь Сысоев :-)
Если это вы, то огромный респект за nginx!
Действительно строка вроде
if ($request_uri ...) {
Не очень красива, но удобна. Все исключения для статики находятся под общим локейшеном для статики. Код конфига легко читается и не надо прыгать вверх-вниз, чтобы найти конкретное исключение. А исключений бывает не мало и порой требуются регулярки.
Насколько location *~ { оптимальнее if( $request_uri ) {?
Не спорь с автором картины о её смысле =)
НЛО прилетело и опубликовало эту надпись здесь
вы ветку комментов почитайте =) оказывается, не очень то и тривиально.
А почему скажем нельзя задать в конфиге константу CONF_AVATAR_DEFAULT и не париться и плясать с конфигами сервера. при обработке скрипта заменять на дефолтный.

CONF_DEFAULT_AVATAR = 'url';

if (!$user['avatar']) $user['avatar'] = CONF_DEFAULT_AVATAR;

оптимизации нужны только там где они реально нужны, а не на пустом месте.
именно это я и привел решением «в лоб»
100 пользователей в минуту загружают по 5 новостей, к каждой из которых 200 комментариев. Итого имеем 100 000 необходимых для загрузки аватар. Если прикинуть, что аватары стоят у 50% пользователей (на редком сайте), то мы ежеминутно имеем 50 000 паразитных некешируемых запросов к серваку.

Ну и кому оно такое надо?
а кому оно мешает? Не нравится некешируемые запросы — уберите заголовки антикеша и вуаля.
Вы, похоже, совсем меня не понимаете. Вдумайтесь еще раз. На бумаге нарисуйте, в конце концов.
Да я вас всех прекрасно понимаю =) вы боитесь 50 000 запросов к веб серверу в минуту?
Так где показывается аватар, там и показывается логин, значит в базу мы уже слазили, и получили признак наличия аватара. Чтобы не мучится с кешем, ставим его хоть на полгода, но при этом в базе храним счетчик обновлений аватаров. И если он больше, чем один, отдаем картинку с адресом /img/$id.jpg?$version, например /img/220.jpg?2
чуть опередили меня, я долго читал комменты :)
С другой стороны статья про nginix, просто пример не самый удачный.
Еще раз повторю. Вся прелесть моего способа в самодостаточности.
Вся прелесть Вашего способа — в перекладывании своих проблем от кривого проектирования системы на nginx. Действительно, способ рабочий, но эт не значит, что он оптимальный.
Byte, кончай гнать и напиши хоть один положительный коммент, а лучше пост, подчеркну, положительный. Достал плакаться.
Мой способ не юзает базу, работает отдельно, по сути не требует её наличия. Есть сервис — gravatar.com, суть примерна та же. Почитай. И работает он практически так же (досконально их реализации я не знаю), как и предложенный способ мной — независимое, целостностное хранение аватаров. Граватар тоже перекладывают свои проблемы кривого проектирования?
напиши хоть один положительный коммент, а лучше пост, подчеркну, положительный. Достал плакаться.
Положительные посты — это не ко мне.
О своих успехах я не распространяюсь, а ближнего пнуть на путь истинный — милое дело.

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

Приведу пример.
Если сервис изначально целиком динамический, кеширование применяется незначительно, за данными постоянно нужно ходить в базу, то заложив при проектировании одно поле в таблицу юзеров для различных флагов (а наличие аватара — всего лишь флаг), можно прекрасно обойтись без излишних запросов, выводя где нужно аватар, где его нет — дефолтную картинку, прекрасно кешируемую в браузере. $flags & 0x1 — очень быстрая операция сравнения.

Второй пример.
Сайт — практически статика (или хорошо кешированная динамика), в базу решено ходить по минимуму, мемкеш не нужен, ибо особо нечего там держать, да и лишняя прослойка. Тогда вариант решения — переложить логику отдачи аватаров на быстрый акселератор (например, nginx), повесить его на отдельный ip, врубить небольшой кип-элайв и отдавать аватары в рамках одной TCP-сессии. И всё-таки отправлять команду их кешировать. Хотя бы на среднее время ежедневной жизни на сайте среднего пользователя проекта.

Вы упираетесь в один метод.
Я — знаю несколько методов и могу заранее выбрать подходит ли мне какой-то из них.
Мой подход — правильней.

А кунфу сильнее, угу.
Я писал совсем о другом. Мои аватары абстрагированы от моей базы. Есть у меня реляционно-ориентированная база, либо эта база на файлах или еще где угодно — мне не нужны никакие флаги. Есть отдельно база, есть отдельно аватары. Я могу брать любую базу, любого проекта в любом виде и без внесения изменений в неё прицепить аватары к проекту.
Мой способ лёгок, он не делает доп. нагрузки серверу до определённых пределов (которые, несомненно, очень высоки), затыком всегда будет либо база, либо бэк, никак не фронт. Уважаемый И.Сысоев писал о том, что nginx сопобен выдержать 10 000 запросов в секунду, это 864 000 000 запросов в сутки. В веб-разработке я лет 6, не так и много, однако я любитель своих велосипедов и перепробовал много способов хранения и доступа к аватарам. Был проект, где аватары хранил в базе. Представляю, как меня сейчас закидают помидорами, но очень даже удобный способ. Базу легко масштабировать, легко балансировать нагрузку, а аватары из базы не так уж и накладно + был написан кеширующий демон на си. Хотя, если честно, он не дал особого прироста производительности — выборки и так проходили довольно быстро.
Со временем я понял, что моё время дороже, посмотрел на все ранее используемые способы и решил что данный — самый простой и «ленивый», в то же время никаким образом не создает лишней нагрузки.

Возможно, вы считаете, что я упираюсь в один способ, т.к. изложил только его. Опираясь на ваш коммент, вы знаете 2 способа. О да, ваше кунфу сильнее.
> в то же время никаким образом не создает лишней нагрузки.
Пойми, он как раз создает лишнюю нагрзку! 50 лишних капросов на каждую старицу это хухры-мухры. Это секунды или минуты времени ожидания клиента. Лишние запросы — то, от чего нужно избавляться в первую очередь когда сайт на клиенте стал долго грузиться. И не надо кичиться шестью годами в разработке. Звучит как «я старый пердун и вы меня хрен переубедите».
В личку тебе уже отвечал на эту тему, поставить expires 1h; и иди уже расслабься. И где я хвастался, что 6 лет в разработке это просто мега супер пупер и что я старый пердун? Это писец как мало, когда я только начал, уже были яндексы, гугли и прочие, я уже опоздал =) За меня все уже придумали =)
Да не надо в базе аватары хранить. И даже пути к ним — не надо. Головой думать надо.

данный [способ]… не создает лишней нагрузки.
На сервер — практически не создает, да. На сеть и клиента — создает. Второе даже более критично. Юзер будет ждать пока загрузятся несуществующие аватары (открою секрет — они не могут грузиться браузером все одновременно, существуют ограничения на соединения с одним хостом). Считайте это законом сохранения нагрузки — если где-то нагрузки убывает, значит где-то ее прибывает. Вы и перекладываете с больной головы на здоровую.

Уважаемый И.Сысоев писал о том, что nginx сопобен выдержать 10 000 запросов в секунду
Тут ко мне на собеседование приходил один товарищ, утверждал, что написал софт, который выдерживает до 70 тысяч запросов в секунду… А еще я слышал, что Петя Зайцев Мускулом Оракл порвал… Дальше-то что? По-любому, если нгинксу надо выдерживать не N запросов, а 10*N, то эт несколько хуже. Даже если не отражается на нагрузке.

Опираясь на ваш коммент, вы знаете 2 способа
Эт я Вам по доброте душевной два рассказал. Могу больше. Консультации оплатите?
Аватары в базе — удобная концепция, к которой, я уверен, скоро прийдет интернет. Так же как все пересели на mysql, со словами: «Фууу, из-за неё сервер тормозит».
Перекладывая боль с больной головы на здоровую и есть балансировка нагрузки, не правда ли?
Сысоев не писал, я не правильно сформулировал, Сысоев раскрыл тему, как довести до ума сервер, чтобы nginx был способен обрабатывать до 10 000 запросов в секунду.

По поводу консультации спасибо =)) буду иметь введу =)
Петя Зайцев Мускулом Оракл порвал…

оценил шутку
Вообще слабо понимаю о чем речь. Зачем это не очень красивое, на мой взгляд, решение подкрепленное аргументом:
Решение «в лоб» будет тоже простым — писать в базу, загрузил пользователь аватар или нет. Но это потребует каждый раз обращаться в базу.
А вы, простите, данные пользователя где храните? Может в файлах, или прямо в html коде?
При любом выводе пользователя рядом с аватарой, в любом случае придется делать запрос к базе чтобы узнать инфу о нем, а значит речь уже идет о какой-то мифической экономии — меняем одно поле в базе на некешируемые перелокейты nginx`а
А вы, простите, данные пользователя где храните?

Регистрационные данные юзера (ник, аватар, что-то еще) на одном сервере баз данных, комменты к статьям — на другом. Физически другом.

Ваши действия по оптимизации?

некешируемые

Файловую систему тоже не дураки пишут.
Если nginx пока ничего не кеширует, это не означает, что совсем ничего нигде не кешируется.
Так вам в любом случае чтобы комент собрать надо к 2-м серверам обратиться — с одного ник цепануть а с другого сам коммент. Я что-то потерял нить мысли, как это относится к теме беседы.
Да, действительно, не совсем корректно выразился.

Я к тому, что часть данных, необходимых для вывода комментариев (ник + id, больше ничего не надо), может хранится на одном сервере, а более полные данные о юзере (включая аватар) — на другом. И зачастую на этот другой у проекта-сателлита доступа нет.
Ну это очень уж частный случай…
если уж такая экономия то к ник+id можно прицепить хотя бы булево поле «аватар» да/нет
все равно мне кажется так будет все шустрее и семантически более верно, чем перекидывание 404 стараниц в 202 по запросам браузера
Ну как сказать «частный»… Почти все проекты Мэйл.Ру, Рамблера итп… Частный случай, говорите? :)
Я вообще к тому, что способов можно придумать много и лучше выбирать способ под конкретный проект, а не рассуждать о правильности или неправильности сферического метода в вакууме
Я не знаком с nginx'ом, но мне кажется, что делать редирект — не очень хорошо.
Я уверен, что можно таким же образом указать, чтобы 404я ошибка не генерировалась, а сразу, без редиректа выдавалась дефолтная картинка.
Ребята правильно сказали, нечего не нужно посылать кучу запросов.
Ребята правильно сказали? Т.е. вы вроде как комменты читали? Я в посте акцент сделал на то, что 404 не будет, и в комментах еще раза 2 о этом повторял. Хотя в общем слушайте ребята, они умные =)
скорее «Вредные советы» ^_^
Для автарок правильнее делать отдельное поле в таблице. А вот для удаленных изображений (на которые остались старые ссылки) можно и через 404 или через js как говорили выше. В том году тоже замарачивался с этой темой изображение недоступно
люблю такие красивые «ленивые» решения. это круто. респект автору.
За «ленивые» спасибо =) Лень вообще великая штука, она изобрела такие неотъемлемы вещи в нашей жизнь как пульт дистанционного управления, RSS, гидро усилитель руля и много других полезных штук =)
Отличное решение, давно применяю. Хочу только добавить, что:
а) реализаций может быть много, не обязательно через 404
б) под апачем тоже можно провернуть такую штуку

Сторонникам хранения флагов и прочей инфы касательно аватаров — в БД: БД, к сожалению, в подавляющем большинстве случаев не умеет быть синхронизирована с ФС, таким образом, этот подход чреват ошибками, особенно в случае, когда картинок много. Например, в одном из моих проектов администраторы попросили доступ к ФС через ФТП, чтобы удалять и загружать картинки целыми папками — ну вот удобнее им работать через ФТП в данном случае, чем через административный веб-интерфейс. Реализация показа дефолтных картинок с помошью веб-сервера в данном случае — просто спасение, иначе пришлось бы на каждую картинку проверять в программе, существует ли тот или иной файл, а при определенных условиях это непозволительная роскошь.
Да уж. В иной раз лишь отметил бы для себя ваш ник и пошел дальше, но сейчас, после долги споров в комментах, не могу не отметить комментарий, практически единственный верный в данном обсуждении.
А то начинают лечить блин.
Как вариант, конечно-же, интересно, но ведь nginx отсутствует на обычном хостинге. Хотя могу ошибаться.
Во всех своих проектах я используую обычную запись в .htaccess положенный в папку с аватарами:
ErrorDocument 404 /img/avatars/0.gif

Этого вполне достаточно.
Да, что-то вроде. Замечу лишь то, что .htaccess порой непозволительная роскошь на больших проектах и то, что в вашем случае, насколько понимаю, будет генерироваться 404 ответ. Или я ошибаюсь?
Ответ будет 200 ОК, если не генерировать другое в /img/avatars/0.gif
Паразитные ссылки… однозначно желательно отдаватьссылку на один «аватар по умолчанию».

Если мы знаем о пользователях, собираем их в массив, потом вытягиваем одним запросом все пути к аватарам и вперёд.
Если бы мне дали готовый проект с таким решением и попросили заменить картинку дефолтного аватара, то я бы голову себе сломал в поисках нужного файла прежде, чем догадался заглянуть в конфиг нгинкса. Mobilz, вы задумывались об этом аспекте? Я так понял, вы эту штуку не только в свои личные проекты вставляете?

Ну и о клиентской и не только оптимизации, тут уже говорилось.
Сам факт того, что вам бы дали готовый проект с подобным решением, говорит о том, что вам бы дали доступ к серверу. Т.е. вы как минимум должны владеть консолью и понимать принципы работы веб-сервера в целом. Любой проект, который обслуживает nginx, в первую очередь
нужно читать именно с конфигов nginx`а, потому как именно там кроются все правила, реврайты и подобные исключения.
О клиентской и прочей оптимизации тут действительно написали много и в обещем все остались правы. Я никому и не доказываю, что это мега оптимальный способ. Но он экономит время программиста не в ущерб машинному времени и времени пользователя.
Если это большой проект, то мне бы вряд ли дали доступ к шеллу какого-либо сервера, мне бы дали доступ к svn или какой-то другой системе контроля версий и что там на фронте стоит в продакшене я мог бы только догадываться и алгоритм моих действий был бы таков:

1. Найти на сайте комментарии от юзеров с аватаром по умолчанию и посмотреть его урл.
2. Найти нужный файл в рабочей копии и заменить его.
3. Сделать коммит.

А тут я увижу, что у всех юзеров у дефолтных аватаров разные урлы. Вряд ли догадаюсь, что это рерайт, т.к. для статики обычно рерайты не делают. Предположу худшее, что можно предположить: при регистрации каждого юзера, ему создается отдельный файл с дефолтным аватаром. Т.к. обычно в свн аватары юзеров не кладут (кроме дефолтного, конечно), я не увижу, что этих файлов реально не существует и придется лезть в код, где происходит регистрация. Конечно же не найду там ничего такого, но времени потрачу изрядно. Короче, про рерайт я вспомню в последнюю очередь — это точно.

Ситуация, конечно, абстрактная, но суть тут вот в чем: вы, сделав такой, или любой другой, неочевидный сходу хак свое время сэкономите здесь и сейчас, а кто-то другой, или даже вы сами через несколько лет, на этом же месте кучу времени потеряет.
Подождите =) если вам дают крупный проект и SVN к нему, 100% у нему есть трак, в котором есть полная или частичная документация, в которой первой строкой будет инфа о аватарах. Да и потом, так трудно догадаться, что дефолтовый аватар лежит в /img/avatar/default.gif?
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории