|
Совет по архитектуре Spring MVC
|
|||
---|---|---|---|
#18+
Добрый день! Пишу бэкенд сервера для работы с кассами. Стек технологий Java/Spring Boot/MySql В качестве БД взял MySQL (ибо фронт уже на нем). По сути сервер должен принимать задания в виде json, а кассы эти задания должны выполнять. Внутри кассы нет очереди и работают они только в одном потоке, грубо говоря так: Код: java 1. 2. 3. 4.
Идея была следующая: храним кассы в таблице devices, задания в таблице tasks. При старте сервера запускаем столько потоков, сколько девайсов в таблице devices. Потоки с определенным периодом делают селект из таблицы с заданиями и поочередно их выполняют. Апи для заданий асинхронное, т.е. снаружи прилетает post запрос, создается запись в таблице tasks и назад клиенту отдается id этого задания. По id задания клиент может отследить прогресс и результат. (GET /task/{id}) В результате получились следующие классы: Контроллеры - спринговые @RestControllerы: DeviceController TaskController Модели - стандартные Entity: Device Task Репозитории - спринговые JpaRepository: DeviceRepository TaskRepository Сервис: DeviceService - спринговый @Service, при инициализации сервис читает из базы список касс и создает на каждую по потоку (экземпляр DeviceWorker) и запускает их. Worker: DeviceWorker - собственно класс наследник thread, который получает и задания из базы и работает с кассой. Каким компонентом спринга должен быть DeviceWorker в данной ситуации, чтобы было удобно инжектить внутрь него репозитории и нормально работали транзакции. Я читал и про спринговые TaskExecutor и про Scheduler, но так и не смог понять как их применить в данной ситуации. Сейчас я передаю экземпляры репозиториев через конструктор из DeviceService при создании воркеров. Но такое ощущение, что это кривое решение и могут быть проблемы с транзакциями(хотя и работает). Репозитории внутри воркера нужны для обновления статуса девайса, таска и записи результата выполнения таска. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.09.2019, 18:53 |
|
Совет по архитектуре Spring MVC
|
|||
---|---|---|---|
#18+
capfreedom228Апи для заданий асинхронное, т.е. снаружи прилетает post запрос, создается запись в таблице tasks игде обоснование нужности асинхронности? ... |
|||
:
Нравится:
Не нравится:
|
|||
26.09.2019, 21:41 |
|
Совет по архитектуре Spring MVC
|
|||
---|---|---|---|
#18+
capfreedom228, Post кто делает? Человек? Тогда вариант без асинхронности - делает задание и вкладка кассы1 висит 15 сек. Вполне допустимо. Надо быстрее, жмакает новую вкладку касса2 и тоже ждет. Вариант асинхронный - 2 веб приложения. Приложение А просто пишет в бд задание. Приложение Б это демон или сервис без ГУИ круглосуточно их выполняет. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.09.2019, 22:00 |
|
Совет по архитектуре Spring MVC
|
|||
---|---|---|---|
#18+
PetroNotC Sharp, Асинхронность нужна, т.к. задания могут выполняться неопределенно долго. И если будет 5 одновременных заданий то последний зависнет больше чем на минуту, а это неприемлимо. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.09.2019, 22:18 |
|
Совет по архитектуре Spring MVC
|
|||
---|---|---|---|
#18+
PetroNotC Sharp, Post из фронта прилетает из браузера. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.09.2019, 22:19 |
|
Совет по архитектуре Spring MVC
|
|||
---|---|---|---|
#18+
capfreedom228PetroNotC Sharp, Асинхронность нужна, т.к. задания могут выполняться неопределенно долго. И если будет 5 одновременных заданий то последний зависнет больше чемн на минуту, а это неприемлимо.контейнер веб сервера при занятом сервлете запускает новый экземпляр. Значит 5 вкладок выполнятся вместе за 15 сек. Проверь ... |
|||
:
Нравится:
Не нравится:
|
|||
26.09.2019, 22:23 |
|
Совет по архитектуре Spring MVC
|
|||
---|---|---|---|
#18+
Дмитрий Мухcapfreedom228, в мире Java нет аналогов Hangfire ?в мире шарпа нет контейнера? https://ru.m.wikipedia.org/wiki/Контейнер_сервлетов ... |
|||
:
Нравится:
Не нравится:
|
|||
26.09.2019, 22:35 |
|
Совет по архитектуре Spring MVC
|
|||
---|---|---|---|
#18+
capfreedom228Каким компонентом спринга должен быть DeviceWorker в данной ситуации, чтобы было удобно инжектить внутрь него репозитории и нормально работали транзакции Я бы попробовал обыкновенный спринговый bean с одним публичным методом и аннотацией Async - почитай про нее. Если кол-во девайсов число постоянное на момент старта, то просто настроить taskexecutor с пулом нужного размера ... |
|||
:
Нравится:
Не нравится:
|
|||
26.09.2019, 22:53 |
|
Совет по архитектуре Spring MVC
|
|||
---|---|---|---|
#18+
PetroNotC Sharpcapfreedom228PetroNotC Sharp, Асинхронность нужна, т.к. задания могут выполняться неопределенно долго. И если будет 5 одновременных заданий то последний зависнет больше чемн на минуту, а это неприемлимо.контейнер веб сервера при занятом сервлете запускает новый экземпляр. Значит 5 вкладок выполнятся вместе за 15 сек. Проверь касса в 1 поток работает ... |
|||
:
Нравится:
Не нравится:
|
|||
26.09.2019, 23:20 |
|
Совет по архитектуре Spring MVC
|
|||
---|---|---|---|
#18+
chpashacapfreedom228Каким компонентом спринга должен быть DeviceWorker в данной ситуации, чтобы было удобно инжектить внутрь него репозитории и нормально работали транзакции Я бы попробовал обыкновенный спринговый bean с одним публичным методом и аннотацией Async - почитай про нее. Если кол-во девайсов число постоянное на момент старта, то просто настроить taskexecutor с пулом нужного размера хотелось иметь возможность добавлять кассы без рестарта ... |
|||
:
Нравится:
Не нравится:
|
|||
26.09.2019, 23:21 |
|
Совет по архитектуре Spring MVC
|
|||
---|---|---|---|
#18+
capfreedom228, Не понял. Касса синглетон или можно сделать Kassa a = new Kassa(settings); Kassa б = new Kassa(settings); ? ... |
|||
:
Нравится:
Не нравится:
|
|||
26.09.2019, 23:24 |
|
Совет по архитектуре Spring MVC
|
|||
---|---|---|---|
#18+
PetroNotC Sharpcapfreedom228, Не понял. Касса синглетон или можно сделать Kassa a = new Kassa(settings); Kassa б = new Kassa(settings); ? сделать можно, но когда ты вызовешь a.open(); то b.open(); - выдаст ошибку подключения. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.09.2019, 23:26 |
|
Совет по архитектуре Spring MVC
|
|||
---|---|---|---|
#18+
capfreedom228выдаст ошибку подключения.то есть нужна асинхронность, но касса категорически однопоточна? Фиктивная нужна? Зачем? ... |
|||
:
Нравится:
Не нравится:
|
|||
26.09.2019, 23:32 |
|
Совет по архитектуре Spring MVC
|
|||
---|---|---|---|
#18+
Чтобы касса не простаивала))))))))? ... |
|||
:
Нравится:
Не нравится:
|
|||
26.09.2019, 23:33 |
|
Совет по архитектуре Spring MVC
|
|||
---|---|---|---|
#18+
chpasha, Выяснили что аннотация не подходит ... |
|||
:
Нравится:
Не нравится:
|
|||
26.09.2019, 23:34 |
|
Совет по архитектуре Spring MVC
|
|||
---|---|---|---|
#18+
PetroNotC SharpЧтобы касса не простаивала))))))))? Такое тз ... |
|||
:
Нравится:
Не нравится:
|
|||
26.09.2019, 23:34 |
|
Совет по архитектуре Spring MVC
|
|||
---|---|---|---|
#18+
capfreedom228PetroNotC SharpЧтобы касса не простаивала))))))))? Такое тзтогда один вариант Второй в 21980326 ... |
|||
:
Нравится:
Не нравится:
|
|||
26.09.2019, 23:37 |
|
Совет по архитектуре Spring MVC
|
|||
---|---|---|---|
#18+
PetroNotC Sharpcapfreedom228выдаст ошибку подключения.то есть нужна асинхронность, но касса категорически однопоточна? Фиктивная нужна? Зачем? Чеки электронные и клиенту нет смысла ждать. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.09.2019, 23:39 |
|
Совет по архитектуре Spring MVC
|
|||
---|---|---|---|
#18+
capfreedom228Чеки электронные и клиенту нет смысла ждать.все хуже. Касса синглетон. Решение выше. Удачи. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.09.2019, 23:46 |
|
Совет по архитектуре Spring MVC
|
|||
---|---|---|---|
#18+
chpashacapfreedom228Каким компонентом спринга должен быть DeviceWorker в данной ситуации, чтобы было удобно инжектить внутрь него репозитории и нормально работали транзакции Я бы попробовал обыкновенный спринговый bean с одним публичным методом и аннотацией Async - почитай про нее. Если кол-во девайсов число постоянное на момент старта, то просто настроить taskexecutor с пулом нужного размера Можно еще лоадбалансер настроить на пару тройку серверов, чтоб уж совсем все было хорошо. ... |
|||
:
Нравится:
Не нравится:
|
|||
27.09.2019, 00:10 |
|
Совет по архитектуре Spring MVC
|
|||
---|---|---|---|
#18+
capfreedom228chpashaпропущено... Я бы попробовал обыкновенный спринговый bean с одним публичным методом и аннотацией Async - почитай про нее. Если кол-во девайсов число постоянное на момент старта, то просто настроить taskexecutor с пулом нужного размера хотелось иметь возможность добавлять кассы без рестарта А параметром номер кассы никак нельзя передать? ... |
|||
:
Нравится:
Не нравится:
|
|||
27.09.2019, 00:12 |
|
Совет по архитектуре Spring MVC
|
|||
---|---|---|---|
#18+
Sergunkacapfreedom228пропущено... хотелось иметь возможность добавлять кассы без рестарта А параметром номер кассы никак нельзя передать? В таске зафиксирован id кассы, т.е. каждый таск предназначен конкретной кассе. ... |
|||
:
Нравится:
Не нравится:
|
|||
27.09.2019, 00:32 |
|
Совет по архитектуре Spring MVC
|
|||
---|---|---|---|
#18+
capfreedom228Sergunkaпропущено... А параметром номер кассы никак нельзя передать? В таске зафиксирован id кассы, т.е. каждый таск предназначен конкретной кассе. Как то уж совсем тупенько. Вот к примеру мой учебный пример на основе пулэкзекьютора написанный пятью годам ранее. Классическая задача Дейкстры - спящий парикмахер https://vyatkins.wordpress.com/2013/12/21/sleeping-barber-problem/ https://github.com/SVyatkin/KafkaSleepingBarberProblem/blob/master/src/main/java/com/sleeping/barber/blockingQueue/BlockingQueueSleepingBarbersPoolExecutor.java Нет там большой проблемы передать параметр Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34.
Что там за таск такой? Код покажи? ... |
|||
:
Нравится:
Не нравится:
|
|||
27.09.2019, 04:33 |
|
Совет по архитектуре Spring MVC
|
|||
---|---|---|---|
#18+
capfreedom228Идея была следующая: храним кассы в таблице devices, задания в таблице tasks. При старте сервера запускаем столько потоков, сколько девайсов в таблице devices. Потоки с определенным периодом делают селект из таблицы с заданиями и поочередно их выполняют. Апи для заданий асинхронное, т.е. снаружи прилетает post запрос, создается запись в таблице tasks и назад клиенту отдается id этого задания. По id задания клиент может отследить прогресс и результат. (GET /task/{id}) ИМХО не делать брокер/очередь сообщений на БД, а воспользоваться соответствующим инструментом (MQ, Kafka и т.д.) Результат отправлять так же по тому же брокеру сообщений. Связь можно сделать, по CorellationID. Создается в сессии контролера и там же храниться, нужен чтобы получить соответствующий ответ. ... |
|||
:
Нравится:
Не нравится:
|
|||
27.09.2019, 07:00 |
|
|
start [/forum/topic.php?fid=59&msg=39867630&tid=2121100]: |
0ms |
get settings: |
11ms |
get forum list: |
14ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
180ms |
get topic data: |
10ms |
get forum data: |
3ms |
get page messages: |
53ms |
get tp. blocked users: |
1ms |
others: | 14ms |
total: | 294ms |
0 / 0 |