FAQ модуля Inet

Не запускается Access и/или Accounting

Вы только установили Access/Accounting и в access.out или accounting.out ошибка java.lang.ClassNotFoundException, например, для Access:

Error on node access
java.lang.ClassNotFoundException: ru.bitel.bgbilling.modules.inet.access.Access
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:190)
at ru.bitel.bgbilling.kernel.application.server.Application.processBean(Application.java:391)
at ru.bitel.bgbilling.kernel.application.server.Application.process(Application.java:297)
at ru.bitel.bgbilling.kernel.application.server.Application.processChildren(Application.java:749)
at ru.bitel.bgbilling.kernel.application.server.Application.application(Application.java:225)
at ru.bitel.bgbilling.kernel.application.server.Application.<init>(Application.java:161)
at ru.bitel.bgbilling.kernel.application.server.Application.main(Application.java:803)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at ru.bitel.common.bootstrap.Boot.boot(Boot.java:129)
at ru.bitel.common.bootstrap.Boot.main(Boot.java:178)

Решение

В документации по установке Access/Accounting указан пункт "Обновитe как обычные серверные приложения биллинга", т.е. запустите update.sh, который находится в директории биллинга.

Access/Accounting не обновляются через update.sh

При вызове update.sh у Access/Accounting происходит ошибка TimeoutException или NullPointerException:

java.lang.NullPointerException
at bitel.billing.server.installer.library.LibraryUpdate.getLibrariesForUpdate(LibraryUpdate.java:94)
at bitel.billing.server.installer.library.LibraryUpdate.main(LibraryUpdate.java:119)

Решение

Проверьте, что BGBillingServer запущен.

Если Access/Accounting и BGBillingServer запущены на разных машинах - проверьте что время на этих машинах синхронизировано.

Соединение с ограниченным доступом (Reject-To-Accept) подключается, но почти сразу отключается или постоянно меняется ограничение соединения

Обычно это происходит из-за того, что Accounting не знает, в каком состоянии соединение, "подключен" или "отключено", т.е. полный доступ или ограниченный (например, редирект). За это отвечают несколько параметров:

# при значении 1 перед выдачей Access-Accept InetAccess заносит запись в БД об этом соединении (рекомендуется)
connection.start.fromAccept=1
# состояние соединения можно определить по наличию определенных атрибутов в Accounting-пакетах (не рекомендуется)
radius.disable.pattern.attributes=
# при значении 1 InetAccess при вызове для изменения состояния метода connectionModify из CoAServiceActivator/ISGServiceActivator/SmartEdgeServiceActivator сразу поменяет состояние в БД (вызовет e.setConnectionStateModified( true ), рекомендуется для CoAServiceActivator)
sa.radius.connection.stateModify=1
# для схем ISG, SmartEdge с посервисным аккаунтингом состояние сессии можно определять по активности сервиса ISG/SmartEdge (рекомендуется для схем с посервисным аккаунтингом)
radius.serviceName.disable=

Рекомендуемые параметры для CoAServiceActivator:

connection.start.fromAccept=1
sa.radius.connection.stateModify=1

Рекомендуемые параметры для ISGServiceActivator/SmartEdgeServiceActivator c посервисным аккаунтингом:

connection.start.fromAccept=1
sa.radius.connection.stateModify=0
radius.serviceName.disable=<сервис(ы) с ограниченным доступом, через запятую>

Абонентов не пускает, команды на коммутаторах не выполняет

Возможно в ActiveMQ накопилось большое кол-во сообщений и нет возможности их корректно обработать. Проверьте, если в /opt/activemq/data/kahadb большое кол-во файлов *.log (например, больше 5-ти), то скорее всего причина в этом или этом.

Удаление определенных сообщений из очереди ActiveMQ

Для того, чтобы через командную строку удалить сообщения, необходимо, чтобы в ActiveMQ был включен JMX. Для этого в conf/activemq.xml должен был пункт managementContext с createConnector="true"

