strzelanie do 2 tys endpointów

0

Hej,

potrzebuję uderzać do ok 2000 endpointów. Każdy z nich zwraca te same dane, ok 30 wartości pewnych parametrów. Większość wartości parametrów chciałbym uzyskiwać co 30 max 60 sekund. Kilka z nich co 1sek. Taki kolektor danych z moich urządzeń.

  1. Zastanawiam się czy job ( @Schedule ) lub kilka jobów ( w zależności od interwału ) + @Async metoda uderzająca na poszczególne końcówki "odpowiednio" to dobry pomysł? Odpowiednio, mam na myśli jakiś thread pool - tutaj jeszcze dokładnie nie wiem co i jak ?

  2. Użycie Prometeusza (https://prometheus.io/), skonfigurowanie pliku konfiguracyjnego yml na 2000 endpointów i puszczenie bestii w ruch. Tutaj jednak chciałbym dane pchać dalej do np. postgresa.

proszę o Wasze przemyślenia w tym tasku, sugestie, etc...

0

Jak potrzebujesz te dane ciągle to może lepiej użyć jakiegoś socketa/websocketa zamiast RESTa?

0

nie wiem jeszcze czy będę miał taką możliwość. Urządzenia są podpięte pod moduły internetowe ( jakieś, nie wiem na ten moment konkretów ).

4

Przetestuj. Zrób joba walnij reaktywnym web clientem w te 2000 endpointów i zobacz co się położy.
Jeżeli ty tworzesz urządzenia to pytanie czy lepiej nie byłoby odwrócić logiki aby to urządzenia wysyłały dane do serwera jak coś sie np zmieni.

0
Schadoow napisał(a):

Jeżeli ty tworzesz urządzenia to pytanie czy lepiej nie byłoby odwrócić logiki aby to urządzenia wysyłały dane do serwera jak coś sie np zmieni.

Dokładnie tak, odpytywanie 2000 endopitów to będzie jakaś maskra - potrzebujesz 2000 wątków, bo jak ci jeden endpoit przytnie ta całość siądzie.
Dużo tez zależy jakie to dane. Co z nimi chcesz zrobić. Czy możesz je agregować, czy chcesz trzymać w wersji surowej.

0

Może najprościej jak się da - task scheduler. Lecisz sobie paczkami (np. 100 endpointow, których czas na odpytanie minął) i wykonujesz dla każdej paczki zrownoleglone requesty, wyniki zapisujesz, przesuwasz daty kolejnego odpytania lub tworzysz nowe taski. Alternatywnie zamiast paczek większa liczba workerów. W obu podejściach potrzebujesz zrobić sobie pulę wątków.

Do tego potrzebny mechanizm obsługi błędów (np. retry, cb) i jakieś limitowanie, żeby nie zabić tych urządzeń.

0

ja nie tworzę tych urządzeń.
dane potrzebuję surowo wrzucić do bazy z oznaczeniem skąd one pochodzą ( id urządzenia ) oraz opatrzyć je timestampem.
Będę rozmawiał z gościem co tworzy te urządzenia, jednak wiem, że on coś kręci nosem na takie podejście.

0

a nie da sie zrobić jakiegoś agregatu, typu ze jedno urządzenie na danym obszarze to master ;) i odpytuje pozostałe i wysyła całość

0

dyskusja otwarta, jednak na ten moment najprawdopodobniej twórca tych urządzeń i sterownika, emitera, dorobi jakiś rest

0

Niekoniecznie potrzeba 2000 wątków, można mniej wątków i wtedy na jeden wątek przypada:

x = liczba endopointów / liczba wątków

Jeżeli jakiś endpoint przymuli to nie zablokuje wszystkiego tylko max x-1

0

pomijając temat wysyłania danych w odwrotna stronę albo socketów, jeśli musisz zostać przy pobieraniu ich z endpointów to może ci się przydać np. hystrix skoro korzystasz z spring boota, żeby nie zapchać wszystkich wątków i mieć jakiś mechanizm fault-tolerance

możesz też rozbić to na kilka instancji i każda będzie odpowiadać za jakąś część całej puli np 4x po 500 endpointów, które będą sobie pobierać endpointy z jakiegoś config serwera; co po części pozwoli uniknąć problemu z zapchaniem wszystkich wątków; ale najpierw odpalilbym chyba jakis test wydajnościowy żeby niepotrzebnie nie komplikować. a nuż jedna instancją z jakimś threadpoolem wystarczy

0

prometeusz wydaje się super kombajnem pod takie rzeczy.

dimensional data model, flexible query language, efficient time series database

dziurę mam jakby to pchać do relacyjnej bazy.

0

Zobacz sobie jeszcze Druida, może podejdzie. Jak dla mnie, to bez kilku POC-ów tutaj się nie obędzie.

https://druid.apache.org/docs/latest/design/index.html
https://hazelcast.com/glossary/kappa-architecture/

1

