пятница, 25 февраля 2011 г.

Creatio ex Nihilo. Архитектура сложного веб-проекта. Введение

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

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

Архитектуры можно разделить на распределенную и монолитную. А внутреняя структура имеет определенную степень связанности - сильную или слабую. Собственно архитектура влияет на структуру кода и проекта в целом, а структура влияет на методику разработки и способы развития проекта.

Перед разговором о собственно архитектуре нужно понимать масштабы задач которые ставятся при ее реализации. Есть веб-ресурсы с огромной упорядоченной инфраструктурой - например Гугл или Яндекс. Есть веб-ресурсы с небольшой инфраструктурой, но большим числом сервисом - фейсбук. Есть небольшие сайты - веб-ресурсы компаний, банков, контентные. Архитектура, структура и реализация у них различна. И различна в первую очередь из-за различия амбиций и способностей созидающих их людей.

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

1. Python/Django - язык программирования и фреймворк посредством которых программист может описать доступ к базе данных, миддлвейры, обработчики контекста и программировать внутреннюю структуру т.н. бекенда;
2. Django-templates/HTML/CSS - система шаблонизации и разметка отображений. То что описывает задачу фронтенда, и позволяет создавать непосредственно внешний вид веб-ресурса;
3. JavaScript/jQuery/AJAX/JSON - язык программирования, фреймворк для создания всего и вся, технология передачи данных и средство сериализации. Все это в сумме позволяет создать динамические, легкие и удобные интерфейсы для пользователя.
4. SQL/JOIN/RELAITIONS/MySQL/Postgresql - средство для хранения данных превращенное временем в кумира и идола для миллионов веб-разработчиков. Благодаря консистентности, строгости в языке запросов и сложности во внутреннем устройстве создает этакую магическую простоту в разработке и шаманскую сложность в обслуживании. Позволяя полным профанам от программирования иметь хранилище с данными, которое очень трудно разрушить. Посредством чего решается множество проблем.

Заменить участки можно чем угодно. Но модель MVC/MVT нынче является архитектурой которой поклоняются мирриады бездушных тварей миллионы веб-разработчиков.

Сколько не грызите ногти, конфетами они не станут.
Идея заложенная в паттерне проектирования MVC - весьма прозрачна. Мы создаем код, который умеет работать с данными (Models/Controllers), мы создаем код который умеет управлять контекстом исполнения (Controller), и пишем код который ответственен за отображение данных (Views/Templates).

При этом мы стремимся к отделению мух от котлет. Работа с данными у нас в одном месте, их обработка в другом. Что и в какой-последовательности в третьем, а создание ненавистных виджетов или генерация HTML в четвертом.

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

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

Da Red Goez Fasta!
Космические Орки знают в то, что красная машина едет быстрее. Основываясь на этом знании, они покрасили гретчинов в красный цвет, думая, что таким образом увеличат их производительность и эффективность. Реальность их удурчала.

В нашем случае веб-программисты постепенно объеденили в себе множество профессий: верстальщиков, JS-программистов и флеш-аниматоров, программистов бизнес-логики, DB-администраторов, системных администраторов и местами даже проектировщиков-архитекторов и менеджеров.

Это все в целом позволяет компаниям минимизировать затраты на штат сотрудников, позволяет более эффективно создавать новые продукты или ресурсы. Увеличить прибыль и получать качественные цельные разработки.


И чтец и жнец и на дуде игрец!
Реальность часто отличается от бизнес-планов. По факту большинство веб-программистов импотенты в аспекте DBA, SQL, администрирования, проектирования архитектуры, менеджемента и нередко даже программирования. Один человек может получить экспертизу во всем вышеперечисленным. Но внезапно он захочет занимать иную должность, например технического директора, а не обычного разработчика. А это явно не совпадает с планами работодателя.

Чтобы убить вампира, вам нужна серебрянная пуля
Дабы упростить задачи веб-девелоперов решения вроде Django предлагают множество допущений - отказ от использования и знания SQL - Django-ORM. Отказ от непосредственной реализации многих сервисных вещей - кеширования, аутенфикаци, валидации форм etc.

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


Серебрянной пули- не существует
Рано или поздно это случиться. Когда удобный мир созданный годами развалиться перед новой задачей. В конечном итоге программист это не человек прочитавший и понявший Дональда Кнута (это скорее всего математик), это не человек который создал множество различных снаружи проектов, но уныло одинаковых внутри - на готовых решениях.

Перечисленное выше решение - это не распределенные вебресурсы с высокой степенью связанности. Если перейти на язык компилируемых языков - все элементы программы собраны в один бинарный файл. Все службы, куски, детали. Это один проект. Попытка сделать что-то вне него - равносильна созданию всего комплекса с начала.