<managementContext>
<managementContext createConnector="true"/>
</managementContext>

После изменения необходимо перезапустить ActiveMQ.

Если JMX включен, то команда activemq-admin purge позволяет удалить определенные сообщения из очереди. Например, чтобы удалить сообщения о необходимости изменения состояния сервисов для устройства с ID=55, нужно выполнить:

./activemq-admin purge --msgsel "deviceId=55" BG.Event.ru.bitel.bgbilling.modules.inet.access.sa.event.InetSaStateModifyEvent

https://activemq.apache.org/activemq-command-line-tools-reference.html#ActiveMQCommandLineToolsReference-purge

В ActiveMQ копятся и в итоге не обрабатываются сообщения

Для того, чтобы быстрее узнать, почему ActiveMQ копит сообщения лучше включить web-консоль ActiveMQ. Для этого в /opt/activemq/conf/activemq.xml расскомментируйте ветку <import resource="jetty.xml"/> и перезапусите ActiveMQ.

<!-- Enable web consoles, REST and Ajax APIs and demos It also includes Camel (with its web console), see ${ACTIVEMQ_HOME}/conf/camel.xml for more info
Take a look at ${ACTIVEMQ_HOME}/conf/jetty.xml for more details -->
<import resource="jetty.xml"/>

Проследите, чтобы порт не оказался открыт наружу.

Откройте в браузере web-консоль http://адрес:8161/admin, перейдите в Queues. Number Of Pending Messages - это кол-во сообщений, которые ActiveMQ получил, но еще не успел или не смог передать приложениям биллинга. При нормальной работе среднее значение 0 или небольшое, т.е. при увеличении очень быстро уменьшается обратно.

Если web-консоль не открывается, при этом activemq.xml поправили корректно и порт 8161 открыт - возможно проблема в дистрибутиве activemq (старая версия ActiveMQ), попробуйте заменить его.

Если значения Number Of Pending Messages у каких-либо очередей большие и не уменьшаются, то на это может быть несколько причин.

Это может быть очередь скриптовых событий (Функции скриптов поведения), возможно:

  • в БД (script_event_type) по какой-то причине нет инфомации об этом событии и сервер его не слушает (обычно большая очередь у одного-двух скриптовых событий);

  • какой-то скрипт/класс поведения работает слишком медленно (у всех скриптовых событий есть какое-то количество сообщений в очереди).

