Работа

Метрика загруженности процессора (CPU utiliztion) — это не то что вы думаете

Submitted by Ромка on Сб, 24/06/2017 - 13:09

Ромка аватар

Всем привет. Предлагаю вашему вниманию свой перевод поста "CPU Utilization is Wrong" из блога Брендана Грегга.

Метрика загруженности процессора (CPU utiliztion), которую все мы привыкли использовать, обычно понимается неправильно. Что такое загруженность процессора? То насколько процессор сейчас занят работой? Нет, это не так, и да, я говорю о метрике %CPU, которая используется всегда и везде, в каждой утилите мониторинга производительности, например в top(1).

Как вы думаете, что значит нагрузка на процессор 90% на картинке ниже?

Вот что это значит на самом деле:

GNU parallel и xargs. Параллельный запуск нескольких копий команды с разными аргументами

Submitted by Ромка on Сб, 19/09/2015 - 16:07

Ромка аватар

Задача

GNU Parallel
Есть консольная команда вида:

./do-something.sh -x 1

Значение аргумента x может меняться в диапазоне от 1 до 30 000. Выполнение команды для одного аргумента занимает от 30 секунд до 15 минут. Нужно максимально быстро выполнить эту команду для заданного диапазона аргументов на N-ядерном сервере максимально используя ресурсы сервера.

Возможные варианты решения

  1. Простой цикл от 1 до 30 тысяч с запуском команды на каждой итерации будет использовать только 1 ядро. Это решение неприемлемо: оно будет работать слишком долго и не задействует все доступные ресурсы сервера.
  2. Можно вручную разбить диапазон на N частей и запустить N циклов вида:
  for i in `seq 1 1000`
  do
      ./do-something.sh -x $i
  done

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

Введение в Content Security Policy (CSP)

Submitted by Ромка on Сб, 06/09/2014 - 18:58

Ромка аватар

Content Security Policy
Перевод статьи Майка Веста An Introduction to Content Security Policy от 15 июня 2012 года. Несмотря на то, что статье уже больше 2 лет, информация все еще актуальна и полезна. Об интересном опыте внедрения CSP в Яндексе можно почитать в этой статье.


Модель безопасности в вебе базируется на политике одинакового источника (same origin policy). Только код сайта https://mybank.com должен иметь доступ к данным https://mybank.com, а https://evil.example.com ни при каких условиях не должен получить такого доступа. Каждый источник остается изолированным от остального веба, что дает разработчикам безопасную песочницу, в которой можно разрабатывать и экспериментровать. Теоретически, это бриллиант без изъяна, но на практике, злоумышленники могут найти способы обойти эту систему.

Например, такие атаки как межсайтовый скриптинг (Cross-site scripting, XSS) позволяют обойти политику одного источника, обманным путем заставив сайт доставить вредоносный код вместе легитимным контентом. Это большая проблема, так как браузеры доверяют всему коду, который показывается на странице, так как он является частью страницы доставленной из доверенного источника. XSS Cheat Sheet — это старый, но весьма актуальный список методов, которые могут быть использованы злоумышленниками для внедрения зловредного кода. Если злоумышленнику успешно удается внедрить любой код в страницу, то игру можно считать оконченной: данные сессии пользователя становятся скомпроментированными и информация, которая должна оставаться в секрете, попадает в руки к Плохим Парням™. Мы, конечно же, хотим предотвратить такую возможность.

Этот туториал освящает один многообещающий механизм защиты, который может значительно снизить риск и вред от XSS-атак в современных браузерах — Content Security Policy (CSP).

Перевод книги "PHP Internals Book"

Submitted by Ромка on Чт, 19/06/2014 - 17:40

Ромка аватар

Взялся за перевод на русский язык книги "PHP Internals Book". Книга посвящена внутренней логике работы интерпретатора PHP и в первую очередь будет интересна разработчикам на языке C, которые хотят научиться писать расширения для PHP, но и PHP-разработчики, думаю, найдут для себя немало полезной информации.

Перевод является неофициальным (хотя и сделан с разрешения авторов), так что все камни о качестве перевода кидать в меня.

