Гость
Форумы / Java [игнор отключен] [закрыт для гостей] / Совет по архитектуре Spring MVC / 25 сообщений из 69, страница 1 из 3
26.09.2019, 18:53
    #39867501
capfreedom228
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Совет по архитектуре Spring MVC
Добрый день!
Пишу бэкенд сервера для работы с кассами.
Стек технологий Java/Spring Boot/MySql
В качестве БД взял MySQL (ибо фронт уже на нем).
По сути сервер должен принимать задания в виде json, а кассы эти задания должны выполнять.
Внутри кассы нет очереди и работают они только в одном потоке, грубо говоря так:
Код: java
1.
2.
3.
4.
Kassa a = new Kassa(settings);
a.open(); // в этот момент больше никто к кассе не может подключиться, open может выполняться несколько секунд
Result r = a.processTask("some json"); // может выполняться несколько секунд
a.close();



Идея была следующая: храним кассы в таблице 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 при создании воркеров. Но такое ощущение, что это кривое решение и могут быть проблемы с транзакциями(хотя и работает).
Репозитории внутри воркера нужны для обновления статуса девайса, таска и записи результата выполнения таска.
...
Рейтинг: 0 / 0
26.09.2019, 21:41
    #39867558
PetroNotC Sharp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Совет по архитектуре Spring MVC
capfreedom228Апи для заданий асинхронное, т.е. снаружи прилетает post запрос, создается запись в таблице tasks игде обоснование нужности асинхронности?
...
Рейтинг: 0 / 0
26.09.2019, 22:00
    #39867564
PetroNotC Sharp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Совет по архитектуре Spring MVC
capfreedom228,
Post кто делает? Человек?
Тогда вариант без асинхронности - делает задание и вкладка кассы1 висит 15 сек. Вполне допустимо.
Надо быстрее, жмакает новую вкладку касса2 и тоже ждет.
Вариант асинхронный - 2 веб приложения.
Приложение А просто пишет в бд задание.
Приложение Б это демон или сервис без ГУИ круглосуточно их выполняет.
...
Рейтинг: 0 / 0
26.09.2019, 22:18
    #39867568
capfreedom228
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Совет по архитектуре Spring MVC
PetroNotC Sharp,

Асинхронность нужна, т.к. задания могут выполняться неопределенно долго. И если будет 5 одновременных заданий то последний зависнет больше чем на минуту, а это неприемлимо.
...
Рейтинг: 0 / 0
26.09.2019, 22:19
    #39867569
capfreedom228
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Совет по архитектуре Spring MVC
PetroNotC Sharp,

Post из фронта прилетает из браузера.
...
Рейтинг: 0 / 0
26.09.2019, 22:23
    #39867574
PetroNotC Sharp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Совет по архитектуре Spring MVC
capfreedom228PetroNotC Sharp,

Асинхронность нужна, т.к. задания могут выполняться неопределенно долго. И если будет 5 одновременных заданий то последний зависнет больше чемн на минуту, а это неприемлимо.контейнер веб сервера при занятом сервлете запускает новый экземпляр.
Значит 5 вкладок выполнятся вместе за 15 сек.
Проверь
...
Рейтинг: 0 / 0
26.09.2019, 22:26
    #39867578
Дмитрий Мух
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Совет по архитектуре Spring MVC
capfreedom228,

в мире Java нет аналогов Hangfire ?
...
Рейтинг: 0 / 0
26.09.2019, 22:35
    #39867588
PetroNotC Sharp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Совет по архитектуре Spring MVC
Дмитрий Мухcapfreedom228,

в мире Java нет аналогов Hangfire ?в мире шарпа нет контейнера?
https://ru.m.wikipedia.org/wiki/Контейнер_сервлетов
...
Рейтинг: 0 / 0
26.09.2019, 22:53
    #39867594
