Как динамически назначить определенного клиента (браузера) одному из множества серверов? - PullRequest
4 голосов
/ 08 февраля 2012

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

Под присваиванием я подразумеваю, что, например, клиент выполняет ajax-вызов example.com/getData, он должен идти напрямую к одному конкретному серверу, который был назначен. Разные серверы будут выполнять разные вычисления, поэтому недостаточно иметь какое-то общее распределение нагрузки.

Какие общие механизмы / технологии позволили бы мне: 1) Оценить задержку между конкретным клиентом и любым сервером, находящимся под моим контролем? 2) Назначить конкретного клиента конкретному серверу? Например, я не могу использовать только IP-адреса, поскольку в JavaScript есть ограничения на основе доменных имен.

Спасибо

1 Ответ

2 голосов
/ 13 февраля 2012

Примечание: у меня недостаточно репутации, чтобы связать все технологии в ответе, поэтому иногда вы видите ссылки, скопированные в виде простого текста.

1) Назначить пользователей на локальный сервер с минимальной задержкой не всегда возможно.

Иногда географически ближайший к пользователю сервер неожиданно оказывается сервером с наибольшей задержкой.

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

Так что лучший способ достичь этого - использовать anycast

Все основные поставщики CDN реализуют этот метод. Некоторые используют anycast по протоколу TCP, что не рекомендуется, а другие по протоколу anycast. Это открытая дискуссия.

В любом случае, для реализации anycast необходимо иметь возможность взаимодействовать с маршрутизаторами ISP, и обычно это невозможно. Кроме того, есть хорошие и плохие сверстники. Наконец, все это требует глубоких знаний о протоколах маршрутизации и стеке TCP / IP.

Быстрое и грязное решение может заключаться в использовании BIND с патчем GEO-IP. Таким образом, вы можете определить конкретные ответы DNS-запросов для каждой страны. Я имею в виду, что, например, если у вас есть сервер в Великобритании и один в США, вы можете настроить BIND так, чтобы он реагировал на пользователей, приезжающих из Европы, чтобы попасть на сервер в Великобритании, и пользователей, приезжающих из США, на сервер в США.

2) Чтобы назначить конкретного клиента определенному серверу, вы можете использовать методику, описанную мной в пункте 1, или вы можете использовать прокси и липкие сеансы. HA-Proxy - хороший продукт для достижения этой цели. (URL: xy.1wt.eu)

3) если вы используете точку 1, у вас не будет проблем с междоменными вызовами ajax. На самом деле это совершенно прозрачно для клиента. Например, для того же домена example.com пользователь из США разрешит его в 1.1.1.1, а пользователь из Германии разрешит example.com в 2.2.2.2 (ip-адреса являются поддельными и используются только в качестве примера).

Кроме того, решением для выполнения междоменного вызова ajax является JSON-P, у которого есть некоторые недостатки, такие как отсутствие поддержки POST.

На вашем месте я бы использовал BIND и GEO-IP, потому что это решило бы все три проблемы за один раз. (часть для задержки, потому что не всегда верно, что географически самый близкий сервер - тот с самой низкой задержкой.)

...