Почитать книгу онлайн можно тут: http://romka.gitbooks.io/php-internals-book-ru/, скачать в формате для читалок тут: https://www.gitbook.io/book/romka/php-internals-book-ru, помочь с переводом тут: https://github.com/romka/phpinternalsbook-ru.

На данный момент переведена только одна глава, но я продолжаю работу.

Важно учитывать, что структуры данных, описанные в книге, актуальны для современных версий PHP (на данный момент это PHP 5.5). Если один из следующих релизов будет слит с веткой phpng, то часть структур и алгоритмов, описанных в текущей версии книги, устареют.

Об области видимости переменных

Submitted by Ромка on Пнд, 12/05/2014 - 12:21

Ромка аватар

Цитата из книги Стива Макконелла "Совершенный код":

Разница между философией «удобства» и философией «интеллектуальной управляемости» сводится к различию между ориентацией на написание программы и ориентацией на ее чтение. Максимизация области видимости может облегчить написание программы, но программу, в которой каждый метод может вызвать любую переменную в любой момент времени, сложнее понять, чем код, основанный на грамотно организованных методах. Сделав данные глобальными, вы не сможете ограничиться пониманием работы одного метода: вы должны будете понимать работу всех других методов, которые вместе с ним используют те же глобальные данные. Подобные программы сложно читать, сложно отлаживать и сложно изменять.

Видеопроигрыватель для сайтов обучающих иностранным языкам

Submitted by Ромка on Чт, 23/01/2014 - 21:12

Ромка аватар

MediaElement language learning plugins

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

За эталон, к которому я стремился при разработке, был взят проигрыватель http://www.yabla.com (не буду скрывать, изначально планировалось склонировать ресурс целиком, но проект не завёлся). Этот проигрыватель обладает следующими особенностями:

  1. навигация по таймлайну осуществляется не с точностью до секунды, а с точностью до предложения. Человеку, изучающему язык по видеороликам, часто приходится проматывать видео назад, чтобы несколько раз переслушать неразборчивую фразу и гораздо удобнее одним кликом переместиться к началу фразы, а не искать её начало несколькими кликами.
  2. Каждая фраза может быть зациклена, чтобы прослушать её многократно.
  3. Разбивка таймлайна на фразы не требует от редактора какой-то особой подготовки: данные о таймингах выбираются из стандартного srt-файла с титрами.
  4. Титры на всех доступных языках выводятся под видеороликом (при желании могут быть скрыты). Эта особенность позволяет, например, показывать пользователю титры на языке оригинала видео и на родном языке пользователя. Клик по слову в титрах ставит видео на паузу и показывает пользователю перевод слова, по которому сделан щелчок.
  5. Таймер показывает не только время от начала видеоролика, но также номер фразы и общее число фраз в ролике.
  6. Скорость проигрывания ролика может быть замедлена или ускорена.
  7. Переход между фразами возможен не только кликом по таймлайну, но и при помощи хоткеев Ctrl + стрелки влево/вправо. Другие горячие клавиши: пробел — зациклить фразу/снять зацикливание, Ctrl + стрелки вверх/вниз — изменение скорости ролика.

Для демонстрации работы проекта я сделал небольшой сайт: http://lang.kece.ru/ (все видеоролики на нем позаимствованы с других ресурсов), сам проигрыватель с установленными плагинами можно увидеть, например, тут: http://lang.kece.ru/ru/series/introducing-artifical-intelligence/video/c.... В принципе, при небольшой доработке, плагины могут быть использованы не только с целью просмотра обучающих роликов, но и с целью просмотра полноценных фильмов/сериалов. Доработка понадобится потому, что если в видео фраз больше чем 20-30, то таймлайн превращается в кашу из мелких блоков с фразами и навигация при помощи кликов мышью становится почти бесполезной, но в таком случае выручает использование горячих клавиш.

Подробности в продолжении

Проблема с кодом вне функций в Drupal 6 и 7

Submitted by Ромка on Пт, 21/06/2013 - 10:25

Ромка аватар

Столкнулся с интересной проблемой, которую удалось повторить и в Drupal 6, и в Drupal 7. В модуле вне тела функции была объявлена константа:

  1. define('TEST_CONST', drupal_get_path('module', 'test_module'));

(тут дело даже не в самой константе, а в использовании апишной функции drupal_get_path() вне тела функции).

Этот модуль долгое время корректно работал, до тех пор пока в нем не был объявлен hook_exit(). После этого события Друпал начал отдавать ошибку "PHP Fatal error: Call to undefined function drupal_get_path() in...", где вместо drupal_get_path() можно поставить почти любую функцию из Drupal API, которая была использована в коде, расположенном вне тела функций.

Поиск и исправление причин ошибки осложнился тем, что она стала проявляться не сразу после добавления hook_exit(), а спустя некоторое время.

Суть ошибки оказалась в следующем:

  • Друпал в таблице system, модулям которые реализуют hook_exit(), проставляет значение 1 в колонке bootstrap, по умолчанию этот параметр равен нулю.
  • В свою очередь модули отмеченные таким образом начинают загружаться Друпалом раньше остальных (на этапе DRUPAL_BOOTSTRAP_LATE_PAGE_CACHE в случае Drupal 6) когда API, в частности файл common.inc, содержащий функцию drupal_get_path(), еще не загружен полностью.
  • Загрузка модуля подразумевает include файла модуля и, что логично, исполнение кода, находящегося вне тела функций.

Таким образом, после добавления hook_exit() модуль стал загружаться до полной загрузки API и функция drupal_get_path() на этом этапе действительно еще не была определена. Решилась проблема переносом проблемного кода в hook_init().

Возникла ошибка не сразу от того, что обновление поля bootstrap в таблице system делается не сразу, а при обновлении кеша списка модулей (вызов функции module_rebuild_cache() в Drupal 6). Этот кеш очищается, например, при нажатии кнопки "Сохранить" на странице списка модулей или при срабатывании модуля Update status.

Похвастаюсь статистикой в день сообщения о разводе Путина

Submitted by Ромка on Вс, 09/06/2013 - 22:28

Ромка аватар

Средняя нагрузка на сайт днем в рабочий день 1000 запросов в минуту (масимум 30-40 в секунду), около 200 тысяч уников в день и около 800 тысяч просмотров. Трафик отдается на скорости до 10 мегабайт в секунду.

В пиках нагрузка раньше доходила до 4 тысяч запросов в минуту (до 120 в секунду), около 350 тысяч уников в день и 2,5 млн. просмотрв. В пиках трафик отдавался на скорости до 50 мегабайт в секунду.

Пятница, 7 июня. В пике сайт отдавал больше 12 тысяч страниц в минуту (250 в секунуду) на скорости около 110 мегабайт в секунду.

visitors
Traffic by minutes
First frontend
Second frontend
Drupal + Varnish отработали на отлично. С учетом нашего канала и железа сайт может держать вдвое большую нагрузку подобного плана.

Интеграция системы статистики Piwik с Drupal 6

Submitted by Ромка on Вс, 21/10/2012 - 13:48

Ромка аватар

При работе над Drupal-проектом у меня возникла необходимость сбора детальной статистики о просмотрах материалов и вывода этой статистики в виде блоков, отображающих самые просматриваемые материалы за последние день, неделю и месяц. Стандартный друпальский модуль Statistics (и в шестом, и в седьмом Друпале) для решения такой задачи абсолютно неприменим:

  • во-первых он осуществляет сбор статистики на hook_exit() и не будет работать корректно со сколько-нибудь серьезными системами кеширования, например при использовании Varnish или модуля Boost.
  • во-вторых модуль Statistics собирает статистику за всё время существования материала, сделать выборку вида: "сколько раз был просмотрен материал за последний день" с этим модулем невозможно. По этому при использовании этого модуля исходную задачу пришлось бы модифицировать к виду: вывести список самых просматриваемых материалов созданных за последние день, неделю или месяц, но этот подход неприемлем, так как на сайте существуют материалы старше месяца, способные попасть в топ по просмотрам.

Таким образом, возникла необходимость внедрить полноценную систему статистики и интегрировать ее с Друпалом. Под полноценными системами я понимаю сервисы типа Google Analytics или Яндекс.Метрика, используя API которых можно запросить статистику просмотров материалов за любой диапазон дат. Достоинством этих сервисов является то, что они у себя хранят всю статистику, а она на посещаемом ресурсе может занимать немало места, их недостаток — все таки это внешние сервисы и неизвестно, что с ними случится завтра: сломаются, станут платными, не захотят внедрять нужную пользователю фичу и т.д.

В итоге я решил установить на собственном сервере open source систему статистики Piwik и интегрировать ее с Друпалом. Да, Пивик пока местами уступает GA и Я.М в гибкости отчетов (хотя есть в нем и отчеты, которых нет ни в ГА, ни в Я.М), но, во-первых, нужную мне задачу он решает, во-вторых он постоянно развивается своими разработчиками и может быть расширен с помощью самописных плагинов.

Для седьмого Друпала есть замечательный модуль Piwik stats, интегрирующий Друпал с Пивиком. Суть модуля состоит в том, что он создает специальное поле, которое может быть прикреплено к любой entity (материалу, пользователю). В настройках поля задается параметр, отвечающий за то, статистика за сколько дней должна быть в этом поле. Одна entity может содержать несколько полей с разными настройками, то есть, например, каждый материал может содержать три поля с информацией о просмотрах за последние день, неделю, месяц, как раз то что мне и требовалось.

Заполнение полей данными осуществляется через Drupal Queue API по крону, но при желании стандартный механизм обработки очереди может быть заменен чем угодно, например Rabbit MQ.

Плюсом хранения статистики в полях является то, что статистика становится прозрачно интегрированной со всем модулями Друпала, например с Views, с помощью которого, в том числе, можно строить блоки с контексто-зависимой статистикой. То есть, например, на главной странице сайта выводить список самых популярных статей со всего сайта, а на странице статьи или раздела — выводить самые популярные статьи текущего раздела.

Основная проблема для меня состояла в том, что модуль Piwik stats работает только под седьмым Друпалом и его разработчик не планировал делать бэкпорт под шестерку, а проект, в котором мне понадобился этот функционал, работает как раз на древней шестой версии Друпала. По этому я сам сделал бэкпорт этого модуля под шестерку. Забрать мою версию модуля можно из sandbox-проекта Piwik_stats, обсуждение этого бэкпорта с автором основного модуля тут: http://drupal.org/node/1736398.

Пока мейнтейнер модуля не хочет делать мою версию модуля официальной, из-за того, что требуется сделать детальный code review. Тем не менее, мой модуль без нареканий больше месяца работает в бою на двух Друпал 6 проектах.

Typo — Drupal-модуль для борьбы с опечатками на сайте

Submitted by Ромка on Сб, 15/09/2012 - 20:11

Ромка аватар

Разработал новый модуль для Drupal 7, который позволяет пользователю выделить мышью найденную в тексте опечатку и нажатием Ctrl + Enter отправить сообщение о ней администратору сайта. Модуль не зависит от внешних сервисов типа Орфуса и тесно интегрирован с популярными модулями Друпала такими как Rules, Token, Views и Views bulk operations.

Интеграция с модулями Rules и Token, позволяет, например, настроить отправку сообщений о найденных ошибках по е-мейлу, в системный журнал или вызвать любое другое действие, доступное в модуле Rules. С помощью токенов [typo:url], [typo:text] и [typo:comment] в текст сообщения можно включить информацию об опечатке.

Интеграция с Views позволяет сделать вывод списка ошибок на странице, в комплекте с модулем уже идет настроенное представление, а интеграция с Views bulk operations позволяет удалять из этого представления обработанные сообщения.

По умолчанию, все сообщения старше 3 дней автоматически удаляются, но это действие можно отключить в настройках модуля.

Popup-окно с формой отправки опечатки выводится модулем Ctools и его вид может быть изменён как правкой CSS-файла, так и правкой соответствующего tpl-файла. Ctools — это единственная зависимость модуля, остальные модули (Rules, Views, etc) нужны только если вы хотите использовать соответствующий функционал.

Скачать модуль можно на странице проекта: http://drupal.org/project/typo.

Испытать этот модуль вы можете прямо на этом сайте, список отправленных отчетов об опечатках доступен всем посетителям здесь: http://romka.eu/typo-reports (на реальном сайте к этому представлению анонимам лучше не давать).

upd
Модуль упомянули в обзоре в блоге Cocomore, жду наплыва установок на агнлоязычных сайтах :)

Страницы

Subscribe to RSS - Работа