Это могут быть очереди заданий синхронизации Inet, возможно:

  • произошел какой-то сбой (например, ниже), очередь переполнилась и теперь не может отработать корректно;

  • одно из устройств (NAS' или коммутатор) очень долгое время не отвечало при попытках синхронизации, таким образом сообщения для него постепенно копились и см. первую причину; нужно посмотреть логи Access;

  • Access долгое время не был запущен и см. первую причину;

  • конфигурация Access некорректна, например, значения rootDeviceId или accounting.deviceTypeIds неправильные;

  • ошибка в ServiceActivator при синхронизации с NAS'ом или коммутатором, нужно смотреть логи Access (возможно нужно перекомпилировать динамические классы);

  • одно из устройств удалили через БД, но к нему были привязаны активные сервисы Inet, в итоге Accounting генерирует сообщения, которые Access не может обработать.

Можно открыть конкретную очередь в web-консоли и посмотреть, какие там сообщения, для каких устройств (поле deviceId).

Решение (Inet)

  1. Если в Access постоянные ошибки с синхронизацией для всех устройств (например, нет подключения к коммутаторам), попробуйте их исправить.

  2. Попробуйте перезапустить Access и Accounting.

  3. Если после перезапуска Access не начал выполнять синхронизацию или начал выполнять нормально, но очень и очень медленно, т.е. Number Of Pending Messages не уменьшается, можно попробовать очистить очередь, нажав на ссылку Purge для очереди в web-интерфейсе.

  4. Если Purge не выполняется вообще или выдает ошибку (старые версии ActiveMQ), можно попробовать удалить очередь через ссылку Delete, но после успешного удаления очереди или очередей нужно будет перезапустить BGBillingServer, BGInetAccess и BGInetAccounting.

  5. Если Delete тоже не выполняется или web-интерфейс не открывается (старые версии ActiveMQ), можно попробовать очистить данные activeMQ. Для этого нужно остановить BGBillingServer, Accounting, Access, ActiveMQ, переименовать папку /opt/activemq/data/kahadb (чтобы осталась резервная копия), запустить ActiveMQ, BGBillingServer, Access, Accounting.

  6. Если после очистки очередь все равно набирается - возможно проблемы с конфигурацией Access.

  7. Если с Access все в порядке, а за ActiveMQ замечены еще какие-то проблемы - возможно проблема в дистрибутиве activemq (например, файлы дистрибутива повреждены), попробуйте заменить его.

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

Не совпадает состояние сервиса Inet с тем, что должно быть

После сбоя или после ручного добавления платежей в БД состояние сервисов может не совпадать с необходимым. При этом при пересохранении сервиса состояние меняется на нормальное. Если это произошло по неизвестной причине, следует ее выяснить. Например, при проблеме c обработкой сообщений (см. В ActiveMQ копятся и в итоге не обрабатываются сообщения) необходимо сначала устранить ее. Или есть скрипт добавления платежей, который не создает необходимые события - необходимо сначала его исправить.

Для того, чтобы заставить биллинг синхронизировать состояние сервисов согласно балансу нужно добавить в "Глобальные скрипты поведения" - "Классы Java" класс ru.bitel.bgbilling.modules.inet.dyn.access.InetServStateSync. Перед запуском этого скрипта нужно перезапустить BGBillingServer, чтобы синхронизация гарантировано запустилась для всех договоров.

Все сессии сбросились на NAS'е, при массовом переподключении - проблемы

Если произошел сбой питания или по какой-то другой причине сессии на NAS'е были сброшены - в этой ситуации сессии остаются в биллинге, т.к. от NAS'а не пришел RADIUS-stop-пакет. При этом адрес, привязанный к сессии считается занятым. По умолчанию сессия не будет закрыта, пока не выйдет connection.close.timeout. Также следует учитывать, что перезапуск InetAccounting приведет к сбросу последней активности на время запуска InetAccess (т.к. в другой ситуации пакеты могли приходить пока InetAccess был не запущен). При этом могут возникнуть проблемы, что абонентов не пускает по ограничению кол-ва сессий, либо происходит ошибка "Свободный IP-адрес не найден".

Такие повисшие сессии можно убрать двумя способами:

  • С помощью radius.connection.checkDuplicate, чтобы при новых Access-Request от одного и того же пользователя старую сессию закрывать в биллинге. Желательно чтобы и при обычной работе этот параметр был указан (но скорее всего понадобится другое значение, чем при такой аварии).

  • Уменьшить в конфигурации устройства connection.close.timeout и connection.suspend.timeout до минуты или даже 5 секунд, указать в конфигурации корневого устройства более частую обработку завершения сессий:

    # пауза между заданиями
    accounting.worker.3.finishing.1.delay=10
    # максимальное количество сброшенных соединений в базу за задание
    accounting.worker.3.finishing.1.batchSize=5000

    Перезапустить InetAccounting, затем после того как сессии будут завершены в биллинге и пропадут из монитора вернуть правильные значения connection.close.timeout и connection.suspend.timeout и нажать "Перечитать конфигурацию на серверах". Позже можно вернуть сброс сессий в БД (finishing) в прежние значения (для этого понадобится перезапуск InetAccounting).

Также следует учитывать, что при выдаче Access-Accept вместе с ним выдается IP-адрес, который резервируется на минуту. Таким образом, если в inet-access.xml для radiusListener указано большое значение очереди maxQueueSize возможна ситуация, что InetAccess будет выдавать Access-Accept, который абонент уже перестал ждать и отправил новый Access-Request. В этом случае адреса будут выдаваться в никуда, это также может быть причиной ошибки "Свободный IP-адрес не найден", а также задержке восстановления до нормальной работы. Поэтому если maxQueueSize больше 200, укажите 100-200 и перезапустите InetAccess. С версии 6.0 InetAccess старается не обрабатывать пакеты из очереди, которые он считает устаревшими, поэтому вероятность возникновения проблемы из-за maxQueueSize меньше.

Свободный IP-адрес не найден или Can't reserve ip address

Если произошел сброс сессий на NAS'е - смотрите выше.

Если назначенных ресурсов IP-адресов должно хватать, посмотрите текущую информацию об IP-ресурсах в выводе команды './accounting.sh status'.

Проверьте, что таблицы в базе данных у вас в InnoDB, а не MyISAM:

SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA="bgbilling" AND ENGINE="MyISAM"

Если в MyISAM (мы используем InnoDB c 5.2, информация об этом есть в документации и инструкции по обновлению) - сконвертируйте с помощью утилит: http://wiki.bitel.ru/index.php/Рекомендации_по_настройке_MySQL

Далее, даже если таблицы в InnoDB - проверьте целостность данных

SELECT INET_NTOA(CONV(HEX(s.address), 16, 10)), s.* FROM inv_ip_resource_subscription_dyn_<mid>_<yyyyMM> as s
LEFT JOIN inet_connection_<mid> as c ON s.ipResourceId=c.ipResourceId AND s.address=c.ipAddress AND c.status=1
WHERE s.timeTo IS NULL AND c.id IS NULL

В yyyyMM сначала укажите текущий месяц, затем выполните запрос для предыдущих. Если в выводе много строк, возможно какая-то ошибка (в билдах до июля 2014 г. в некоторых случаях могла возникнуть такая проблема) и биллинг считает эти адреса занятыми. Проверьте, действительно ли эти адреса свободны. Если да и записей набирается как раз, чтобы занять до конца пул IP-адресов, попробуйте завершить эту подписку (осторожно!):

UPDATE inv_ip_resource_subscription_dyn_<mid>_<yyyyMM> as s
LEFT JOIN inet_connection_<mid> as c ON s.ipResourceId=c.ipResourceId AND s.address=c.ipAddress AND c.status=1
SET s.timeTo=NOW()
WHERE s.timeTo IS NULL AND c.id IS NULL

Затем перезапустите InetAccess и InetAccounting, перед этим сохранив их логи для дальнейшего разбирательства.

Access и/или Accounting потребляют много памяти

Access и/или Accounting потребляют много памяти постепенно после старта

Возможно задействовано много источников логов (NAS'ы, которые посылают пакеты RADIUS, коммутаторы, которые посылают DHCP-пакеты, flow-агенты). При получения, обработки и записи DHCP/Radius/Netflow/sFlow пакетов используются буферы. Максимальное кол-во памяти, которые могут забрать буферы - threadCount * datalog.chunk.size * (кол-во устройств-источников данных), где threadCount - кол-во потоков слушателя (InetRadiusListener/DhcpListener/InetFlowListener).

Решение

В этом случае не стоит указывать большое кол-во потоков для слушателя threadCount и при большом кол-ве источников логов имеет смысл уменьшить chunk.size:

# Общее для всех значение, используется, если не указано специально для типа лога
datalog.chunk.size=131072
# DHCP
datalog.dhcp.chunk.size=65536
# RADIUS
datalog.radius.chunk.size=65536
# Netflow/sFlow
datalog.flow.chunk.size=262144

Эти параметры указываются в inet-access.xml и inet-accounting.xml. Пример для inet-accounting.xml:

<!-- Параметры сохранения radius-пакетов в файлы логов -->
<!-- Директория, в которую сохранять radius логи -->
<param name="datalog.radius.dir" value="data/radius" />
<!-- Размер блока данных в файле лога, также размер буфера на поток слушателя -->
<param name="datalog.radius.chunk.size" value="524288" />
<!-- Сжимать radius логи: 0 - не сжимать, 1 - zlib -->
<param name="datalog.radius.compression.type" value="1" />
<!-- Параметры сохранения flow-пакетов в файлы логов -->
<!-- Директория, в которую сохранять flow логи -->
<param name="datalog.flow.dir" value="data/flow" />
<!-- Размер блока данных в файле лога, также размер буфера на поток слушателя -->
<param name="datalog.flow.chunk.size" value="524288" />
<!-- Сжимать flow логи: 0 - не сжимать, 1 - zlib -->
<param name="datalog.flow.compression.type" value="1" />

Accounting потребляет много памяти сразу после старта

При использовании InetFlowListener возможна схема, когда будет множество устройств-коммутаторов с интерфейсами, которые никак не связаны с Flow-агентом и поэтому у них не указан в конфигурации flow.agent.link. Исторически сложилось, что если параметр flow.agent.link не указан, то устройство само считается Flow-агентом с указанными интерфейсами. Для экономии памяти рекомендуется указать для таких устройств flow.agent.link={@deviceId}:-1.

Как помочь разработчикам быстрее исправить ошибку

  • Предоставить более полный лог ошибки (исключения), со всеми Caused, а не только первую строчку, например:

    05-20/12:22:29 ERROR ["http-bio-/0.0.0.0-8080"-exec-5] AbstractJaxWsHandler -
    java.util.concurrent.ExecutionException: java.security.PrivilegedActionException: java.lang.Exception: java.lang.NullPointerException
    at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:232)
    at java.util.concurrent.FutureTask.get(FutureTask.java:91)
    at ru.bitel.bgbilling.kernel.script.server.DynamicScriptEventListener$ThreadedScriptEventListener.runScriptImpl(DynamicScriptEventListener.java:267)
    at ru.bitel.bgbilling.kernel.script.server.DynamicScriptEventListener.runScript(DynamicScriptEventListener.java:149)
    at ru.bitel.bgbilling.kernel.script.server.DynamicScriptEventListener.notify(DynamicScriptEventListener.java:117)
    at ru.bitel.bgbilling.kernel.event.LocalEventProcessor.request(LocalEventProcessor.java:240)
    at ru.bitel.bgbilling.kernel.event.EventProcessor.request(EventProcessor.java:848)
    at ru.bitel.bgbilling.kernel.event.EventProcessor.request(EventProcessor.java:817)
    at bitel.billing.server.contract.action.ActionUpdateListParam.doAction(ActionUpdateListParam.java:35)
    at bitel.billing.server.Executer.doModule(Unknown Source)
    at bitel.billing.server.Executer$1.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at javax.security.auth.Subject.doAs(Subject.java:396)
    at bitel.billing.server.Executer.doPost(Unknown Source)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at bitel.billing.server.filters.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:48)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:164)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:462)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:563)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:403)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:301)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:162)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:309)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:662)
    Caused by: java.security.PrivilegedActionException: java.lang.Exception: java.lang.NullPointerException
    at java.security.AccessController.doPrivileged(Native Method)
    at javax.security.auth.Subject.doAs(Subject.java:396)
    at ru.bitel.bgbilling.kernel.script.server.DynamicScriptEventListener$ThreadedScriptEventListener$1.call(DynamicScriptEventListener.java:241)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
    at java.util.concurrent.FutureTask.run(FutureTask.java:138)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:662)
    at ru.bitel.common.worker.WorkerThread.run(WorkerThread.java:40)
    Caused by: java.lang.Exception: java.lang.NullPointerException
    at ru.bitel.bgbilling.kernel.script.server.DynamicScriptEventListener.runScriptImpl(DynamicScriptEventListener.java:200)
    at ru.bitel.bgbilling.kernel.script.server.DynamicScriptEventListener$ThreadedScriptEventListener.access$0(DynamicScriptEventListener.java:1)
    at ru.bitel.bgbilling.kernel.script.server.DynamicScriptEventListener$ThreadedScriptEventListener$1$1.run(DynamicScriptEventListener.java:247)
    ... 9 more
    Caused by: java.lang.NullPointerException
    at ru.bitel.bgbilling.kernel.script.server.DynamicScriptEventListener.runScriptImpl(DynamicScriptEventListener.java:196)
    ... 11 more
  • Сохранить лог-файлы на момент ошибки

  • Сохранить информацию по стекам c помощью утилиты jstack из JDK:

    jstack <id_процесса> > stack1.txt
  • Если проблема сложная или связана с излишнем потреблением памяти - сделать дамп памяти процесса (может быть затратно по ресурсам) с помощью утилиты jmap из JDK (дамп памяти нельзя выкладывать в открытый доступ). Данная операция может быть ресурсозатратна, особенно на приложениях, которые заняли более 1GB оперативной памяти:

    jmap -dump:format=b,file=dump.hprof <id_процесса>

    Перед снятием дампа рекомендуется вызвать garbage collector:

    accounting.sh gc

