Disabling Spring Cloud Bus still ends up starting RabbitMQ - spring-boot

I am using Spring boot 2.2.9.RELEASE and Spring Cloud Hoxton.SR7. I am using Spring Cloud Bus to signal all my containers in a docker swarm stack and when deployed in production with a running RabbitMQ cluster things work perfectly!
I am using the RabbitMQ implementation via the spring-cloud-starter-bus-amqp Spring Boot starter. We occasionally run tests without needing the bus. There is a spring boot flag for this:
spring.cloud.bus.enabled=false
this disables the bus, but rabbitMQ still starts, and spits out connection refused errors. I had to also add:
rabbitmq.autoStarting=false
I tried fussing around with disabling RabbitMQ's auto configuration, but it seems there is a RabbitAutoConfiguration class that implies it is a SB autoconfig class, but in actual fact it is a normal SB config class.
Is there a cleaner way to disable the Cloud Bus that also prevents RabbitMQ from starting?

You just need to include the spring-cloud-stream-test-support jar in your test scope. This jar includes binders that will override and replace the default binders. These test binders will not actually connect to the resources in the background.
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream-test-support</artifactId>
<version>${spring.cloud.stream.version}</version>
<scope>test</scope>
</dependency>

Related

Intercept route in Apache camel parallel

I need to save the details of my route in DB including the details between each patterns in camel route . I planned to use intercept (which will be defined in my CamelContext so all routes will in the context will be intercepted before each pattern process) to save details in DB.
But as I understood this will impact my applications performance as routes will be intercepted before each pattern processing.Is there any way to make intercept in camel to process parallel?
As another way I thought about using WireTap pattern in apache camel but I can't define it in context level So while writing every route I would need to explicitly write the WireTap pattern.This is little bit hectic as I am trying to reduce the complexity of developers who write the routes.As they only need to write routes and the other things that are needed will be done via what I defined in the CamelContext .Is there any way to write WireTap at context level and not in route level?.
Or some one please help with any other way which will help me to make this possible
Thanks in advance
Intercept with seda or try global OnCompletion
You could use intercept to call separate seda endpoint which is basically fire and forget asynchronous version of direct.
You could also try using global OnCompletion to get message history from complete exchanges.
But to be honest all this will affect performance and increase complexity for developers.
JMX
More conventional way to monitor routes would be to use jmx or jmx through jolokia. This allows you to monitor your camel application(s) using external application that could even access the application remotely. For example your spring application(s) might run in container(s) and so you could have another container to monitor all these applications and write data to your database.
Through jmx you could call your route to dumpRouteAsXml() to form a route diagram you mentioned here then you could poll dumpRouteStatsAsXml(true, true) periodically to get bunch of information about the route and each of its endpoint like endpoint id and exchangesCompleted that you can use in your database.
This doesn't require any changes to routes, but needs one to provide JVM some parameters to enable JVM, possibly some authentication and SSL configurations for security depending on the environment and some camel dependencies. Much of this can be done with project templates, docker images however.
Enabling JMX with JVM parameters
Disabling enabling camel-jmx
Managing Camel Routes With JMX APIs
JConsole - GUI application for JMX
Maven dependencies
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-management</artifactId>
<version>${camel.version}</version>
</dependency>
<!-- For Camel 3.x Spring boot -->
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-jmx-starter</artifactId>
<version>${camel.version}</version>
</dependency>
<!-- For Camel 2.x Spring boot -->
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-jmx-starter</artifactId>
<version>${camel.version}</version>
</dependency>

Micrometer KafkaConsumerMetrics present when running locally but not when deployed

When I run locally I can see that kafka.consumer. are being collected. While when I deploy my service - I see that those metrics are not present.
I use kafka version 1.11.0, java 11 and Spring Boot 2.2.
How I can determine what is missing?
In case anyone has this issue. I've had to explicitly add:
spring.jmx.enabled=true
It is needed since Kafka publishes data to jmx, and Micrometer reads it from there. By default jmx is disabled starting from Spring Boot 2.2.
It worked locally because IDEA added spring.jmx.enabled=true flag under the covers.

Configure Kafka consumer acknowledgement mode for Spring Boot Kafka project

I'm using Spring Boot version 1.5.2.RELEASE along with Spring Kafka version 1.1.2.RELEASE.
Via the application.properties file I do see available options (spring.kafka.consumer.*) to configure Kafka Consumer.
What I'm not able to find though is a way to configure the acknowledgement mode.
spring.kafka.listener.ack-mode=
You can use Spring Cloud Stream Kafka Binder to streaming messages. In that case
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream-binder-kafka</artifactId>
</dependency>
and configure consumer like this.
spring.cloud.stream.kafka.bindings.<channelName>.consumer..
and producer like this
spring.cloud.stream.kafka.bindings.<channelName>.producer..
to more detail follow this or this video

Spring cloud bus - rabbitmq unavailability marks the instance DOWN

I use spring cloud config bus (rabbitmq) in my micro-service. Only purpose for me to use rabbitmq in my microservice is spring cloud bus... I have 2 questions below.
When I was experimenting, I found that spring expects rabbitmq to be UP and running during application start. Which is contrary to what Spring cloud evangelises... (Circuit breakers...) To be fair, even service discovery is not expected to be up and running before starting an application. Is there any sensible reason behind this...?
Say, I start my application when rabbitmq is up and running. For some reason, rabbitmq goes down... What I should be losing is just my ability to work with rabbitmq... instead, /health endpoint responds back as DOWN for my micro-service. Any eureka instance listening to heart beats from my micro-service is also marking the instance as down. Any reasons for doing this...?
To my knowledge, this is against the circuit breaker pattern that spring cloud has evangelised.
I personally feel that spring cloud config bus is not an important feature to mark an application as down...
Is there any alternatives to tell my spring boot micro-service that connection to rabbitmq is not a critical service?
Thanks in advance!

How to configure client and server to make client auto refresh in spring cloud confi

I have created the demo for client as well as server using spring cloud config documentation. I am using git properties file for external configuration. If I made any change in external configuration file and refresh the client then its working fine. But I don't want to refresh each and every time. I want to make my client in such a way that it will auto refresh.
I go through spring documentation and I think we can do it with following way.
With help of Redis
Spring cloud bus
Which one is right way to do it?
Currently I am trying first one with https://github.com/spring-cloud-samples/configserver/ but it did't work.
So any one please explain me how to configure client and server so that we don't need to refresh client?
Should I moved with spring cloud bus?
There is no "right" way. To monitor changes in the config server you need the spring-cloud-config-monitor (or that could be used in a standalone app). It uses Spring Cloud Bus to broadcast the change events, but you have to choose a transport (so Redis is one valid choice).
You also need to listen for the changes on your client, so add the spring-cloud-starter-bus-redis (or amqp or kafka etc. if you use a different transport on the server).
The sample you linked to is currently hooked up to monitor changes and propagate them via Spring Cloud Bus over Redis (the dependencies spring-cloud-config-monitor and spring-cloud-starter-stream-redis switch this on):
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-monitor</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-stream-redis</artifactId>
</dependency>
To receive notifications from github though, you need to register your application URL with your github repository. The sample doesn't have a URL, so it isn't registered. If you change it to use a file-based repository (e.g. a local git repo) then it will monitor the files and won't need a hook.

Resources