Java REST jako Kafka Producer

0

Cześć,
dostałem zadanie, które polega na wysyłaniu wiadomości z web serwisu do topicu w kafce (jestem juniorem, o ile w ogóle).
Udało się wyklikać podstawową funkcjonalność - działa. W topicu pojawia się wiadomość.
Problem w tym, że zanim dostanę responsa mijają 2 sekundy.
Pierwsza myśl - spoko, trzeba poprawić performence. Tylko jak?
Dlatego przychodzę z prośbą o pomoc, ponieważ nie wiem nawet z jakiej strony ugryźć temat.
Moje pytania / wątpliwości:

  • Chyba nie powinienem otwierać i zamykać producera w jednej funkcji
  • Kombinowałem ze statycznymi metodami w klasie "SimpleProducer", które odpowiednio utworzą lub zwrócą istniejącą instancję Producera, ale to raczej nie wpłynęło na wydajność.
  • Proszę o wskazówki jak poradzić sobie z designem takiego resta.
    Używam Jersey'a, a moim kontenerem apki jest OpenLiberty. Poniżej zamieszczam fragment kodu.

Funkcja przyjmuje POST'em skromnego json'a, zmienia go na stringa i wpisuje do topica.

@POST
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public Model getInfo(Model model) throws JsonProcessingException {

    	if(producer == null)
    		producer = (KafkaProducer<String, String>) KafkaProducerExample.createProducer();
    	else
    		producer = (KafkaProducer<String, String>) KafkaProducerExample.getProducer();
        
        ObjectMapper mapper = new ObjectMapper();
        mapper.enable(SerializationFeature.INDENT_OUTPUT);
        String json = mapper.writeValueAsString(model);
        
        ProducerRecord<String, String> record = new ProducerRecord<String, String>("topic", json);
		
		// send message - asynchronous
		producer.send(record);
		
		// message produced and pushed to send method
		producer.flush();
		
		// close producer
		producer.close();
    	
    	
        return "OK";
    }
0

Jak szybko powinno się przetwarzać i co konkretnie przetwarzać, żeby było "dobrze" ?

Piszesz, "Problem w tym, że zanim dostanę responsa mijają 2 sekundy." response skąd?

  1. Client --> REST ---> Kafka , klient czeka 2 sekundy na zakończenie wywołania RESTa ?

czy

  1. Po drugiej stronie coś bierze komunikat z Kafki i po 2 sekundach przesyła Ci odpowiedź?
0

Po 2 sekundach dostaję "OK" w postmanie i po takim czasie pojawia się komunikat w Kafce.
Wydaje mi się, że publikowanie do Kafki powinno być w granicach 50ms.

0
esy_floresy napisał(a):

Po 2 sekundach dostaję "OK" w postmanie i po takim czasie pojawia się komunikat w Kafce.

Rozbij ten czas na mniejsze bloki i zobacz, która część jest najdłuższa i tę optymalizuj. Czy może już to zrobiłeś i doszedłeś do wniosku, że to nie sieć i nie czekanie na cpu i nie coś innego ?

Która z operacji zajmuje najwięcej czasu?

0

Czeli tę jedną funkcję rozbić na kilka mniejszych?
Czy użyć jakiegoś narzędzia do testowania? Jeśli tak to czy polecasz jakieś?

Tak na chłopski rozum wydaje mi się, że to jest problem z otwieraniem i zamykaniem producera z każdym requestem. Stąd pomysł na statycznego producera, bo przecież on nie zmienia swoich propertisów. Ale to nie za bardzo pomogło.
Zakładam też, że istnieją "dobre praktyki" w takich sytuacjach, których pewnie nie stosuję i chciałem o nie zapytać.

Wątpię też, że to problem samego parsowania jsona do stringa.

0
esy_floresy napisał(a):

Czeli tę jedną funkcję rozbić na kilka mniejszych?

Samo rozbicie nic Ci nie da, bo potrzebujesz zmierzyć ile czasu idzie na wykonanie poszczególnych operacji.

Czy użyć jakiegoś narzędzia do testowania? Jeśli tak to czy polecasz jakieś?

Masz tak prosty kod, że możesz wypluwać timestamp z dokładnością do milisekund przed wejściem do metody, po wyjściu i przed wywołaniem każdej instrukcji z tej metody.
Zwykłe System.out.println bieżącego czasu na konsolę :-)

Co o narzędzi, to możesz rozpoznać temat "java profilers".

Obstawiam, że flush() blokuje.

0
esy_floresy napisał(a):

Cześć,
dostałem zadanie, które polega na wysyłaniu wiadomości z web serwisu do topicu w kafce (jestem juniorem, o ile w ogóle).
Udało się wyklikać podstawową funkcjonalność - działa. W topicu pojawia się wiadomość.
Problem w tym, że zanim dostanę responsa mijają 2 sekundy.
Pierwsza myśl - spoko, trzeba poprawić performence. Tylko jak?

Kafka ma dobry performence. To o czym mówisz to słabe latency.
Kafka jest zaprojektowana tak, żeby mieć dobry performence kosztem złego latency.

3

Nie no przecież to co tam masz to dramat :) Masz tu niejako stateless service restowy, ale nie wiedzieć czemu przy każdym requeście robisz:

  • tworzenie object mappera
  • otwieranie producera do kafki
  • zamykanie producera

To wszystko jest 100 razy cięższe niż to co masz faktycznie zrobić, czyli przygotować payload dla kafki i wysłac! Czemu object mapper i producer dla kafki nie są elementami jakiegoś singletonowego serwisu którego cykl życia jest taki sam jak cykl życia aplikacji?

0

Będzie wolno i już chyba wiem czemu ;-)

Wątek obsługujący żądanie do REST:

	producer.send(request.data); // send async - powinno być szybko
	producer.flush(); 		       // czekamy na wysyłkę do kafi, więc dupa z asynchroniczności 
```	
	
Żeby to było szybkie, to flush powinien być wykonywany per ileś tam requestów.  

Możesz zwracać OK po producer.send(), a flusha robić w innym wątku, ale... istnieje ryzyko utraty zbuforowanych komunikatów. 

Jak to ma być szybkie i niezawodne, to potrzebujesz zrobić własny protokół (nie w sensie technicznym, a logicznym) między klientem a Twoim systemem. 

Client: Send REQ  (leci REST Request, wrzucasz do kafki asynchronicznie, zwracasz OK, gdzieś tam osobno robisz flusha na producencie)
Server: REQ.ACK (jak się uda wysłać komunikat do kafi, to leci ACK) 
Server: RES (jak uda się przetworzyć wiadomość to leci response do klienta jakimś innym kanałem)
Client: RES.ACK  (klient wysyła potwierdzenie otrzymania wiadomości do serwera)

Możesz sobie taki protokół  dowolnie rozbudowywać...
0

Zgodnie z sugestiami wyrzuciłem tworzenie obiektów producera i objectmappera do singletonów.
Wyrzuciłem też z kodu flusha - i to znacznie przyspieszyło. Prawdę mówiąc chyba źle skumałem tę funkcję (flush), bo myślałem, że bez niej wiadomości nie trafią do kafki.
Dzięki za słowa krytyki, teraz przynajmniej mogę zawęzić dalszy research.

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