Как SQL запросом посмотреть IP-адрес, MAC-адрес из inet_serv varbinary(64)?

MAC:

SELECT HEX(macAddress) FROM inet_serv

IP:

SELECT INET_NTOA(CONV(HEX(ipAddress), 16, 10)) FROM inet_connection
SELECT * FROM inet_connection WHERE ipAddress=UNHEX(CONV(INET_ATON('10.0.0.1'), 10, 16))

Невозможно удалить сервис с активным периодом действия

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

Создание Web-сервиса в динамическом коде

Тут создается Web-сервис InetDeviceService. Web-сервис для любого другого класса получается по аналогии. INET_MODULE_ID - код экземпляра модуля inet.

ServerContext context = ServerContext.get();
InetDeviceService wsDevice = context.getService( InetDeviceService.class, INET_MODULE_ID );

При работе по DHCP и статическом адресе абонент иногда получает динамический адрес

Скорее всего это происходит, когда абонент подключает другое устройство. Появляется новый MAC, биллинг не может технически определить, что предыдущая сессия уже закончилась, только по таймауту DHCP-lease, поэтому считает адрес еще занятым и выдает адрес из динамического пула. При схеме один порт/VLAN - один компьютер/роутер поможет параметр конфигурации устройства Inet dhcp.connection.closeOnNew=1. С этим флагом при появлении DHCP Discover с того же порта/VLAN с другим MAC-адресом предыдущая сессия будет завершена, таким образом адрес освободится и для новой сессии будет выдан он же.

