English

Qbalance


Содержание

  1. Введение
  2. Термины и определения
  3. Общая архитектура
  4. Алгоритм выбора прикладного сервера
  5. Глубина очереди нераспределенных клиентов
  6. Контроль доступности серверов
  7. Контроль прав доступа через tcp_wrapper
  8. Запись в системный журнал
  9. Запись в базу данных
  10. Нити (потоки, threads)
  11. Флаг resolve
  12. Отладочная информация
  13. Безопасность
  14. Разное
  15. Условия распространения
  16. Команды конфигурирования
  17. Прототипы SQL-выражений, SYSLOG сообщений.
  18. Программа Qbctl
  19. Вопросы и ответы

  1. Введение
    Программа qbalance предназначена для распределения входящих TCP соединений на несколько прикладных серверов для разделения нагрузки. Используется механизм: для каждого входящего TCP соединения - отдельный дочерний процесс. Конфигурирование qbalance производится "на лету", или через конфигурационный файл. Широкие возможности настройки протоколирования сеансов, в том числе запись в SQL базу данных.
    Работает на FreeBSD-4.8.
    Используются библиотеки: Glib, MM libgetline. ( libwrap libmysql )

    Область применения.

    Программа может использоваться в ситуации, когда:

    Преимущества данного подхода (по сравнению с NAT):

    Минусы:

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

  2. Термины и определения
    Входящий IP адрес и порт - адрес и порт, НА которые устаналиваются TCP соединения со стороны внешних клиентов

    Исходящий IP адрес и порт - адрес и порт ОТ которых устаналиваются TCP соединения.

    Сервер балансировки - выделенный сервер (компьютер), на котором работает программа qbalance Сервер балансировки владееет IP адресом, на который устанавливают соединения внешние клиенты. Прикладные программы на этом сервере НЕ ИСПОЛНЯЮТСЯ.

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

    Группа - в данном документе, означает абстрактное понятие, объединяющее входящий IP адрес, входящий порт на серврере балансировки, список прикладных серверов.
    Внешний клиент устанавливает соединение на IP адрес и порт, принадлежащий группе, и это соединение прозрачно пробрасывается на один из прикладных серверов, входящих в эту группу.
    Не может существовать две группы с одинаковым входящим IP адресом и портом.
    Но прикладной сервер может входить более чем в одну группу.
    Qbalance может обслуживть несколько групп одновременно.

  3. Общая архитектура
    Работающая программа состоит из нескольких процессов: Клиентских процессов может быть множество или ни одного. Главный процесс и checker исполняются всегда.

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

    Главный процесс - однопоточная программа. Его фукнкции:

    Основной алгоритм
    В цикле, проверять групповые сокеты ожидая входящие соединения. В случае поступления соединения, порождать(fork) дочерний процесс для его (соединения) обслуживания. Принимать сообщения от клиентского процесса о успешном\неуспешном пробросе сеанса, и о завершении сеанса. В случае неуспешных попыток проброса сеанса, послать сигнал checker-у для обнаружения нерабочего сервера и его проверки.

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

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

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

    Общая сумма весов всех серверов в группе берется за 100%

    Если есть сервер, у которого нет клиентов - отдаем клиента ему.

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

    	 w1,...wN  - веса 
    	 W         - сумма весов
    	 с1,...сN  - распределение клиентов по серверам
    	 С         - общее число клиентов 
    
    	wK/W - плановая доля
    	сK/C - реальная доля	
    	
    Если для сервера достигнут максимум клиентов, или он помечен нерабочим - его не рассматриваем.

  5. Глубина очереди нераспределенных клиентов
    Может возникнуть ситуация, когда почти одновременно поступит много входящих соединений. При этом каждый следующий сеанс будет обрабатываться в момент, когда предыдущий еще не завершил фазу установления соединения с прикладным сервером. В это время данные по количеству клиентов на каждом прикладном сервере - не корректные. И может возникнуть ситуация, когда, скажем, 10 входящих соединений (поступивших почти одновременно) будут распределены на один и тот-же прикладной сервер, а остальные сервера при этом могут простаивать.
    Чтобы этого не происходило, введено понятие "глубина очереди нераспределенных клиентов" - это максимальне число одновременных сеансов, которые еще не прошли фазу установления соединения с прикладным сервером. Если этих сеансов больше, чем заранее указанное число (P) - обработка следующих сеансов задерживается.

    Как следствие, ошибка алгоритма выбора прикладного сервера = P/wN , wN - вес прикладного сервера.

  6. Контроль доступности прикладных серверов
    Реализовано несколько методов проверки доступности прикладных серверов.
    default
    Процедура проверки, может ли данный прикладной сервер обслужить новых клиентов состоит в попытке установить TCP соединение с ним.

    Если в клиентском процессе попытка установить соединение с прикладным сервером не удалась - клиентский процесс посылает главному сообщение, о недоступности сервера, и продолжает поиск доступного прикладного сервера.

    Главный процесс удаляет этот сервер из списка активных и посылает checker-у сигнал. С этого момента данный сервер не участвует в алгоритме выбора. Checker находит нерабочий сервер и помещает его в очередь на периодическую проверку.

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

    Главный процесс помещает сервер в список активных серверов группы, и с этого момента он снова может участвовать в алгоритме выбора.

    none
    Никакой проверки доступности не производится. Подразумевается, что сервер "Всегда готов!"

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

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

    Checker может проверять одновременно несколько серверов, из разных групп.

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

  7. Контроль прав доступа через tcp_wrapper
    Контроль прав доступа реализован с использованием стандартного механизма "tcp_wrapper", (библиотека libwrap).

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

    Права доступа могут быть разные для каждой группы. Имя сервиса, соответствующего, скажем, группе с именем "7774" , будет выглядеть как "qbalance[7774]".

    Если для данной группы определены logstart или logstop выражения, то, в случае, если даному клиенту запрещено пользаться сервисом, об этом будет сделана запись в систеный журнал.

    Если Вам не нужно будет прозводить контроль доступа, можно исключить связанный с этим код, если убрать ключ -DUSE_WRAPPER в Makefile.

  8. Запись в системный журнал (протоколирование)
    В обычном режиме, в системный журнал записываются сообщения об ошибках, сообщения о добавлении\изменении\удалении групп или серверов, о недоступности\доступности серверов.

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

    Прототип LOG-строки указывается в конфигурационном файле, для каждой группы отдельно, в теле прототипа можно применять специальные последовательности символов - "макросы", вместо которых, в момент исполнения, будут подставлены текущие значения внутренних переменных ( например, время, IP адрес клиента, длительность сеанса и т.д.)

    Если не указаны "logstart" или "logstop" прототипы, соответствующие строки в системный журнал не записываются.

    Если включен контроль прав доступа "tcp_wrapper", и данному клиенту запрещено подключение, запись об этом в системный журнал записывается, только если существует "logstart" или "logstop" прототип.

    Уровень системного журнала:
    для сообщениях об ошибках - LOG_ERROR
    для прочих сообщений - LOG_INFO
    (facility = LOG_DAEMON)

  9. Запись в базу данных
    Кроме протоколирования в системный журнал, существует возможность записывать сообщения в SQL-базу данных. Реализована функция исполнения SQL-запроса ( в общем случае, произвольного, но не предполагающего считывание результатов). Запросы можно исполнять в начале сеанса - перед началом обмена данными(logdbstart), и в конце сеанса, после разрыва соединенения(logdbstop).

    Прототип запроса указывается в конфигурационном файле, отдельно для каждой группы. В теле запроса можно применять специальные последовательности символов - "макросы", вместо которых, в момент исполнения, будут подставлены текущие значения внутренних переменных ( например, время, IP адрес клиента, длительность сеанса и т.д.)

    Кроме собственно прототипа SQL-запроса, необходимо указать параметры базы данных - название базы, хост, где она расположена, имя и пароль пользователя, и тип SQL базы. Все эти параметры можно указывать отдельными командами, либо одной командой, например:

            group logdbpath XXXXXX mysql://dbuser:password@db_host:db_port/database_name  
            
    В текущей версии реализована только поддержка MySQL.

    Если явно не указан пользователь, имя пользователя берется из переменной окружения MYSQL_USER. Если имя пользователя не удалось обнаружить, запросы не выполняются.

    Если явно не указан пароль, он берется из переменной окружения MYSQL_PASSOWRD, если такой переменной не определено, пароль считается пустым.

    Если явно не указан хост, он берется из переменной окружения MYSQL_HOST, если такой переменной не определено, считается, что это "localhost".

    Если явно не указана база, её имя берется из переменной окружения MYSQL_DATABASE. Если такой переменной не определено, запросы не выполняются.

    Каждый зарпос исполняется отдельно и независимо, включая установление и разрыв соединения с MySQL сервером.

    Если не указаны "logdbstart" или "logdbstop" SQL прототипы, соответствующие запросы не исполняются.

    Внимание!

    Если вы используете "CHROOT" для клиентских процессов, и подключаетесь к локальной базе ( "localhost") клиентская библиотека mysql сама решает, что ей нужно использовать UNIX-сокет ( /tmp/mysql.sock) и не находит его. В данном случае нужно явно указать IP адрес (или имя хоста), для того чтобы выбирался TCP сокет.

    Либо можно создать hard link, если chroot каталог на той-же файловой системе, что и /tmp

    Обращаю внимание, что в некоторых ситуациях поток входящих соединений может быть настолько большим, что SQL сервер не будет успевать обрабатывать запросы в реальном времени. Это будет приводить к нарастанию количества процессов и, как следствие - перегрузке сервера балансировки.
    В таком случае можно информацию писать в SYSLOG, и перидически, при помощи внешнего процесса производить "пакетную" загрузку данных в базу.

    Если Вам не нужно будет исполнять SQL-запросы, можно исключить связанный с этим код, если убрать ключ -DUSE_SQL в Makefile.

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

    Если Вы уверены, что исполнение стартового SQL запроса не задерживает, обслуживание клиента, или Вам не нужен стартовый SQL запрос, можно не использовать треды, убрав ключ -DHAVE_PTHREADS в Mаkefile. (по умолчанию, треды не используются.)

  11. Флаг resolve
    Данный флаг разрешает(on, default) или запрещает (off), определение символического имени клиента по его IP адресу, ( а также определение символических имен для сервера и локальных IP адресов).

    Это символическое имя используется при формировании сообщения для системного журнала и при формировании SQL выражения, а так-же, при проверке прав доступа (tcp_wrapper).

    Определение символического имени хоста по IP адресу занимает некоторое время, которое может стать очень большим при некорректной работе внешних DNS серверов.

    Если нужно максимально уменьшить задержку в начале обслуживания клиента, можно отключить определение символических имен при помощи команды "group resolve XXXXXXXX off".

    В случае, когда отключено определение символических имен, но определены прототипы строк для системного журнала или прототипы SQL выражений, при подстановке макросов %a %d %g %j , вместо символьных имен будет подставлено "unknown".

    По умолчанию, определение символических имен разрешено.

  12. Отладочная информация
    Печать отадочной информации включается и отключается асинхронно, и независимо для разных алгоритмических блоков программы.
    	debug  config  on/off   - все, что связано с конфигурированием и контролем 
    	debug  mainloop on/off  - главный цикл 
    	debug  client on/off    - клиентский сеанс.
    	debug  checker on/off   - процедура проверки доступности серверов.
    	debug  srvselect on/off - алгоритм выбора сервера для данного клиента.
    	debug  all on/off       - все вместе.
    	
    Отладочная информация записывается в системный журнал. При переключении режимов печати отладочной информации checker или all, производится перезапуск вспомогательного процесса "checker".

    По умолчанию, печать отладочной информации отключена. Уровень системного журнала - LOG_DEBUG (facility = LOG_DAEMON)

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

    В программе qbalance используются следующие механизмы:

  14. Прочее
        	Сигналы.
    	    SIGUSR1 - используется для взаимодействия между процессами.	    
    	    SIGALRM - используется для определения истечения тайм-аутов.
    	    SIGCHLD - завершение дочернего процесса.
    	    SIGTERM - завершение работы. Главный процесс посылает 
    	      такой-же сигнал всем дочерним, и по истечении 5 секунд после этого
      	      завершается.
    	Файлы
    	    /tmp/qbalance.ctl  -  управляющий сокет.
    	    /usr/local/etc/qbalance.conf - конфигурационный файл по умолчанию.
    	    /var/run/qbalance.pid  - PID файл главного процесса
    	
  15. Условия распространения
    Программа распространяется только в бинарном виде (FreeBDS package), по запросу. Запрос (в свободной форме) направлять по адресу vfom@narod.ru.

© Виктор Фомичев

Last change:
Hosted by uCoz