chpasha
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Совет по архитектуре Spring MVC
capfreedom228Каким компонентом спринга должен быть DeviceWorker в данной ситуации, чтобы было удобно инжектить внутрь него репозитории и нормально работали транзакции
Я бы попробовал обыкновенный спринговый bean с одним публичным методом и аннотацией Async - почитай про нее. Если кол-во девайсов число постоянное на момент старта, то просто настроить taskexecutor с пулом нужного размера
...
Рейтинг: 0 / 0
26.09.2019, 23:20
    #39867614
capfreedom228
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Совет по архитектуре Spring MVC
PetroNotC Sharpcapfreedom228PetroNotC Sharp,

Асинхронность нужна, т.к. задания могут выполняться неопределенно долго. И если будет 5 одновременных заданий то последний зависнет больше чемн на минуту, а это неприемлимо.контейнер веб сервера при занятом сервлете запускает новый экземпляр.
Значит 5 вкладок выполнятся вместе за 15 сек.
Проверь

касса в 1 поток работает
...
Рейтинг: 0 / 0
26.09.2019, 23:21
    #39867615
capfreedom228
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Совет по архитектуре Spring MVC
chpashacapfreedom228Каким компонентом спринга должен быть DeviceWorker в данной ситуации, чтобы было удобно инжектить внутрь него репозитории и нормально работали транзакции
Я бы попробовал обыкновенный спринговый bean с одним публичным методом и аннотацией Async - почитай про нее. Если кол-во девайсов число постоянное на момент старта, то просто настроить taskexecutor с пулом нужного размера

хотелось иметь возможность добавлять кассы без рестарта
...
Рейтинг: 0 / 0
26.09.2019, 23:24
    #39867618
PetroNotC Sharp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Совет по архитектуре Spring MVC
capfreedom228,
Не понял.
Касса синглетон или можно сделать
Kassa a = new Kassa(settings);
Kassa б = new Kassa(settings);
?
...
Рейтинг: 0 / 0
26.09.2019, 23:26
    #39867619
capfreedom228
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Совет по архитектуре Spring MVC
PetroNotC Sharpcapfreedom228,
Не понял.
Касса синглетон или можно сделать
Kassa a = new Kassa(settings);
Kassa б = new Kassa(settings);
?

сделать можно, но когда ты вызовешь a.open(); то b.open(); - выдаст ошибку подключения.
...
Рейтинг: 0 / 0
26.09.2019, 23:32
    #39867623
PetroNotC Sharp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Совет по архитектуре Spring MVC
capfreedom228выдаст ошибку подключения.то есть нужна асинхронность, но касса категорически однопоточна?
Фиктивная нужна? Зачем?
...
Рейтинг: 0 / 0
26.09.2019, 23:33
    #39867624
PetroNotC Sharp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Совет по архитектуре Spring MVC
Чтобы касса не простаивала))))))))?
...
Рейтинг: 0 / 0
26.09.2019, 23:34
    #39867625
PetroNotC Sharp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Совет по архитектуре Spring MVC
chpasha,
Выяснили что аннотация не подходит
...
Рейтинг: 0 / 0
26.09.2019, 23:34
    #39867626
capfreedom228
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Совет по архитектуре Spring MVC
PetroNotC SharpЧтобы касса не простаивала))))))))?

Такое тз
...
Рейтинг: 0 / 0
26.09.2019, 23:37
    #39867628
PetroNotC Sharp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Совет по архитектуре Spring MVC
capfreedom228PetroNotC SharpЧтобы касса не простаивала))))))))?

Такое тзтогда один вариант
Второй в 21980326
...
Рейтинг: 0 / 0
26.09.2019, 23:39
    #39867630
capfreedom228
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Совет по архитектуре Spring MVC
PetroNotC Sharpcapfreedom228выдаст ошибку подключения.то есть нужна асинхронность, но касса категорически однопоточна?
Фиктивная нужна? Зачем?

Чеки электронные и клиенту нет смысла ждать.
...
Рейтинг: 0 / 0
26.09.2019, 23:46
    #39867631
PetroNotC Sharp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Совет по архитектуре Spring MVC
capfreedom228Чеки электронные и клиенту нет смысла ждать.все хуже. Касса синглетон.
Решение выше. Удачи.
...
Рейтинг: 0 / 0
27.09.2019, 00:10
    #39867638
Sergunka
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Совет по архитектуре Spring MVC
chpashacapfreedom228Каким компонентом спринга должен быть DeviceWorker в данной ситуации, чтобы было удобно инжектить внутрь него репозитории и нормально работали транзакции
Я бы попробовал обыкновенный спринговый bean с одним публичным методом и аннотацией Async - почитай про нее. Если кол-во девайсов число постоянное на момент старта, то просто настроить taskexecutor с пулом нужного размера

Можно еще лоадбалансер настроить на пару тройку серверов, чтоб уж совсем все было хорошо.
...
Рейтинг: 0 / 0
27.09.2019, 00:12
    #39867639
Sergunka
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Совет по архитектуре Spring MVC
capfreedom228chpashaпропущено...

Я бы попробовал обыкновенный спринговый bean с одним публичным методом и аннотацией Async - почитай про нее. Если кол-во девайсов число постоянное на момент старта, то просто настроить taskexecutor с пулом нужного размера

хотелось иметь возможность добавлять кассы без рестарта

А параметром номер кассы никак нельзя передать?
...
Рейтинг: 0 / 0
27.09.2019, 00:32
    #39867641
capfreedom228
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Совет по архитектуре Spring MVC
Sergunkacapfreedom228пропущено...


хотелось иметь возможность добавлять кассы без рестарта

А параметром номер кассы никак нельзя передать?

В таске зафиксирован id кассы, т.е. каждый таск предназначен конкретной кассе.
...
Рейтинг: 0 / 0
27.09.2019, 04:33
    #39867664
Sergunka
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Совет по архитектуре Spring MVC
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.
	class Barber extends Thread {
		BlockingQueue<Integer> queue = null;
		private String name;

		public Barber(BlockingQueue<Integer> queue, String name) {
			this.name = name;
			this.queue = queue;
		}

		public void run() {
			while (true) { // runs in an infinite loop

				try {
					Integer i = this.queue.poll(OFFICE_CLOSE,
							TimeUnit.MILLISECONDS);
					if (i == null)
						break; // barber slept for long time (OFFICE_CLOSE) no
								// more clients in the queue - close office
					this.cutHair(i); // cutting...

				} catch (InterruptedException e) {
				}
			}
		}

		public void cutHair(Integer i) {
			System.out.println("The barber " + this.name
					+ " is cutting hair for customer #" + i);
			try {
				sleep(BARBER_TIME);
			} catch (InterruptedException ex) {
			}
		}
	}



Что там за таск такой? Код покажи?
...
Рейтинг: 0 / 0
27.09.2019, 07:00
    #39867670
mad_nazgul
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Совет по архитектуре Spring MVC
capfreedom228Идея была следующая: храним кассы в таблице devices, задания в таблице tasks.
При старте сервера запускаем столько потоков, сколько девайсов в таблице devices.
Потоки с определенным периодом делают селект из таблицы с заданиями и поочередно их выполняют.
Апи для заданий асинхронное, т.е. снаружи прилетает post запрос, создается запись в таблице tasks и назад клиенту отдается id этого задания.
По id задания клиент может отследить прогресс и результат. (GET /task/{id})


ИМХО не делать брокер/очередь сообщений на БД, а воспользоваться соответствующим инструментом (MQ, Kafka и т.д.)
Результат отправлять так же по тому же брокеру сообщений.
Связь можно сделать, по CorellationID. Создается в сессии контролера и там же храниться, нужен чтобы получить соответствующий ответ.
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / Совет по архитектуре Spring MVC / 25 сообщений из 69, страница 1 из 3
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]