При работе по DHCP и статическом адресе абонент иногда получает динамический адрес

Скорее всего это происходит, когда абонент подключает другое устройство. Появляется новый MAC, биллинг не может технически определить, что предыдущая сессия уже закончилась, только по таймауту DHCP-lease, поэтому считает адрес еще занятым и выдает адрес из динамического пула. При схеме один порт/VLAN - один компьютер/роутер поможет параметр конфигурации устройства Inet dhcp.connection.closeOnNew=1. С этим флагом при появлении DHCP Discover с того же порта/VLAN с другим MAC-адресом предыдущая сессия будет завершена, таким образом адрес освободится и для новой сессии будет выдан он же.

Ошибка InetDhcpProcessor - Timeout exceed!

В логах InetAccess есть ошибки при обработке DHCP-запросов:

dhcp 01-10/21:33:31 ERROR [dhcpLstnr-p-10-t-11] InetDhcpProcessor - Timeout exceed!
ru.bitel.bgbilling.common.BGException: Timeout exceed!
at ru.bitel.bgbilling.modules.inet.access.InetConnectionManager.accountingStart(InetConnectionManager.java:576)
at ru.bitel.bgbilling.modules.inet.dhcp.InetDhcpProcessor.processOption82RequestImpl0(InetDhcpProcessor.java:757)
at ru.bitel.bgbilling.modules.inet.dhcp.InetDhcpProcessor.processOption82RequestImpl(InetDhcpProcessor.java:216)
at ru.bitel.bgbilling.modules.inet.dhcp.InetAbstractDhcpProcessor.processOption82Request(InetAbstractDhcpProcessor.java:504)
at ru.bitel.bgbilling.modules.inet.dhcp.InetAbstractDhcpProcessor.processRequest(InetAbstractDhcpProcessor.java:253)
at ru.bitel.bgbilling.kernel.network.dhcp.DhcpListenerWorker.runImpl(DhcpListenerWorker.java:89)
at ru.bitel.common.worker.WorkerTask.run(WorkerTask.java:86)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
at java.lang.Thread.run(Thread.java:662)
at ru.bitel.common.worker.WorkerThread.run(WorkerThread.java:40)

