Распределение трафика. Объединяем все партнерки.

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

Итак, начнем. Основная идея такова: создадим нечто вроде очереди, замкнутой в кольцо. В очереди каждый узел – это отдельный URL платника. Далее при обращении к скрипту происходит выбор. Я организовал 2 типа выбора из набора платников: равномерный рандом и выбор по очереди в цепочке. Давайте начнем смотреть на код и станет все понятно.

Первое – это класс отдельного узла. Как я говорил узел – это URL платника с определенной служебной информацией.  Рассмотрим:

 

Тут все просто. Создаем узел со свойствами $url,  $is_enable, и т.д. Все они перечислены в коде и даже с комментариями. Скажу отдельно о $is_root. Его я сделал пока исключительно для порядка, как определитель корня, то есть условного начала кольца. Возможно в будущем пригодиться, хотя и сейчас можно использовать его для постановки определенных требований. В остальном же методы класса просты. Это сам конструктор, которые инициализирует наш узел, а далее ряд сеттеров и геттеров для получения и установка служебных значений. Например enable() делает наш адрес активным, а disable() деактивирует его (например платник закрылся).

К настоящему моменту у нас есть узел. Напишем теперь класс кольца.

 

Как видим тут посложнее. Ну в первую очередь тут есть сам массив для хранения узлов кольца $nodes и корневой элемент кольца $root. Далее имеется метод addNode добавления к кольцу узла. Не будем на нем подробно останавливаться, так как по поводу очередей много написано в сети, в частности о добавлении удалении узла и т.д. Скажу только, что первое что мы делаем это проверяем имеется в кольце у нас узлы. Если нет, то добавляем текущий и делаем его root-элементом, а далее выставляем указатели на себя же. А если элементы в кольце уже имеются просто приписываем их в конец и направляем указатели нового узла и бывшего последним. Дальше пара служебных методов по извлечению массива всей очереди и извлечения из массива определенного элемента.

Самый интерес представляют функции getCurrentUrlByRandom и getCurrentUrlByOrder. Они являются составляющими всего алгоритма управления. Первый – будет производить направление на url, а в случае недоступности выберет по равномерному распределению из имеющихся доступных. Второй метод – также произведет направление на url, а в случае недоступности выберет следующий в очереди до тех пор, пока не найдет доступный, если таковой имеется. Я не случайно в обоих случаях сказал просто “направление на url”. Тут можно использовать методы по необходимости. Можно указать определенный элемент для направления и отталкиваться от этого. Но если не указывать параметров при вызове, то началом будет считаться root-элемент и первым мы будет “стучаться” по его url. Так же есть ситуация, когда ни один из url платников не доступен (редкая, конечно, но все же). В таком случае оба метода после определенного количества итераций поиска заканчивают работу, вернув какой-то url-по-умолчанию. Я его пометил в коде, можно заменить на свой.

В целом вышло не так уж и сложно. Давайте взглянем как этим пользоваться на практике.

 

Итак, использование тоже очень важно. Сперва подключили наши классы. Далее завели массив, где перечислили наши url всех наших платников. Это пожалуй единственное место для активного редактирования. Далее создаем экземпляр кольца и начинаем в него писать. Причем очень хитро. Узлы мы создаем налету, проверяя их доступность. Для этого используем cURL. Если мы получаем от данного url заголовок с HTTP_CODE равным либо 200, либо 301, то можно считать, что все с ним в порядке и пометить этот url как доступный (true), иначе он лежит (false).  Таким образом пробегаем по url в цикле и создаем узлы, сразу добавляя в кольцо. Ну а дальше все просто. Пишем header(‘location: ‘.$circle->getCurrentUrlByOrder())или header(‘location: ‘.$circle->getCurrentUrlByRandom()). От этого будет зависеть политика выбора. Кроме того мы могли сделать так:

 

Так бы мы могли получить из запроса $id и попытаться постучаться по конкретному url, а далее уже, отталкиваясь от него искать замену в случае необходимости.

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

На предложения и замечания отвечу в комментариях.

4 комментария Распределение трафика. Объединяем все партнерки.

  1. Ярик

    Классно, как раз то о чем мы думали!)
    Только вот код для меня сложноват, не все понял. А как его можно применить на практике без особых знаний? Просто мой самописный уже меня совсем не устраивает, а вот ТДС юзать не охота, на фришные вроде фильтры стоят..

  2. MUTOgenMUTOgen

    @Ярик, использовать довольно просто. можно взять этот код без изменений и только внести url’ы в массив в начале последнего скрипта. а внутри класса Circle только поправить те url’ы, куда будет литься трафик по умолчанию (ну я там записал, для примеры, адрес своего сайта). При желании можно сделать несколько колец аналогичным способом и разделить массив с url’ами платников на несколько.

  3. Shazzy

    партнерки дело хорошее, молодцы что код написали))
    еле добил полученный код, только все-равно сложновато вышло с кодом, может полегче будет что?

  4. MUTOgenMUTOgen

    на самом деле это наиболее логичное и правильное построение (зявляю как сторонник ООП :))
    здесь довольно прозрачные код и говорящие имена. если есть вопросы задавай.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">