Всё самое модное

    Начитавшись в интернете про новые, простые, быстрые и масштабируемые технологии, захотелось их всех попробовать. Вдруг они окажутся лучше уже привычной мне связки postgresql + django + json-rpc.

    Идея проекта


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


    Осторожно! В статье много субъективных оценок, основанных на личном опыте!

    Реализация





    Архитектуру пришлось намеренно усложнить, иначе всё интересное не получилось бы попробовать. Плюс операция получения данных пользователя по vk api довольно таки долгая, и идея распаралелить её не такая уж и плохая. Для этого понадобится MQ, выбор пал на RabbitMQ. Вы, возможно, скажете AMQP «отстой», ØMQ «наше всё», но с zeromq я уже наработался, и он в данном контексте мне не интересен.
    RabbitMQ использовался через pika. Для инициализации и отправки/получения сообщений потребовалось минимум кода, его можно посмотреть в в «воркере» и его тестках. После написания появилось небольшое сравнение с уже используемыми ZerocIce и ØMQ для удовлетворения данной или похожей задачи:
    RabbitMQ ØMQ ZerocIce
    Плюсы небольшое количество кода;
    простота работы;
    скорость;
    пересылка нативных объектов;
    не требует своего демона;
    возможность работы с удалённым функциями и объектами;
    отсутствие как такового сокета;
    сигналы/слоты;
    Минусы требуется запуск демона; требуется написание роутера;
    много кода;
    требуется написания slice;
    требуется запуск демона(icebox);
    сложность;

    И так получилось, что для текущей задачи RabbitMQ и ØMQ подходят одинаково хорошо, а ZerocIce тут как пушкой по воробьям.

    Теперь полученные и обработанные данные надо где-то хранить. Сейчас модно nosql, поэтому была выбрана mongodb. Для данной задачи никакой разницы относительно postgresql с orm нет, всё шустрое и удобное.

    Пришла очередь web сервера. Сейчас пошла мода на асинхронность и push от сервера на клиент, поэтому был выбран tornado и tornadio2, тем более про него на хабре недавно писали. Тут сразу вылезла проблема, из tornadio2 не получилось достать куки. Поэтому пришлось городить костыль из отправки id с «секретом» от клиента через socketio, что немного усложнило реализацию. После всего этого получилось небольшое сравнение с django + json-rpc:
    tornado + tornadio2 django + json-rpc
    Плюсы push с сервера;
    легковесность;
    скорость;
    простота;
    стандартизированный протокол;
    Минусы сложность;
    «кривая» работа с куками;
    монструозность;
    периодические запросы для симуляции push'а;

    Тут всё неоднозначно, но из-за push вариант с tornado всё-таки лучше.

    Для клиентской части ничего особого придумать не получилось, поэтому использовались просто coffee script, haml и sass, что помогло сэкономить много строчек кода.

    Деплой


    Долго не думая, я решил разворачивать всё на сервере через nginx используя стандартную схему:



    Но ни тут то было. Оказалось, что nginx не поддерживает web сокеты и было 3 варианта решения проблемы:
    1. Ставить нестабильный nginx.
      Для ubuntu есть ppa, из него я и поставил, но отвалилась http авторизация, решить проблему не получилось. А так как на сервере лежит ещё и mercurial репозиторий с такой авторизацией, вариант быстро отпал.
    2. Собирать nginx с tcp proxy.
      Найдя простую инструкцию, всё получилось собрать. Все старые проекты запустились. Но тут или я где-то ошибся, или что, но сделать нормальную работу websocket'ов не получилось. Вариант отпадает.
    3. Использовать HAProxy.
      Тут получается схема с оверхедом, которую проще показать картинкой:



      С ней всё запустилось и заработало хорошо.

    Итог


    Это, конечно, всё круто, удобно и быстро, но есть ещё много косяков. Основной косяк с деплоем, но конечное решение получается не таким уж плохим.

    github с кодом.
    В запущенном виде.
    Ads
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More

    Comments 33

      0
      Идея норм, реализация не очень.
        0
        Тут просто технологии пощупаны, цели сделать круто не было)
          +3
          Имхо, раз уж взялся не делай «бесполезных вещей». :)

          Видимо у всех болит бошка, минусуют всё и всех…
            +2
            Будет пользоваться хоть минимальной популярность. — буду улучшать)
              +10
              Я вообще на хабре недавно. И у меня за эти 2 месяца сложилось впечатление, что 80% пользователей хабра — злые тролли. Да и вообще народ у нас я Вам скажу — все за спинами любят подо… ать друг на друга. Ужас какой-то. Пишешь статью, стараешься — пару плюсов всего, а как написал «Друпал стремный )» так сразу минус 10 на тебе, получай. И всем пофигу что человека в минус загнали и все, больше человек этот ничего сюда не напишет. Хоть мог бы что-то полезное написать. У меня лично всякое желание отпало. И так у нас во всем. Жаль наш народ — бедный он, не столько материально, сколько морально
                0
                Это только впечатление, у меня о хабре складывается мнение уже много лет, потому что читаю статьи и комментарии не злых троллей, а очень образованных, организованных, усидчивых и терпеливых кои качества смею желать… Роли не должно играть 80% тролли или нет, тролли только те, чей материал вы читаете… Минусы получают те — кто реально заслуживает… Не то что бы это контролируемый процесс — стадный эффект везде есть… Так что не обобщайте до такой критической массы как 80%…
          +7
          «Я надену все лучшее сразу».
            +3
            Как же резво минусуют :) Хабр дорвался
              0
              Уже кто-то добавление пользователя в скрипт догадался засунуть.
                0
                Ага, а кто-то индексы забыл добавить)
                +1
                Обновите Торнадо, у вас на текущей версии Chrome не работают WebSockets
                  0
                  Используется 2.1.1, последняя.
                    +1
                    Придется обновить до мастера в github. Протокол вебсокетов все еще в разработке, и с релизом Chrome 16 появилась поддержка нового стандарта, что, в свою очередь, сломало вебсокеты в Торнадо.

                    Вот тикет в тракере Торнадо: github.com/facebook/tornado/issues/385

                    Это, к слову, тоже говорит о плюсах/минусах описанных технологий. Я обеими руками за вебсокеты и тому подобное, но да, плясать с ними приходится постоянно :)
                    0
                    А, всё, поставил версию из git'а — заработало.
                    0
                    habrahabr.ru/blogs/python/134822/ — рекомендуют альтернативу Socket.IO

                    А по поводу схемы деплоя — почему «голый» Tornado не хотите выставить? Зачем его за всякими HAProxy/Nginx убирать?
                      0
                      SockJs не видел, надо будет посмотерть.

                      На 80 порту висит не только этот проект.
                        +1
                        насчет 80 порта не совсем понял… Раздавайте HTTP с 80-го через Nginx а WebSockets/Socket.IO с другого порта.
                          0
                          Об этом варианте я как-то не подумал)
                            0
                            плохой вариант. технически — можно, практически — нет: злобные админы на конторах какбэ намекают, что среднестатистическому офисному планктону можно делать только 80 и 443. Так что про «другой порт» на реальном приложении — забудьте.
                      –2
                      Желаю встречать новый год до конца выходных и отдохнуть от компьютера. )
                        0
                        А что с куками в торнадио2 было не так? Там ведь они передаются в on_open, вместе с query string.
                          0
                          Передавалась пустота, возможно торнадо старый был, но вроде есть похожая бага в трекере.
                            0
                            Аналогичная проблема, пусто в куках, временно просто передаю sessionid в качестве аргумента подключения + при использование флешевой прослойки отпадает морока с куками.
                            0
                            Делаю очень похожую штуку, но без архитектурных изысков. Работает бодрее.
                              0
                              Без изысков такое за день можно сделать и не интересно)
                                0
                                1000 строк за день — это лихо! А чтобы без ошибок так и вообще шикарно просто.
                                  0
                                  Вы что-то перемудрили)
                                  На джанге вышло бы меньше, таки рор хуже?)
                                    0
                                    Таки функционала больше. И таки даже не рор это.
                                      0
                                      Ага, больше, но весь очень простой и под каждую функцию можно найти уже созданный апп.
                              0
                              Подскажите идею — как в случае с json-rpc лучше делать авторизацию клиентов?
                                0
                                Если используется django-json-rpc, то там достаточно в любой метод требующий авторизации передать username и password.
                                  0
                                  Подскажите пожалуйста js библиотеку или jQuery-плагин для json-rpc на стороне браузера.
                                  Спасибо.

                            Only users with full accounts can post comments. Log in, please.