| Как это было* | |
| Когда-то давным давно заказчик купил у третьей стороны один проект. Этим проектом было приложение, предназначенное для удаленного администрирования компьютера, на котором оно было установлено. Приложение позволяло администрировать компьютер через веб-интерфейс всякому, кто придет к нему с помощью броузера и удачно залогинится локальным или доменным пользователем. Назовем это приложение «Клиент», а компьютер, предназначенный для того, чтобы на него установили Клиент — «Хост». | |
| Через некоторое время заказчик купил и доработал напильником другое, большое enterprise веб-приложение. Задача этого приложения состояла в администрировании множества компьютеров. Администратор логинился в приложение, выбирал домен, выбирал компьютер в домене, устанавливал Клиент на выбранный компьютер, и администрировал его. Это в двух словах. В деталях же приложение имело навороченную функциональность по разграничению прав доступа, установке Клиентов, поиску и управлению компьютерами, и прочую модную лабуду, идущую в ногу со временем. Назовем это приложение «Веб-Приложение». | |
| Веб-Приложение предполагало, что Хосты либо не имели выхода в Интернет, либо не могли напрямую принимать входящие соединения от пользователей Интернета. Если Хост был в домене, то Веб-Приложение требовало, чтобы домен-контроллер мог инициировать соединение на компьютер, на котором развернуто Веб-Приложение. Если же Хост был вне домена, то Веб-Приложение требовало, чтобы он имел выход в Интернет. | |
| Поэтому, для того, чтобы любой пользователь Интернета, открыв броузер и зайдя на сайт, на котором развернуто Веб-Приложение, мог администрировать любой из компьютеров, о котором знало Веб-Приложение, требовалось дополнительное звено. Этим дополнительным звеном был маршрутизатор запросов, входивший в приложение еще тогда, когда заказчик купил его у третьей стороны. | |
| Пользователь Интернета с помощью броузера отправлял запрос Веб-Приложению, первый маршрутизатор перенаправлял запрос с Веб-Приложения на домен-контроллер, второй маршрутизатор отправлял запрос с домен-контроллера на Клиент, получал ответ на запрос, и по обратной цепочке доставлял этот ответ броузеру пользователя. Если же Хост не было доменным, а просто имел выход в Интернет (без возможности принимать входящие соединения), то система доставки работала несколько иначе: маршрутизатор, установленный вместе с Веб-Приложением, формировал очередь запросов, отправленных от пользователя Интернета к Хосту; маршрутизатор, установленный на Хосте, периодически «ходил» на Веб-Приложение чтобы узнать, нет ли в очереди адресованных ему запросов. Если такие запросы были, то они доставлялись Клиенту, а ответы, полученные от Клиента по обратной цепочке уходили на броузер пользователя. | |
| Таким образом, любой пользователь Интернета, имеющий логин и пароль, мог прозрачно администрировать любой Хост о котором знало Веб-Приложение, как будто этот Хост был доступен пользователю напрямую через HTTP-протокол. | |
| * В целях конспирации хронология событий предыстории проектов незначительно изменена | |
| | |
| Веб-Приложение развивалось и у заказчика появлялись все новые и новые пожелания относительно его возможностей. И в один прекрасный день стало ясно (по крайней мере мне :-), что маршрутизатор невозможно адаптировать под новые условия. Точнее, сделать это будет дороже, чем переписать его заново, поскольку реализация существующего маршрутизатора с точки зрения качества кода была запредельным… Кхм… Ну как это обычно бывает :-) | |
| Поэтому было принято решение переписать маршрутизатор запросов, чем я, собственно, и занялся. | |
| | |
| Задача | |
| Переписать маршрутизатор запросов. | |
| | |
| Как это стало | |
| В результате переписывания «с нуля», маршрутизатор запросов получил следующие технические и архитектурные преимущества. | |
| Новый маршрутизатор работал по keep-alive соединению, в то время как старый на каждый запрос инициировал отдельное соединение и закрывал его после получения ответа. Keep-alive режим позволил значительно увеличить производительность процесса администрирования Хостов через Веб-Приложение. Кроме того, в силу архитектурных ограничений, на старом маршрутизаторе не работало администрирование доменного Хоста, если его фаервол не пускал входящие соединения. Эта проблема была также решена за счет keep-alive соединений, инициируемых в одностороннем порядке от Хоста к Веб-Приложению. | |
| Старый маршрутизатор был заточен сугубо под HTTP протокол. Новый же имел низкоуровневый бинарный протокол, что позволяло маршрутизировать любой трафик. В дальнейшем на этом принципе была реализована прозрачная маршрутизация LDAP-запросов. | |
| На старой архитектуре можно было выстраивать довольно ограниченную структуру маршрутизации. Новая архитектура позволяла выстраивать маршрутизаторы в любую древовидную структуру, любой глубины вложенности. | |
| Новая архитектура позволяла без особых усилий организовать динамическую балансировку нагрузки на дерево маршрутизации на основе собранных статистических данных. | |