Навигация
На днях столкнулся с достаточно популярной проблемой съедания Апачем всех ресурсов с дальнейшим отказом в обслуживании. Как и в аналогичных случаях, netstat -a показывал десятки CLOSE_WAIT соединений.
Практически все, кто сталкивался с этой проблемой, валят всё на поисковых роботов и предлагают запретить индексацию сайта. Тем не менее, есть ещё один вариант решенения проблемы - прибивать процессы апача, которые хотят слишком многого. Здесь можно возразить, что в поле такие трюки лучше не делать. Тем не менее, есть ситуации когда подобный подход вполне работоспособен.
Нижележащий код крайне не рекомендуется к использованию, если только не знаете, что делаете.
#!/bin/bash arr=$( ps h -eo pid,pcpu,comm k -pcpu| head -n 10) IFS=$'\n' for x in $arr; do x="${x#"${x%%[![:space:]]*}"}" x="${x%"${x##*[![:space:]]}"}" pid=${x%% *} proc=${x##* } cpu=${x% *} cpu=${cpu#* } cpu=${cpu/\.*} if [ $proc == "apache2" -a $cpu -gt 5 ]; then echo $pid kill -9 $pid fi done
Скрипт смотрит на самые прожорливые процессы и прибивает их. Ограничение на 5% загрузку процессора связано с тем, что top и ps выдают разные значения и при 200% нагрузки в top, ps может показывать только 5-7%.
Пусть вам такое никогда не понадобится
В процессе разработки иногда приходится писать эмуляторы партнёрских систем, если доступа к ним нет. Сейчас мне пришлось работать над эмулятором, который должен был предоставлять API вида http://emulator/connectionPoint. Первой мыслью было использовать для этой цели фичу MultiViews, но выбор оказался неверен.
Запрос
GET /connectionPoint HTTP/1.1 Host: emulator User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; ru-RU) AppleWebKit/533.19.4 (KHTML, like Gecko) Version/5.0.3 Safari/533.19.4 Accept-Encoding: gzip, deflate Accept: text/event-stream Accept-Language: ru-RU Cache-Control: max-age=0 Pragma: no-cache Connection: keep-alive
Ошибка соединения, «Options +MultiViews»
HTTP/1.1 406 Not Acceptable Server: Apache Alternates: {"connectionPoint.php" 1 {type application/x-httpd-php} {length 152}} Vary: negotiate,Accept-Encoding TCN: list Content-Encoding: gzip Content-Length: 274 Content-Type: text/html; charset=iso-8859-1 Connection: close
Верный ответ, «Options -MultiViews»
HTTP/1.1 200 OK Content-Type: text/event-stream Connection: close
К сожалению, MultiViews имеет более высокий приоритет, нежели ModRewrite, что делает невозможным исправление ситуации без его отключения.
Итак, рецепт правильных редиректов для EventSource - создание корректного .htaccess
Options -MultiViews RewriteEngine on RewriteBase / RewriteRule ^([^.]*)$ /$1.php [L]
На странице описывается, как можно ТОЛЬКО средствами командного интерпретатора включить в имя файла текущие дату или время. На примере создания jar-файла было показано как можно это выполнить. Были подробно рассмотрены все шаги. В свете текущей заметки прежнее решение можно считать длинным и громоздким:
@echo off rem Skip incorrectness in time earlier than 10:00 - replace of leading whitespaces with '0' set now=%DATE: =0% %TIME: =0% rem Disassemble date and time on parts for /f "tokens=1-7 delims=/-:., " %%a in ( "%now%" ) do ( rem Define your owned delimiters and order of tokens set now=%%a%%b%%c_%%d%%e ) rem Create the point patch for all files within the current directory jar -cf patch_%now%.jar *
Следует заметить, что скрипт системно-зависимый: порядок отдельных частей даты и времени зависит от текущих установок на компьютере (национальные, пользовательские настройки). В данном примере порядок отдельных частей времени следующий (в предположении, что дата и время соответствуют форматамYYYY/MM/DD и hh:mm:ss,ms, где ms - сотые доли секунды):
%%a - год%%b - месяц%%c - день%%d - часы%%e - минуты%%f - секунды%%g - сотые
Таким образом, строка в цикле формирует переменную %now% в формате YYYYMMDD_hhmm. То есть, в результате выполнения данного примера (на момент написания 20 января 2009 года 20:53) был бы создан файл patch_20090120_2053.jar.
Процесс достаточно простой, для начала нужно добавить модули апача mod_dav и mod_dav_svn (установку которых оставим за рамками этой заметки). Настроить их загрузку при запуске Апача, примерно так:
APACHE2_OPTS="-D DEFAULT_VHOST -D INFO -D LANGUAGE -D SVN -D SVN_AUTHZ -D DAV -D DAV_FS"
.
Прошлая неделя стала «юбилейной» в истории Виртуальной Клавиатуры - преодолён рубеж в 100 языков (сейчас порядка 125) и 200 раскладок.
УРА!
Грамотный код — залог успеха. Этому принципу следуют разработчики большой американской компании. Встречайте:
if (tc.isSortedCell()) attr += " class=sortedCell"; else if (tc.isSortedCellLeft()) attr += " class=sortedCell"; else if (tc.isSortedCellRight()) attr += " class=sortedCell";
Иногда требуется повесить действие в документе не на кнопку, а на ввод последовательности символов. Эта задача решается достаточно просто:
В продукте одной широко известной в узких кругах компании я нарыл сей шедевр… По-моему - гениально. Орфография и стиль сохранены.
function onLoad() { var strUrl = new Object; var strUrlString = 'target_url'; strUrl.src = strUrlString; var targetWindow = null; if (g_clientInfo.isBrowser(ClientInfo.MOZILLA)) { var depth = 1; if (depth>3) { targetWindow=window; } else { targetWindow=window.parent; } } else { targetWindow=window.parent; } navigateToURL(strUrl.src, "returnForm", targetWindow); }
Дошли руки разобраться с Google Gadget API, нарисовать клавиатуру уменьшенного размера и собрать гаджет. Работает на персональной странице гугля, в Google Syndication.
Выглядит он так:
Приветствуются отзывы, пожелания и предложения по улучшению как самого гаджета, как и виртуальной клавиатуры.
PS: добавил его в каталог GoogleModules, проголосуйте, пожалуйста.
Как оказалось, явная вставка скрипта в HTML может понадобиться и в жизни. Хотя я и предпочитаю eval… Данное решение не претендует на полноту и правильность, поскольку ни один использованный дебаггер не увидел команду debugger в скрипте и не позволил поставить там точку останова.
/** * Функция вставляет произвольный скрипт в HTML * * @param {String} script код скрипта * @author Ilya Lebedev */ function insertScript(script){ var targetNode = document.createElement('div'); document.body.appendChild(targetNode); try { var el = document.createElement('script'); el.type="text/javascript"; el.innerHTML = script; targetNode.appendChild(el); } catch (e) { var el = document.createElement('span'); targetNode.appendChild(el); el.innerHTML = "<br /><scr"+"ipt type='text/javascript' defer='defer'>"+script+"</script" + ">"; } }
Дискуссия