Camel org.apache.camel.component.direct.DirectConsumerNotAvailableException - java

we are using camel direct component in our project.
Application will work fine most of the time.
But sometimes services won't work because of following exception.
if we restart server again things will go normal.
we are not following any route startup order to start camel routes. All routes will load at deployment time only.
we are using camel 2.16.1 version.
Could any one suggest what causing this issue and why it is occurring often.
Caused by: org.apache.camel.component.direct.DirectConsumerNotAvailableException: No consumers available on endpoint: Endpoint[direct://framework-logger-service].

This error occurs when "direct://framework-logger-service" route is not initialized in your application context.
but if it occurs sometimes then direct being a synchronous component it may not be available for accepting requests while processing other requests.
This behavior is possible when you send huge number of requests to direct component.

The simple approach will be split your direct to two components to load balance
from(somesource).to(direct:total);
from(direct:total)
.multicast()
.parallelProcessing()
.to(direct:part1,direct:part2);

Related

Requests get dropped during springboot service pod rollout

I am using the Kubernetes cluster with docker. When I deploy the java services[springboot] some requests get dropped(for a couple of secs) with the following error.
exception=org.springframework.beans.factory.BeanCreationNotAllowedException: Error creating bean with name 'controller': Singleton bean creation not allowed while singletons of this factory are in destruction (Do not request a bean from a BeanFactory in a destroy method implementation!), stackTrace=[org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton() at line: 208]
I am already using livenessProbe & readinessProbe.
Java Version: 12
SpringBoot Version: 2.1.5.RELEASE
Hibernate Version: 2.4.3 with Postgres DB
As per my knowledge, it is happening due to the closing of the application context while executing some requests. Ideally, it should not be.
can anyone help here ?
the problem is not actually springboot, but rather the way Kubernetes stops pods.
at the moment when a pod from your old deployment/replicaset is being terminated (or rather actually set to state "terminating"), 2 things happen simultaneously:
A) pod is removed from service endpoints, so it does no longer receive new requests
B) pod container gets a SIGTERM, so apps can gracefully shutdown
so what you are seeing here is basically active requests that are being processed when the context gets shut down (as you already found out)
there are (at least) two solutions:
1 in kubernetes pod definition:
Kubernetes pods can be configured with a pre-stop hook that get executes a command in between A and B.
depending on your app, a simple "sleep" for a couple (milli)seconds should be sufficient, leaving the app enough time to finish the current requests before shutting down.
theres nice docu from google that goes more into detail:
https://cloud.google.com/blog/products/containers-kubernetes/kubernetes-best-practices-terminating-with-grace
2 in SpringBoot:
you can make Java wait for finishing up running tasks when receiving the shutdown interrupt.
this is (imho) nicely explained here:
https://www.baeldung.com/spring-boot-graceful-shutdown
Beware: kubernetes default graceful shutdown timeout is 30seconds, then the pod is forcefully removed. but as usual you can configure this timeout in terminationGracePeriodSeconds (also described in the google blog in (1)

Springboot: need to be informed/notified when Web-Server is Up

I am writing a Springboot application embedding Tomcat as a Web Server.
At startup, some of my threads are ready (and so start doing their job) before Tomcat is. For many contraints I have, I want that these threads do nothing before Tomcat is ready
But I don't know how to decided to block/unblock my threads; to do so, I need to be informed of the Tomcat status. Is there:
a way to ask: isWebServerStarted()?
or a way to be notified asynchronously by a message saying: WEB_SERVER_IS_STARTED?
Thank you for help
FYI, I don't want to declare a kind of "private ReST endpoint" that my
application could try to reach in order to guess whether the webserver
is ready
Go with a ServletContextListener. Annotate your class with #WebListener and tell spring configuration about this listener by adding #ServletComponentScan annotation.

Logging aspect for exceptions with JMS retry mechansim

In our project we use Activemq (jms template) - to publish many events from one webapp to another.
we use logging aspect (spring aop) as well - mainly we log errors and entering\quitting methods.
Now, sometimes we face racing conditions on the flow of the systems. i.e. an entity is being created on one web app, an event is fired to notify another webapp, but the handling of the other webapp requires a different event to be handled first, so if such scenario happens, the handling fails (for example, an id is missing ) and immediately retried (jms re-delivery), on the 2nd time of the retry its usually works (never more then 3 retries are required).
So basically, we have exceptions as part of our day to day flow, but:
our log files are huge and messy because of the exceptions thrown by such scenarios, any idea how can we not log the first few retries exceptions and only on a later exception we will log? Maybe another approach you can recommend?
Thanks.
You can use JMSXDeliveryCount property of Message to get the redelivery count. See http://activemq.apache.org/activemq-message-properties.html

How to update camel properties externally?

Im developping non OSGI app and i need to update the values ​​of some properties used in camel routes (loaded BridgePropertyPlaceHolder).
So I thought:
To use Hawtio, the cool mangement console, in order update camel using JMX
Create a JMX MBean that will update the properties ..
I successfully create the MBean operations and call them using JMX, but I can't figure out how to update the camel routes that depends on these properties.
Is there a way to update the camel context externally?
Update:
Exemple of use case:when a remote server doesn't return response, we keep sending messages until we reach the max of unsuccessful attempt(messages without ack).
in camel we create a router pattern based on property loaded from file system.
This property can change occasionally, and we want to do this without restarting server, but the problem is that camel parse routes when starting context and i can't find no mean to update routes accordingly.
I am grateful for any proposal that could help:)
If you use Camel error handling to retry (redeliver) then you can use the retryWhile to keep retrying until you return false. This allows you to use java code etc, and that allows you to read the updated configuration option.
See more details at
http://camel.apache.org/exception-clause.html
And if you have a copy of Camel in Action book, see page 152
For what properties you want them to be dynamic.you can move those prop to some db and fetch them whenever you are reading.I think a redesign is required for your camel route.
Changing from endpoint parameters such as URLs etc., following procedure has to be used according to dynamic change endpoint camel:
stop the route
remove the route
change the endpoint
add the route
start the route
If the to endpoint has to be configurable, you may use the recipient list component. Here you may read properties from a database and/or from the filesystem using the appropriate Camel component.

Spring Integration Channels on Content

I have used Spring Integration in my current successfully for some of the needs. Awesome..
There is some weird behavior observed on a heavy load where-in the same message seems to be processed more than once. I can confirm that because there are multiple rows in the database which is typically the last command on the chain that is configured over the channel.
Digging into the manual further, it looks seems like load-balancing is done automatically by spring. The manual says that the message is balanced between multiple message handlers.
Question is:
How many handlers are present on a channel by default? The spring XML that gets loaded does not seem to have that configuration. All i do is this (per the recommendation in the manual):
<int:channel id="SwPath.Channel"/>
<int:chain id="SwPath.chain" input-channel="SwPath.Channel">
</int:chain>
I can disable the fail-over but I am curious to know how many are present by default.
It's been a while since I worked on those load balancers, but I remember that the default number of threads in the thread pool was somewhere between 2 and 10.
It is possible that you have found a concurrency bug.
If you turn on TRACE logging the load balancer will give you a lot of information, but that could easily hide the problem.
If you would create a JIRA issue with a JUnit test case, I'm sure it would be much easier to figure out what happens exactly.

Categories