4

I have an application that gets messages from Kafka and calls a target system to update a legacy Oracle DB.

I want to enable a scenario where if the target system is down, to leave the messages on Kafka bus and not process them for a given period of time. I was thinking of some Circuit-breaker Hystrix-based solution, but I can't find any mechanism to tell Spring Cloud Stream to "stop" the event listening. The only other alternative I can think of is if the circuit breaker is open, to transfer these messages to an error/reprocess topic, but that sounds like an anti-pattern to me. I should be able to just pause the system from handling events, that's the whole advantage of pub/sub in a micro services app.

Any help would be appriciated.

odedia
  • 931
  • 2
  • 11
  • 27

1 Answers1

2

One solution is to auto wire the application context.

@Autowired
private ConfigurableApplicationContext context;

You can stop() and start() the context.

You should not call stop() on the thread that invokes the @StreamListener though, or the stop will be delayed (because the container will wait for that thread to exit for 5 seconds by default - with a Rabbit binder at least).

Of course, you will need some kind of out-of-band mechanism to restart - perhaps JMX or a separate application context listening on some kind of control topic.

Gary Russell
  • 166,535
  • 14
  • 146
  • 179
  • Great idea! I'll give it a try. My guess is this won't be a full-featured circuit breaker solution because I'm guessing stopping the context stops the entire application, but it's a good starting point. – odedia Sep 20 '16 at 19:51
  • This works great. Once I reach a certain threshold of errors, I am stopping the context and go into a simple while loop to test if the server is up or not (with 30 seconds internal). Once the server is up, I just call context.start() again. So there's not even a need for JMX or anything, the process is kind of self-healing in this scenario, all the while messages continue to queue up in Kafka. Naturally I can't use any Spring features in the ping method but that's ok, since it is really straightforward. Thanks again! – odedia Sep 20 '16 at 21:12
  • See [this answer](https://stackoverflow.com/questions/58795176/stop-consume-message-for-stream-listener) for a solution to stop/start individual bindings instead of the entire app context. – Gary Russell May 20 '20 at 21:32