Inet FAQ

Материал из BiTel WiKi

(Различия между версиями)
Перейти к: навигация, поиск
(При работе по DHCP и статическом адресе абонент иногда получает динамический адрес)
Строка 134: Строка 134:
Для того, чтобы заставить биллинг синхронизировать состояние сервисов согласно балансу нужно добавить в "Глобальные скрипты поведения" - "Классы Java" класс ru.bitel.bgbilling.modules.inet.dyn.access.InetServStateSync. Перед запуском этого скрипта нужно перезапустить BGBillingServer, чтобы синхронизация гарантировано запустилась для всех договоров.
Для того, чтобы заставить биллинг синхронизировать состояние сервисов согласно балансу нужно добавить в "Глобальные скрипты поведения" - "Классы Java" класс ru.bitel.bgbilling.modules.inet.dyn.access.InetServStateSync. Перед запуском этого скрипта нужно перезапустить BGBillingServer, чтобы синхронизация гарантировано запустилась для всех договоров.
 +
 +
 +
== Свободный IP-адрес не найден или Can't reserve ip address ==
 +
 +
Ad

Версия 08:16, 24 октября 2014

Содержание

Не запускается 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 (например, файлы дистрибутива повреждены), попробуйте заменить его.

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

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

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

Решение:

  1. Если в Access постоянные ошибки с синхронизацией для всех устройств (т.е. даже если очередь заработает - функциональность не восстановится), попробуйте их исправить.
  2. Попробуйте перезапустить Access и Accounting.
  3. Если после перезапуска Access не начал выполнять синхронизацию или начал выполнять нормально, но очень и очень медленно, т.е. Number Of Pending Messages не уменьшается, можно попробовать очистить очередь, нажав на ссылку Purge для очереди в web-интерфейсе.
  4. Если Purge не выполняется вообще или выдает ошибку, можно попробовать удалить очередь через ссылку Delete, но после успешного удаления очереди или очередей нужно будет перезапустить BGBillingServer, BGInetAccess и BGInetAccounting.
  5. Если Delete тоже не выполняется или web-интерфейс не открывается, можно попробовать очистить данные activeMQ. Для этого нужно остановить BGBillingServer, Accounting, Access, ActiveMQ, переименовать папку /opt/activemq/data/kahadb (чтобы осталась резервная копия), запустить ActiveMQ, BGBillingServer, Access, Accounting.
  6. Если после очистки очередь все равно набирается - возможно проблемы с конфигурацией Access.
  7. Если с Access все в порядке, а за ActiveMQ замечены еще какие-то проблемы - возможно проблема в дистрибутиве activemq (например, файлы дистрибутива повреждены), попробуйте заменить его.

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


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

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

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


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

Ad


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" />


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

  • Предоставить более полный лог ошибки (исключения), со всеми 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)?

macAddres:
SELECT HEX(macAddress) FROM inet_serv
ipAddress:
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-адресом предыдущая сессия будет завершена, таким образом адрес освободится и для новой сессии будет выдан он же.

Источник — «http://wiki.bitel.ru/index.php/Inet_FAQ»
Личные инструменты