1. Лучики

    В последнее время мой провайдер интернетов как-то плохеть стал, что ли.

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

    И ведь даже в новостях на сайте об этом не написали. Некрасиво! Плохо, черт подери. Особенно при том, что я уже больше года тонко намекаю сотрудникам компании о том, что экспорт новостей в RSS — удобно до черта.

    Зато цены уже больше года не снижать — это запросто. Мегабитный канал стоит 1100 рублей.

    А название провайдера не скажу, а то один из их сотрудников читает мой твиттер (а может и бложек), и когда я говорю плохо о его компании, он очень обижается :)

    Ну а так они хорошие, да. Привет, Серега.

    Уф.

    2 weeks ago  /  0 notes  / 

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

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

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

    А ты дома. Асфальт мокрый вокруг, ветер в лицо дует, а ты у окна торчишь. И хочешь туда. Потому что вроде тебе и тут-сейчас хорошо, а там, в другой возможности — прямо сейчас гораздо интереснее. Заветной двери в «лето» под рукой вот только все равно нет, только балконная дверь за спиной.

    Стоишь, давишь эту грустную мысль о том, что хорошо не там, где ты, и дышишь воздухом. Набираешься свежего кислорода… и уходишь домой.

    Может быть когда-нибудь потом. Верно ведь?

    1 month ago  /  0 notes  / 

  3. Long live rock’n’roll

    Разбавлю-ка я это унылое технарское говно лирическим лытдыбром.

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

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

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

    Здесь должна быть мораль, но я с трудом ее могу написать буковками, поэтому проще плюнуть на это дело, сказать, что жизнь-то, черт ее подери, проходит, и нечего почем зря торчать сиднем на одном месте.

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

    1 month ago  /  0 notes  / 

  4. Monitоринг системных процессов

    Monit — легковесное средство для мониторинга работы системных процессов. Умеет смотреть на состояние процессов и файлов и при достижении определенных условий паниковать.

    Во время вчерашнего инженерного дня поставил именно его в качестве дворника, растаскивающего по квартирам пьяненьких жильцов. В Arch Linux он находится в community репозитории.

    Основные настройки лежат в /etc/monitrc и выглядят примерно так:

    # Проверка состояния раз в две минуты
    set daemon 120
    
    set logfile "/var/log/monit/monit.log"
    
    # Уведомления идут через GMail
    set mailserver smtp.gmail.com port 587
        username "example@example.org" password "password"
        using tlsv1 using hostname "example.org"
    
    # Если не удается отправить уведомления
    # последние их 100 штук хранятся и периодически пытаются отправиться
    set eventqueue basedir /var/local/monit slots 100
    
    # Получатель уведомлений
    set alert admin@example.org
    
    # Простой web-интерфейс для подглядывания состояния сервера
    set httpd port 2831 and
        use example.org
        allow admin:password
    
    # Конфигурационные файлы для демонов лежат отдельно
    include /etc/monit.d/*
    

    Остальные конфигурационные файлы:

    Nginx

    check process nginx with pidfile /var/run/nginx.pid
        group http
        start program = "/etc/rc.d/nginx start"
        stop program = "/etc/rc.d/nginx stop"
    
        if cpu > 60% for 2 cycles then alert
        if cpu > 80% for 5 cycles then restart
        if totalmem > 300.0 MB for 5 cycles then restart
        if children > 250 then restart
        if loadavg(5min) greater than 10 for 8 cycles then restart
    

    PostgreSQL

    check process postgres with pidfile "/var/lib/postgres/data/postmaster.pid"
        group postgres
        start program = "/etc/rc.d/postgresql start"
        stop program = "/etc/rc.d/postgresql stop"
    
        if failed host 127.0.0.1 port 5432 protocol pgsql then restart
        if 5 restarts within 5 cycles then timeout
    

    Memcached

    check process memcached with pidfile "/var/run/memcached.pid"
        start program = "/etc/rc.d/memcached start"
        stop program = "/etc/rc.d/memcached stop"
    
        if failed host 127.0.0.1 port 11211 then restart
    

    sshd

    check process sshd with pidfile "/var/run/sshd.pid"
        start program = "/etc/rc.d/sshd start"
        stop program = "/etc/rc.d/sshd stop"
    
        if failed host 127.0.0.1 port 23 protocol ssh then restart
        if 5 restarts within 5 cycles then timeout
    

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

    В частности, надо будет добавить контроль за django сайтами, которые тоже можно мониторить по pid файлу, создаваемому ими. Поддерживаемая команда exec позволит заново перезапускать инстансы python’а, обслуживающего сайт.

    Теперь, при каждом alert’e будет приходить уведомление такого плана:

    Does not exist Service nginx 
    
    Date:        Sun, 23 May 2010 23:38:34 +0900
    Action:      restart
    Host:        example.org
    Description: process is not running
    

    Остается только поставить сервис мониторинга, который будет следить за monit.

    Официальный сайт Статья на хабрахабре

    2 months ago  /  0 notes  / 

  5. Инженерный день

    Воскресенье, 23 марта. Хроника событий, посвященная техническим работам над сервером Hello ACY.

    Черт меня дернул с утра посмотреть top на сервере. Вверху списка висело процессов 20 python’a, старательно раздающих контент пользователям. Для Hello ACY такое количество инстансов — это чертовски много.

    tail -f access.log мгновенно засыпал экран записями о том, что раз в секунду чей-то RSS клиент забирает нашу ленту. Лента — это около 23 килобайт на запрос, в час - около 80 мегабайт, и так далее.

    Первая часть проблемы была решена банально: кеширование отдаваемых данных. На стороне сервера генерировался результирующий xml файл и складывался в memcached на пять минут.

    from django.core.cache import cache
    from django.http import HttpResponse
    
    from syndication.feeds import ComicsAndBlogFeed
    
    def comics_and_blog(request):
        content = cache.get('helloacy:rss')
        if not content:
            feed = ComicsAndBlogFeed()
            content = feed(request).content
            cache.set('helloacy:rss', content, 300)
    
        return HttpResponse(content, mimetype='application/rss+xml')
    

    nginx получил соответствующее правило, по которому он брал данные напрямую из памяти, не трогая django. Если данные отсутствовали в memcached, запрос направлялся к бэкенду.

    location ~* ^/rss/$ {}
        set $memcached_key "helloacy:rss";
        add_header Content-Type "application/rss+xml; charset=utf-8";
        memcached_pass 127.0.0.1:11211;
        error_page 404 502 504 = @fallback;
    }
    

    Нагрузка на сервер вернулась к прошлым значениям, оставалось только одно: по-прежнему уходил трафик. Проблема разрешилась весьма неожиданно, из access.log был найден IP адрес клиента, и внезапно, по нему найден и сам владелец RSS читалки. Не пользуйтесь, в общем, RSS reader’ом для Miranda IM, он невероятно кривой.

    После этого я наконец-то прибрался на сервере и в конце концов решил перезагрузить VPS.

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

    Я начал нервничать еще больше, потому что сайт хостера тоже перестал открываться. Беглый поиск по твиттеру показал, что у хостера упал один дата-центр в Далласе и еще два из-за этого теперь перегружены. Клиенты хостера уже начали ругаться, а я неудомевая пытался понять, действительно ли я перезагрузил вместе с VPS и весь дата-центр?

    Через двадцать минут хостер сообщил, что у их collocation провайдера лег один из роутеров, и все системы уже работают в обычном режиме.

    После этого я точно решил поставить что-нибудь для мониторинга работы демонов и установил monit. Отличное воскресенье.

    2 months ago  /  0 notes  / 

  6. Hello ACY fail whale

    Сервер Hello ACY сегодня в 5 утра попытался забрать новые твиты, обнаружил, что twitter лежит, запаниковал и умудрился подзавесить сервер баз данных.

    Сервер бд от этого тоже лег, прихватив за собой остальные сайты, лежавшие на этом сервере.

    БЛЕАТЬ!

    2 months ago  /  0 notes  / 

  7. Альбом приятного легкого акустического регги.

    Альбом приятного легкого акустического регги.

    3 months ago  /  0 notes  / 

  8. С первым апреля, истерички, ноющие от 11 пиксельной Lucida Sans.

Довольны теперь?

    С первым апреля, истерички, ноющие от 11 пиксельной Lucida Sans.

    Довольны теперь?

    4 months ago  /  0 notes  / 

  9. Пара mercurial hooks для python-программиста

    Хуки — действия при определенных событиях в репозитории. Это чертовски удобная вещь в системах контроля версий. С их помощью можно делать проверки сохраняемых файлов, запускать unit-тесты для проекта, уведомлять других разработчиков о новых changeset’ах и т.д.

    Ниже я приведу два хука к mercurial, которые немного облегчают жизнь python разработчику.

    Задачи:

    • Не дать сделать commit файлов, содержащих в себе print.
    • После обновления репозитория удалить .pyc и .pyo файлы

    Проверка существования print в тексте.

    Зачем? Например, если запущенному приложению нельзя писать в stdout. К примеру, mod_wsgi для apache запрещает так делать и вызывает IOError.

    Код: http://code.svartalf.info/misc/src/tip/mercurial_hooks.py#cl-12

    Удаление .pyc файлов

    Известно, что интерпретатор python делает byte-compiled версии файлов с расширением .pyc. После переключения в другой branch или получения новых changeset’ов код может по-прежнему читаться из «кешированных» файлов, что конечно не хорошо. Подключаем хук на событие incoming:

    Код: http://code.svartalf.info/misc/src/tip/mercurial_hooks.py#cl-55

    Как теперь подключить эти хуки к репозиторию? Сохраняем их в файл .hg/hooks.py (Или в любое место из PYTHONPATH) и редактируем файл .hg/hgrc

    [hooks]
    precommit = python:.hg/hooks.py:print_check
    incoming = python:.hg/hooks.py:clean_cache
    

    Как видно, автоматизация мелкой рутинной работы при работе с mercurial весьма проста. Нужны еще примеры? Их есть в файле commands.py из исходников самого mercurial.

    4 months ago  /  0 notes  /