Иван Авсеянко @Rebus
Программист
Information
- Rating
- Does not participate
- Location
- Москва, Москва и Московская обл., Россия
- Date of birth
- Registered
- Activity
Specialization
Backend Developer, Fullstack Developer
JavaScript
HTML
CSS
Web development
Perl
MySQL
PostgreSQL
Redis
Nginx
High-loaded systems
Навскидку придумал следующее решение. Можно попробовать использовать встроенный интерпретатор перла. В данном случае он будет весьма к месту, тогда алгоритм примерно следующий:
— получаем запрос к файлу с картинкой;
— в perl-хэндлере вычисляем md5 от запрошенного названия файла, и делаем internal_redirect на заранее описанный location, вида /cached_files_path/just_calculated_md5.jpeg;
— в описании локейшна /cached_files_path/ описываем фоллбэк для 404, как путь к скрипту, который эти файлы генерит и отдаёт;
Это должно сработать, а, поскольку вычисление md5 — процедура с достаточно предсказуемым временем выполнения, к тому же без ввода-вывода, решение не приведёт к дополнительным тормозам. Но, возможно я что-то упустил, так что пинайте меня, если я неправ. :)
Во-первых, есть множество устройств, которые не полностью поддерживают JS, или имеют проблемы с его поддержкой. Во-вторых, у многих пользователей Firefox стоит расширение Noscript (что совершенно правильно, учитывая недавно обнаруженные в ветке 3.5 дыры). Кроме того, есть множество старых компьютеров, на которых JS отключен по причине низкой производительности (или используется какой-нибудь IE5, что ещё страшнее).
Конечно, в общем случае, это, даже суммарно, достаточно небольшая доля пользователей (максимум, 0,5%). Но 0,5% от 1000 человек — это пять человек, пять потенциальных покупателей вашего интернет-магазина. Почему бы не позаботиться о них, если это стоит совсем недорого… А если у вас 2-3 миллиона посетителей ежедневно?
Не надо отталкивать людей, с отключенным Javascript, вместо этого можно чуть более грамотно спроектировать своё приложение. Ведь, при правильном подходе, поддержать их не так уж и долго и сложно.
Отдача статики nginx в разы быстрее, чем любой скрипт на любом динамическом языке. К тому же, в описанном случае вам вообще не надо запускать интерпретатор — и вы экономите ещё мегабайт пять-пятьдесят на нём. :)
А коллега как-то не вполне рад качеству драйвера под Вистой — модем почему-то не всегда определяется сразу после включения. Опять таки, девайс новый, его поддержки «из коробки» нет, наверное, ещё ни в одной ОС, так что я даже скорее удивлён, что всё заработало без особых проблем и сразу.
В общем, дело в том, что, на текущий момент, почти весь дисковый ввод-вывод в Nginx — синхронный. Игорь сейчас работает над тем, чтобы переделать его на AIO, но результат может появиться ещё не скоро.
Синхронность работы с ФС, при обычной нагрузке веб-сервера, не составляет проблемы, поскольку обычно отдаётся относительно небольшое количество мелких файлов, которые прекрасно размещаются в кеше ОС, и читаются оттуда практически мгновенно. Тем более, что системные вызовы write* итак реализованы в той или иной степени асинхронно (об этом обычно заботится драйвер файловой системы).
А вот в случае нагрузки, характерной для файлового хостинга — большое количество больших файлов, которые не помещаются в кеш, и запрашиваются почти рандомно — имеет смысл создавать «по процессу на жёсткий диск» именно для того, чтобы избежать блокировок на дисковом вводе-выводе. Это не очень хорошо, но, если подумать, в этом случае тормозом, в любом случае, станет жёсткий диск, а эту проблему никаким асинхронным вводом-выводом не решить.
Кстати, системный вызов sendfile работает в большой степени синхронно. Он позволяет избежать лишнего копирования данных в адресное пространство процесса, но, не выполняет отдачи данных «совсем в фоновом режиме» (впрочем, если работать с асинхронными сокетами, ситуация, кажется, немного меняется).