Gdybys nie musial ty odpytywac tych urzadzen to moglyby one same wysylac wszystko na jakis system kolejkowy chocby rabbitmq/kafka do tego odpalasz powiedzmy x10 consumer i niech sobie dane miela bo i tak za pomoca rest nie bedziesz mial tego real-time wystarczy zeby msg z rabbit-a mial wszystkie info jesli wazna jest kolejnosc tak zeby consumer wiedzial co i jak zapisac.
Do tego jesli cos pojdzie nie tak wrzucasz znowu msg do kolejki z jakims max retry po ktorym po prostu mozesz cos zrobic z msg ktore nie potrafisz przetworzyc.
Mysle ze dla typa zamiast napisac jakis REST ktory ty bedziesz odpytywal moze tak samo napisac jakis system ktory bedzie to wszystko wysylal do kolejki co jakis czas.
Do tego kazde urzadzenie mogloby miec swoja queue wtedy masz 1 consumer per urzadzenie no chyba ze cos zle zrozumialem

1
Tomek Pycia napisał(a):

Dokładnie tak, odpytywanie 2000 endopitów to będzie jakaś maskra - potrzebujesz 2000 wątków, bo jak ci jeden endpoit przytnie ta całość siądzie.
Dużo tez zależy jakie to dane. Co z nimi chcesz zrobić. Czy możesz je agregować, czy chcesz trzymać w wersji surowej.

john_doe napisał(a):

ja nie tworzę tych urządzeń.
dane potrzebuję surowo wrzucić do bazy z oznaczeniem skąd one pochodzą ( id urządzenia ) oraz opatrzyć je timestampem.
Będę rozmawiał z gościem co tworzy te urządzenia, jednak wiem, że on coś kręci nosem na takie podejście.

Porady w tym wątku dotyczą głownie możliwości implementacji. Ja przypomnę o głębokim projekcie "niezawodnościowym".
Co, gdy coś padnie, co od tego zależy, ile można przeżyć, kiedy alarmować, jaka awaria "zakaża" inne obszary danych itd.

Przy niezawodności jednej sztuki 0,9999 prawdopodobieństwo, ze wszystko globalnie jest OK jest ... ktoś się spodziewał? 0,13519

Będę rozmawiał z gościem co tworzy te urządzenia, jednak wiem, że on coś kręci nosem na takie podejście.

Zgubiłem się w wątku. "to podejście" tzn?

1
marcio napisał(a):

Gdybys nie musial ty odpytywac tych urzadzen to moglyby one same wysylac wszystko na jakis system kolejkowy chocby rabbitmq/kafka
...
Do tego jesli cos pojdzie nie tak wrzucasz znowu msg do kolejki z jakims max retry po ktorym po prostu mozesz cos zrobic z msg ktore nie potrafisz przetworzyc.
Mysle ze dla typa zamiast napisac jakis REST ktory ty bedziesz odpytywal moze tak samo napisac jakis system ktory bedzie to wszystko wysylal do kolejki co jakis czas.

To może być całkiem fajny pomysł.

Dla hardcorów C/C++ jest biblioteka pub/sub ZeroMQ. W programowaniu urządzeń jest też lubiany protokół MQTT. Do "naszych" brokerów są pluginy/drivery, które sie z tym złączą.

Z "dużych" brokerów chyba dobrą pozycję ma Rabbit MQ, choć nie pisany w Javie

0

Jeśli koniecznie ma być to REST to może http://postgrest.org? "TLDR; subsecond response times for up to 2000 requests/sec on Heroku free tier."
albo - scylladb.com/2017/11/15/smf-fastest-rpc/
albo - dzone.com/articles/keeping-the-web-api-layer-in-kafka-with-a-rest-pro
to raczej jest strimowanie danych, a endpoint może sobie być przypisany do konkretnego urządzenia

0

Prosta apka typu Spring Boot raczej się do tego nie nada bo 2000 x strzał/30 sekund na jednej VMce może być ciężko ogarnąć. Zakładając, że będziesz miał 24 wątki, czas zajętości per request sekundę to ci apka zacznie się zapychać.

Sprawdź raczej coś skalowalnego, np. Apache Airflow.

Możesz też użyć wspomnianej Kafki + Kafka Streams, ale odwrócić normalny flow, tj.

  1. Masz 2000 URLi
  2. Jakiś producent co 30 sekund wrzuca na Kafkę message z timestampem i URLem do którego trzeba podbić
  3. Wystawiasz N maszyn na których działają instancje Kafka Streams i to one wołają RESTy oraz zapisują do bazy

Takie rozwiązanie będzie lepsze bo ilość maszyn z pkt. 3 można łatwo zwiększyć.

1

REST jak rozumiem będzie wykorzystywać HTTP. To ciągnie za sobą TCP, a to znowu Handshake za każdym razem.

Jeżeli to są odczyty tylko, to może lepiej byłoby gdyby to był protokół binarny? Może nawet latać po UDP z wykorzystaniem sumy kontrolnej.

Najlepiej gdybyś miał możliwość postawienia systemu rozproszonego. Kilku agentów sczytujących po UDP dane i przekazujące po REST wiele odczytów już oznaczonych do głównego serwera.

1 użytkowników online, w tym zalogowanych: 0, gości: 1