Решение

  • Возможно, проблемы с activemq, проверьте пункт В ActiveMQ копятся и в итоге не обрабатываются сообщения.

  • Если activemq, InetAccess или InetAccounting находятся на разных машинах, убедитесь, что время между ними синхронизовано. Проверьте еще раз, расхождения на секунды достаточно для создания проблем (это же все-таки биллинг).

  • Если и там все в порядке, а это первичная установка или недавно менялась конфигурация сети или серверов убедитесь, что имя сервера с ActiveMQ указано в файле /etc/hosts. Имя сервера можно получить командой uname -n. ActiveMQ-сервер, http://forum.bitel.ru/viewtopic.php?f=44&t=10031\

Пакеты из некоторых сетей не доходят до слушателя radius или dhcp.

Иногда бывает что до InetAccess не доходят dhcp-запросы, при это на этой же машине tcpdump их видит(даже может работать стандартный isc сервер если его запустить на том же порте) . Первое что нужено проверить - это настройка файервола.

И одна из возможных причин изложена ниже.

В сетвых подсистемах есть RPF (Reverse Path Filtering)

http://xgu.ru/wiki/RPF

Cмысл в том, что к серверу прилетает запрос например из сети 10.1.1.0/24 и для сервера этой сети нет в таблицы маршрутизации. Он думает что его надо отправить по маршруту по умолчанию.
Но прилетел он с другой сетевой карты, не там где находится маршут по умолчанию. Поэтому пакет не проходит проверку.
Есть 2 выхода из положения.

1. Добавить маршрут к сети, кто делает релей, через тот интерфейс, через который все прилетает.
2. отключить проверку на том интерфейсе, с которого прилетает пакет.
https://serverfault.com/questions/816393/disabling-rp-filter-on-one-interface

Удаление старых данных из БД

Можно удалять месячные таблицы за предыдущие месяцы (например, старше двух месяцев):

  • inet_auth_error_x_yyyyMM - таблица, которая используется для отображения ошибок на вкладке Монитор;

  • connection_log_entry_x_yyyyMM - таблица, которая используется для получения RADIUS/DHCP-логов при нажатии правой кнопкой мыши на сессии.

Если не нужна история сессий за предыдущие месяцы (например, старше полугода), то можно удалить:

  • inet_session_log_x_yyyyMM - сессии абонентов

  • inet_session_log_detail_x_yyyyMM - информация по трафикам сессий (тип трафика - кол-во)

  • inet_session_log_account_x_yyyyMM - информация по наработке сессий (услуга - кол-во, наработка)

Или, если же информация по сессиям нужна, но не нужна информация по трафикам, а достаточно информации по наработке, то можно выполнить TRUNCATE inet_session_log_detail_x_yyyyMM для старой таблицы. Если и детализации по наработке старых сессий не нужна, то выполните также TRUNCATE inet_session_log_account_x_yyyyMM