java.lang.RuntimeException: wXb6Vnl31u :: Ошибка для HTML= 001 003 004 005 006 007 008 009
010

Компонент MyBPM API

011 012

Компонент MyBPM API распространяется как образ контейнера 013 Docker. Примерное имя контейнера следующее:

014 015
016  hub.mybpm.kz/mybpm-api-...
017  
018  
019  
020  
021 022

Где вместо многоточия стоит ветка разработки и версия данного 023 компонента. Вы его получите от разработчика.

024 025

При запуске, этот компонент вначале проверяет все соединения с 026 базами данных. Если до какой-то базы данных он не может 027 достучаться, то он падает и выдаёт ошибку в логи. По этой ошибке 028 нужно понять причину. Исправить её и запустить компонент 029 заново.

030 031

MyBPM API-сервис для своей работы требует следующие базы 032 данных:

033 034
    035
  1. 036

    MongoDB - это основная база данных. Здесь платформа MyBPM хранит 037 оперативную информацию.

    038
  2. 039 040
  3. 041

    MongoDB (Files) - здесь хранятся файлы. Можно эту базу-данных 042 совместить с оперативной MongoDB. Но это не рекомендуется, так как 043 характер работы с файлами сильно отличается.

    044
  4. 045 046
  5. 047

    Apache Kafka - здесь платформа MyBPM хранит историческую 048 информацию. Также кафка используется как брокер сообщений для 049 синхронизации данных между различными компонентами платформы 050 MyBPM.

    051
  6. 052 053
  7. 054

    Apache Zookeeper - здесь платформа хранит свою конфигурацию. 055 Желательно администраторам платформы иметь веб-интерфейс к 056 Zookeeper. Например, ZooNavigator: https://zoonavigator.elkozmon.com/en/latest/

    058
  8. 059 060
  9. 061

    ElasticSearch - здесь платформа MyBPM хранит оперативную 062 информацию для поиска по ней (в MongoDB для поиска ходить 063 запрещено)

    064
  10. 065 066
  11. 067

    PostgreSQL - здесь обрабатываются различные алгоритмы с 068 использованием реляционного механизма.

    069
  12. 070
071 072

Требования к БД, к которым подключается компонент MyBPM API 073 смотрите здесь

074 075

Конфигурация платформы MyBPM

076 077

Вся конфигурация платформы MyBPM находиться на сервере ZooKeeper 078 поэтому рекомендуется иметь удобный интерфейс к нему, разработчики 079 рекомендуют ZooNavigator: https://zoonavigator.elkozmon.com/en/latest/

081 082

Его можно быстро установить через докер: https://hub.docker.com/r/elkozmon/zoonavigator

084 085

В будущем планируется конфигурацию системы перенести полностью 086 на MongoDB и отказаться от Zookeeper. Это будет сделано абсолютно 087 бесшовно. А управление конфигурацией будет через Web-интерфейс, 088 встроенный в платформу MyBPM.

089 090

Файлы конфигурации создаются автоматически со значениями по 091 умолчанию. Эти значения уже настроены для оптимальной работы 092 платформы MyBPM. Но иногда может возникнуть ситуации, что их можно 093 поменять. После изменения этих параметров платформу MyBPM 094 перезапускать НЕ нужно - они применяются на платформе НА 095 ГОРЯЧУЮ.

096 097

Жонглирование подсистемой MyBPM API

098 099

MyBPM API содержит в себе подсистемы:

100 101
    102
  1. 103

    REST-API: Подсистема обработки REST-сервисов и Web-сокетов

    104
  2. 105 106
  3. 107

    Kafka Consumers: Подсистема обработки сообщений кафки

    108
  4. 109 110
  5. 111

    Schedulers: Подсистема выполнения задач по расписанию.

    112
  6. 113
114 115

Их можно включать и выключать на конкретном сервере. Тем самым 116 можно распределять нагрузку между серверами, в случае, если один 117 сервер не справляется со всеми задачами. Это напоминает 118 микро-сервисную архитектуру, просто все сервисы сосредоточены в 119 одной программе, и их можно активировать и деактивировать выборочно 120 с помощью переменных окружения.

121 122

Параллельная работа подсистем

123 124

Все эти подсистемы реализованы так, чтобы могли работать на 125 нескольких экземплярах параллельно.

126 127

Подсистема REST-API реализована по принципу БЕЗ-СОСТОЯНИЯ 128 (state-less), поэтому, если один сервер не справляется с нагрузкой, 129 можно запустить несколько копий и случайным образом выбирать 130 обработчик запросов. Для этого можно использовать балансировщик 131 нагрузки, и он может работать в любых режимах (случайный выбор, 132 выбор менее нагруженного сервере и др. - это зависит от имеющегося 133 ПО по управлению нагрузкой).

134 135

Подсистема REST-API всегда активна - её отключение делается 136 недоступностью данного сервера для REST-запросов.

137 138

В подсистеме Schedulers все задачи реализованы так, чтобы 139 корректно отрабатывать даже если одновременно запущены на разных 140 серверах. Следует знать, что эти задачи не нуждаются в большом 141 количестве ресурсов, и поэтому их можно держать только на одном 142 сервере. В случае например миграции, то миграция проходит через 143 кафку, а сама задача просто инициирует миграцию заполняя кафку 144 записями с идентификаторами, которые говорят куда смигрировать одну 145 запись. Другие задачи решаются подобным образом.

146 147

Подсистему Schedulers на одном сервере можно отключить с помощью 148 переменной окружения:

149 150
151   MYBPM_SCHEDULER_OFF
152  
153  
154  
155  
156 157

Описание переменных окружения 158 здесь.

159 160

Подсистема Consumers - это набор обработчиков сообщений из кафки 161 из различных топиков. Её распараллеливание решается самой 162 архитектурой кафки. Главное чтобы топики в кафке содержали большое 163 количество партиций. Рекомендуется 48 для малых систем. И 480 - для 164 больших.

165 166

Подсистему Consumers на одном сервере можно отключить с помощью 167 переменной окружения:

168 169
170  MYBPM_ALL_CONSUMERS_OFF
171  
172  
173  
174  
175 176

Описание переменных окружения 177 здесь.

178 179

Настройка обработчиков в подсистеме 180 Consumers

181 182

Конфигурация управляющая обработчиками сообщений из кафки 183 находиться по пути

184 185
186  /mybpm/consumers/...
187  
188  
189  
190  
191 192

Этот путь можно поменять с помощью переменной окружения

193 194
195  MYBPM_CONSUMER_DIR
196  
197  
198  
199  
200 201

Описание переменных окружения 202 здесь.

203 204

Тем самым можно распределить настройки одних 205 серверов-consumer-ов в одном месте, а других - в другом. Это 206 позволяет распределять обработку различных ТИПОВ сообщений из кафки 207 по разным серверам.

208 209

Рассмотрим пример. Есть файл конфигурации:

210 211
212  /mybpm/consumers/BoiEvents.workerCount
213  
214  
215  
216  
217 218

В нём содержится следующий текст:

219 220
221  #
222  # Created at 2023-10-23 16:26:40
223  #
224  # Генерирует события инстанций БО по их изменениям и кидает их в кафку
225  boiKafkaToBoiEventKafka = 1
226  #
227  # Appended at 2023-10-23 16:26:40
228  #
229  # Парсит события инстанций БО для отображения их на клиенте
230  applyBoiEventKafkaToMongo = 1
231  
232  
233  
234  
235 236

Параметр boiKafkaToBoiEventKafka соответствует 237 одному обработчику, который "Генерирует события..." - об этом 238 сказано в комментарии к параметру выше. Цифра у этого параметра 239 обозначает количество потоков, которые обрабатывают данные 240 сообщения.

241 242

Например, Вы хотите, чтобы на сервере S1 обрабатывались только 243 boiKafkaToBoiEventKafka в три потока, а на сервере S2 244 обрабатывались только applyBoiEventKafkaToMongo в 245 четыре потока.

246 247

Для этого на сервере S1 установите переменную окружения 248 MYBPM_CONSUMER_DIR=s1, а на сервере S2 установите 249 переменную окружения MYBPM_CONSUMER_DIR=s2. После 250 запуска этих серверов платформа создаст следующие конфиги:

251 252
253  /mybpm/consumers-s1/BoiEvents.workerCount
254  boiKafkaToBoiEventKafka = 1
255  applyBoiEventKafkaToMongo = 1
256  
257  
258  
259  
260 261

И:

262 263
264  /mybpm/consumers-s2/BoiEvents.workerCount
265  boiKafkaToBoiEventKafka = 1
266  applyBoiEventKafkaToMongo = 1
267  
268  
269  
270  
271 272

Здесь комментарии убраны, а первая строка - это путь к 273 файлу.

274 275

Вам нужно изменить эти конфиги следующим образом:

276 277
278  /mybpm/consumers-s1/BoiEvents.workerCount
279  boiKafkaToBoiEventKafka = 3
280  applyBoiEventKafkaToMongo = 0
281  
282  
283  
284  
285 286

И:

287 288
289  /mybpm/consumers-s2/BoiEvents.workerCount
290  boiKafkaToBoiEventKafka = 0
291  applyBoiEventKafkaToMongo = 4
292  
293  
294  
295  
296 297

После сохранения этих файлов перезапускать сервера НЕ НУЖНО - 298 платформа автоматически узнает об их изменении и обновит своё 299 поведение.

300 301

Теперь будет работать всё так, как Вы запланировали.

302 303

Учтите, что платформа MyBPM создаст не только этот 304 конфигурационный файл, но и другие файлы тоже, и Вам нужно их тоже 305 настроить соответствующим образом.

306 307

Настройка расписания в подсистеме 308 Schedulers

309 310

Расписания в подсистеме Schedulers тоже вынесены в 311 конфигурационный файл. Конфигурация расписаний находиться по 312 пути:

313 314
315  /mybpm/scheduler/core/...
316  
317  
318  
319  
320 321

Для ядра системы, и по пути:

322 323
324  /mybpm/scheduler/plugin/<plugin-id>/...
325  
326  
327  
328  
329 330

Для плагинов.

331 332

Эти файлы тоже создаются платформой автоматически и заполняются 333 расписанием по умолчанию. Так же в эти конфиги добавлено описание 334 как самих задач с расписанием, так и формата расписания.

335 336

Например, есть файл:

337 338
339  /mybpm/scheduler/core/BoProcessScheduler.scheduler-config.txt
340  executeProcesses = repeat every 10 min
341  
342  
343  
344  
345 346

(Здесь комментарии убраны, а первая строка - это путь к 347 файлу.)

348 349

И Вам нужно увеличить интервал запуска этой задачи до тридцати 350 минут. Тогда Вам нужно написать:

351 352
353  /mybpm/scheduler/core/BoProcessScheduler.scheduler-config.txt
354  executeProcesses = repeat every 30 min
355  
356  
357  
358  
359 360

И, после сохранения, платформа MyBPM автоматически 361 идентифицирует изменение файла и обновит данное расписание. Если же 362 Вы допустите ошибку в формате расписания, то платформа отключит 363 запуск данной задачи, и создаст файл:

364 365
366  /mybpm/scheduler/core/BoProcessScheduler.scheduler-config.txt.error
367  
368  
369  
370  
371 372

В котором опишет данную ошибку. Вы её исправите, и после 373 сохранения этот файл удалиться сам, что обозначает, что никаких 374 ошибок нет, и расписание принялось к запуску задачи.

375 376

Так же Вам может понадобиться отключить вообще запуск данной 377 задачи, для этого Вам нужно поставить символ решётки, вот так:

378 379
380  /mybpm/scheduler/core/BoProcessScheduler.scheduler-config.txt
381  executeProcesses = # repeat every 30 min
382  
383  
384  
385  
386 387

И тогда запуск этой задачи будет отменён.

388 389

УЧТИТЕ, решётка должна стоять ПОСЛЕ знака равно.

390
391 392 at kz.greetgo.md_reader.util.MdUtil.xmlTextToDoc(MdUtil.java:80) at kz.greetgo.md_reader.core.MdConverter.prepareHtmlFileFrom(MdConverter.java:136) at kz.greetgo.md_reader.core.MdConverter.convert(MdConverter.java:208) at kz.greetgo.md_reader.controller.RenderController.downloadToc(RenderController.java:360) at kz.greetgo.md_reader.controller.RenderController.request(RenderController.java:108) at jdk.internal.reflect.GeneratedMethodAccessor3.invoke(Unknown Source) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:568) at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:207) at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:152) at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:884) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797) at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1081) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:974) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1011) at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903) at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564) at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885) at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:205) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) at kz.greetgo.md_reader.interceptors.TextReplaceFilter.doFilter(TextReplaceFilter.java:36) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:166) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:341) at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:390) at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:894) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1741) at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.base/java.lang.Thread.run(Thread.java:833) Caused by: java.io.IOException: Server returned HTTP response code: 429 for URL: http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:2000) at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1589) at java.xml/com.sun.org.apache.xerces.internal.impl.XMLEntityManager.setupCurrentEntity(XMLEntityManager.java:677) at java.xml/com.sun.org.apache.xerces.internal.impl.XMLEntityManager.startEntity(XMLEntityManager.java:1397) at java.xml/com.sun.org.apache.xerces.internal.impl.XMLEntityManager.startEntity(XMLEntityManager.java:1333) at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDTDScannerImpl.startPE(XMLDTDScannerImpl.java:732) at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDTDScannerImpl.skipSeparator(XMLDTDScannerImpl.java:2101) at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDTDScannerImpl.scanDecls(XMLDTDScannerImpl.java:2064) at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDTDScannerImpl.scanDTDExternalSubset(XMLDTDScannerImpl.java:299) at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$DTDDriver.dispatch(XMLDocumentScannerImpl.java:1165) at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$DTDDriver.next(XMLDocumentScannerImpl.java:1040) at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(XMLDocumentScannerImpl.java:943) at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:605) at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:542) at java.xml/com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:889) at java.xml/com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:825) at java.xml/com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141) at java.xml/com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(DOMParser.java:247) at java.xml/com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:342) at java.xml/javax.xml.parsers.DocumentBuilder.parse(DocumentBuilder.java:122) at kz.greetgo.md_reader.util.MdUtil.xmlTextToDoc(MdUtil.java:71) ... 48 more