Определить ближайшее зеркало PHP - PullRequest
8 голосов
/ 29 января 2012

Я поддерживаю сайт с кучей загружаемых файлов.В настоящее время он находится на сервере в США, но недавно я приобрел новый сервер в Германии.Я хотел бы отразить загрузку на сервер в Германии и иметь скрипт PHP на первом сервере (на котором размещается веб-сайт), чтобы определить, какое файловое зеркало использовать в зависимости от местоположения пользователя.Например, если пользователь находится в Канаде, он должен загрузить файл с моего текущего сервера в США. Если он находится во Франции, он должен получить файл из Германии, а не через Атлантику.Как же тогда я могу определить, к какой стране они ближе?

Я знаю о MaxMind GeoIP и установил ли он, но это просто дает мне страну, и AFAIK, нет способа автоматически определить, какаяиз двух моих зеркальных стран данная страна ближе всего.Я полагаю, что я мог бы сделать это по континентам: пусть пользователи в Азии, Европе, Африке и Австралии получают контент из Германии, а посетители из Северной и Южной Америки - из США. Если кто-то может придумать лучшее решениеЯ открыт для предложений.


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

Ответы [ 5 ]

2 голосов
/ 03 мая 2012

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

Определениеближайшее зеркало (с использованием почтовых индексов)

  1. Ведение списка почтовых индексов в массиве для этих доступных зеркальных серверов.
  2. Определение почтового кода агента пользователя (например, пользовательский ввод или библиотека PHP)
  3. Рассчитать расстояние между двумя почтовыми кодами (например, библиотека PHP)
  4. Продолжить выбор зеркала на основе полученного расстояния

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

Ресурсы и ссылки

Подход "Maverick"

На мой взгляд, Mavericks также известны как новаторы, решатели проблем и изобретатели этих замечательных библиотек и сред, которые мы все используем сегодня.Иногда ошибочно ассоциируется с «хакерскими» идеями, но мы принимаем дополнение:)

  1. Создайте свою собственную службу API на любом из ваших зеркальных серверов, которая будет принимать либо $ _GET, либо $ _POSTrequest.

  2. Эта служба API возьмет IP-адрес, который ей дан, и отправит ping (), вычисляя время отклика, а затем получая среднее значение, возвращая его запрашивающему интерфейсу (например, вашемупортал внешнего интерфейса, через который подключаются клиенты и / или сервер, пытающийся определить ближайшее зеркало).Сервер, который отвечает с самым низким средним значением, должен быть вашим самым быстрым отвечающим сервером, хотя не обязательно самым близким.Что для вас важнее?См. Ping site и возвращаемый результат в PHP для работающей функции ping (), которая не зависит от локального выполнения команд оболочки (например, не зависит от платформы).

  3. Последний шагПолучите IP-адрес запрашивающего клиента и передайте его службе API, работающей на любом зеркальном сервере в фоновом режиме.И все мы знаем, как получить IP, но не так хорошо, как вы думаете, мы могли бы.Если вы сбалансированы по нагрузке или находитесь за прокси-сервером, вы можете сначала проверить, прошел ли какой-либо из этих заголовков (HTTP_FORWARDED, HTTP_FORWARDED_FOR, HTTP_X_FORWARDED, HTTP_X_FORWARDED_FOR, HTTP_CLIENT_IP).Если это так, то это, вероятно, реальный IP-адрес пользовательского агента.

Именно в этот момент (Шаг 3) вы бы сравнили средние значения времени ответачто каждое зеркало ответило, когда они пошли пинговать пользовательский агент.Затем перейдите к выбору зеркала, с которого должен загружаться пользовательский агент.Затем созданный вами поток службы будет выглядеть примерно так:

  1. Агент пользователя посещает портал
  2. Портал перенаправляет IP-адрес агента пользователя в службу API, работающую отдельно на обоих зеркалах, используя фоновый AJAX./ jQuery запрос (или традиционный POST и перенаправление).
  3. Служба API, работающая на зеркалах, проверяет IP-адрес, который она получает, и возвращает среднее значение общего числа ответов, настроенных для получения.
  4. Портал читает возвращенные средние значения и сравнивает их.

Надеюсь, что это поможет и удачного кодирования!

1 голос
/ 03 мая 2012

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

Затем, как только вы получите «лучшее время», установите файл cookie JS и перенаправьте на нужное зеркало, когда потребуется загрузка. Измерение можно начать со страницы загрузки в фоновом режиме, так что пользователь, вероятно, не заметит задержку (пока он выбирает нужный файл).

Вы можете даже ответить «загрузкой сервера» в каждой операции AJAX и выбрать лучший сервер не только по времени ответа, но и по текущей загрузке. Таким образом, пользователь из Великобритании будет использовать сервер в США, даже если ближайший сервер находится в Германии, если нагрузка на него будет значительно выше, чем на первом.

0 голосов
/ 03 мая 2012

не проще ли использовать какую-нибудь библиотеку, такую ​​как geoip, как вы сказали, и использовать широту и долготу, чтобы сравнить расстояние между зеркалами и пользователем?

Я думаю, что он менее сложен и его очень легко реализовать, он работает для N зеркал, и вам не нужно запрашивать Zip или другой тип данных для ссылок

0 голосов
/ 03 мая 2012

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

В зависимости от количества прыжков и расположения клиента traceroute (я полагаю, он такой же, как сценарий PHP), выберите между США и Германией.

Географическое расстояние не имеет ничего общего с расстоянием в сети и скоростью сети или расходами на пропускную способность.

В качестве альтернативы traceroute (поскольку это хакерское решение с небольшим кодом), Я рекомендую вам использовать $ _SERVER ["REMOTE_ADDR"] и искать его в базе гео ip , чтобы получить код страны. Если код страны не входит в число стран на американских континентах, чтобы избежать пересечения перегруженной магистрали Интернета, используйте запасной вариант в Германию (дополнительно вы можете указать код страны для Европы).

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

Исходя из моего опыта работы с вышеуказанной базой геоданных, она так редко пропускает, что не имеет значения.

0 голосов
/ 01 мая 2012

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

Рассчитайте расстояние между двумя IP-адресами с помощью этого калькулятора расстояний .Или узнайте широту и долготу двух IP-адресов (один сервер) и (один гость) и рассчитайте расстояние.Вот псевдокод для этого

distance = ( 3956 *2 * ASIN( SQRT( POWER( SIN( ( 34.1012181 - ABS( latitude ) ) * PI( ) /180 /2 ) , 2 ) + COS( 34.1012181 * PI( ) /180 ) * COS( ABS( latitude ) * PI( ) /180 ) * POWER( SIN( ( ABS( - 118.325739 ) - ABS( longitude ) ) * PI( ) /180 /2 ) , 2 ) ) ))
...