Spring boot - Tomcat proper shutdown procedure - spring

I have a sprig boot app leveraging websockets using tomcat. The app is writing stuff to the database constantly, and now I would like to implement a proper shutdown procedures i.e.
I have found a way to tell in my Service Layer to wait until all database transactions has finished however I would like to tell tomcat during that time that he shell not accept new connection i.e. only process the the currently established one. Tomcat should run but all new sessions should be denied.
I can get all the currently logged in users trough the “SessionRegistry” bean and invalidate their sessions, once all database transactions has finished, but that does not prevent anyone form creating new session during that time. So my question is how to I tell tomcat to stop accepting new session but not to drop the currently created one and let them finish. Is there something like that build in into tomcat?
Addition : 15 March 2018
I think i found the answer look
here
Hope that this will be useful for someone

Related

Spring boot restful webservices

My spring boot restful web services is working even though stopped running microsoft sqlserver database in my services. How does it work?
There might be below reason.
You might be using some kind of cache so still response is coming form cache even your db is down.
You might be checking services which are not required db transaction..
OR if you are only referring you application is continue to running then might be spring.datasource.continue-on-error=true has been set. or you might have some defined data source validations properties to at-least continue run app and whenever db is back, it will established a connection.

How to ensure my Reactive application is running in event loop style

I am using spring boot 2.0.4.RELEASE. My doubt is whether my application is running in event loop style or not. I am using tomcat as my server.
I am running some performance tests in my application and after a certain time I see a strange behaviour. After the request reaches 500 req/second , my application is not able to serve more than 500 req/second. Via prometheus I was able to figure out max thread for tomcat were 200 by default. Looks like all the threads were consumed and that's why , it was not able to server more than 500 req/second. Please correct me if am wrong.
Can the tomcat server run in event-loop style ?
How can I change the event-loop size for tomcat server if possible.
Tried changing it to jetty still the same issue. Wondering if my application is running in event loop style.
Hey i think that you are doing something wrong in your project maybe one of your dependency does not support reactive programming. If you want to benefit from async programing(reactive) your code must be 100 reactive even for security you must use reactive spring security.
Normally a reactive spring application will run on netty not in tomcat so check your dependency because tomcat is not reactive
This is more of a analysis. After running some performance test on my local machine , I was able to figure out what was actually happening inside my application.
What I did was, ran performance test on my local machine and analysed the application through JConsole.
As I said I scheduled all my blocking dB calls to schedulers.elastic. What I realised that I it is causing the bottleneck. since my dB connections are limited and I am using hikari for connection pooling so it doesn’t matter the number of threads I create out of elastic pool.
Since reactive programming is more about consuming resource to the fullest with lesser number of threads, since the threads were being created in unbounded way so it was no different from normal application .
So what I did as part of resolution limited the number of threads to 100 that were supposed to be used by for dB calls. And bang number jumped from 500 tps to 2300 tps.
I know this is not the number which one should expect out of reactive application , it has much more capability. Since right now I do not have any choice but to bear with non reactive drivers .Waiting for production grade availability of reactive drivers for mssql server.

Spring Application Context Initialization

In my Spring Application, at the time of context Initialization. The DB is not available, it will come up after some time (Due to DB redundancy). In this scenario, my spring application initialization should be delayed or the application should do retry for DB connectivity. How to achieve the same via Spring.
Srirama.
I'd suggest investigating the ApplicationContextInitializer. It is meant to be used for setting up your context before most of the magic of spring initialization happens.
I'm not sure if it is designed for your use case, but no beans are initialized when the initialize method is called during startup.
The example provided in the link deals with properties, but I see no reason why you should not create your own manually created connection and wait for it's readiness.
Thanks for the reply.
My application is initialized by means of C3P0. Here C3P0, is trying to reconnect to DB only for 30 times (the default configuration for acquireRetryAttempts) and after that it is saying failed to create the application beans.
Changed the configuration for acquireRetryAttempts to -1, so that C3P0 is retrying indefinitely till the DB connection is successful. Basically my app. initialization should be delayed till the DB comes up.
Srirama.

Can I use separate non connection pool data source for long running but infrequent tasks?

My application stack consists of Spring MVC, Hibernate and MySQL hosted on Apache tomcat 7.
I have set up Spring to manage transactions and Hibernate session factory is utilizing the tomcat dbcp connection pool backed datasource for getting the connection.
I have a use case in my application in which I have a run a long running task which is initiated through the web UI (say a button click). This task runs for let’s say 10 minutes then my connection pool starts to throw connection closed exceptions. This is obviously because of connection pool setting in which if the connection is not returned to pool after a specific time, it is marked as abandoned and later removed. I could solve this by tinkering with the timeout settings and increasing it to a large enough value. But I may have several other use cases like this and may not currently have idea how long those will run.
So I am thinking of another approach here.
This use case will be initiated not very often, so I may use a separate datasource definition without using connection pool. Of course I can set two transaction managers in Spring with different names “abc” and “xyz” and use the #Transactional(name=”abc”) and #Transactional(name=”xyz)”. Both these transaction managers would use their respective datasources – one with connection pool to support common use cases and one without connection pool to support long running transaction. This way I won’t have to worry about changing the timeout configurations.
Will this be a generally accepted solution or should I take the timeout configuration approach?
Avoiding to use the connection pool will cause problems if you don't have another way to limit the number of connections that your application can initiate. For example (trivial example of cours) if your going to launch your batch process each time a user clicks a button, make sure you limit the times they can do this task.
Another way would be to define a new jdbc resource in your application server (jdbc/batchprocess) and configure in this resource a longer timeout. Then change from one to another using dynamic datasource routing.
You can open Hibernate Sessions, supplying your own Connection:
sessionFactory.withOptions().connection( yourConnection ).openSession();

Access Denied randomly when connecting to mysql

I have a very rare problem it is a java web application with jsf 2.0, spring 3.0.3 and jpa2 eclipselink implementation running on tomcat 7 when deploying the application to server it run correctly without any errors and after random period of time it return Access Denied for user "user#host" and all i need to do is just restarting tomcat to work again.
Please help if you know anything about this problem.
Thanks,
Are you leaking connections?
It sounds like you're using up all the connections and MySQL won't let you create new ones.

Resources