Распределенная архитектура - делает в целом тоже самое, что написание программы разделенное на функции. Мы выделяем определенную задачу и решаем ее необходимым способом.

Слабая связанность - достигается должной степенью абстракций. Отказом от конкретных способов реализации. Т.е. новостную ленту мы можем сделать на Django+MySQL. А вот счетчик посещений реализуем комплексом из C+libevent+NoSQL DB+python+Postgresql.

Нет ничего более упорядоченного, чем политика дворов Хаоса
Чем больше технологий, тем больше хаоса. Но в действительности это зависит от спецификации. В нашей архитектуре каждая задача решается верными способами и в рамках общей идеи.

Collector & Templates
Наиважнейшей частью веб-проекта является его внешний вид. Если у вас порядка 10 источников с данными, и количество их будет лишь расти с геометрической прогрессией, то вам нужен общий центр синхронизации.

В нашем случае это приложение прототипированое посредством python+twisted+lxml(libxml2). Оно занимается следуюшими вешами:

1. URL Dispatching - анализируем URL и определяем к каким источникам данных нам нужно обратиться. Для упрощения реализации, обращаемся к источником только через протокол HTTP, хотя в целом ничего не мешает использовать и другие средства.
2. Authentication - частично выполняет проверку аутенфикации. Для уменьшения числа запросов к бекендам (источникам данных) которые требуются только для определенных ситуации на данном рынке :)
3. Context Processing - для каждого контекста нужен свой общий набор запросов к данным. Группируя их мы формируем общий контекст для вывода;
4. Data Transformation - в общем и целом мы генерируем на выход HTML. Впрочем нам ничего не мешает генерировать CSS/JS/JSON/AMF или что-то еще. Для текстовой информации мы используем XSLT. Это формирует и требования к ответу бекендов - XML. Причина использования XSLT будет обоснована позднее. Пока коротко о XML. XML не оптимален как транспортный протокол, в случае если он станет узким местом, мы всегда сможем сделать JSON способ сериализации, или вообще использовать бинарные протоколы. Коллектору останется лишь привести их к XML.

Backend Developing
Источник данных может быть любым. В простейшем случае это pylons/pyramid сервис который обращается к хранилищу и препарирует данные для сериализации. Главное это специфицировать метод обращения к бекенду.

В сложном случае им может быть и сложное асинхронное приложение (или даже комплекс) которые выполняют множество задач.

Например мы хотим знать кто из друзей пользователя онлайн. У пользователя 100 тысяч друзей. Вычисление постраничного вывода на лету, для пары тысяч таких ребя, может стать травматичным и опасным мероприятием. Поэтому у нас есть некий сервис который активируется при авторизации пользователя и запускает процесс кеширования данных. Они вынимаются из базы и складываются например в Redis. Дальше когда кто-то переходит в состояние оффлайн, мы его удаляем из писка онлайн у его друзей (точно так-же в бекграунде). Снижая таким образом накладные расходы на множество вычислений и перекладывая их с одного средства (СУБД) - на другое (Redis).

Т.к. нам в данном случае результат работы не важен, наш бекенд ответит коротким респонсом и передаст дальше задачу либо своим внутренним ресурсам, либо вообще через MQ стороннему приложению.

Хранилища
Основное хранилище данных у нас MongoDB. Однако помимо оного используется так же MySQL и Postgresql. А в ближайщем будущем добавиться еще и Cassandra и парочка прочих веселых вещей.

Частично это получилось исторически. И оказалось достаточно удачным для создания в целом гибкой инфраструктуры.

Что мы получаем?
Благодаря разделению задач на каждом пласте комплекса программ и средств мы получаем распределение обязанностей между людьми. Тот кому нравится работать с веб-интерфейсом - трудится с коллектором и XSLT. Используя свои знания и способности в области HTML/CSS/JS/jQuery.

Тот кому нравится писать бизнеслогику работает с бекендами. Программисты интересующиеся сетевым стеком и интеграционными задачами пишут программы вроде коллектора или сервера приложений работающие с данными поступающими из MQ.

Каждая программа и каждый программист таким образом живет независимо от других. И в то же время является частью общего целого. Общая интеграция становится весьма простой задачей. Добавлением пары строчек в конфигурационный файл коллектора и на данном конкретном сайте появится новый виджет.

В продолжении

В продолжении рассмотрим каждую деталь механизма подробнее. А вдруг я ошибаюсь. Лишь графоманство и размышления позволяет понять не допущены ли ошибки в спецификации :)

1 комментарий: