Spring Boot: Starting multiple services using shell script (.sh) - spring-boot

I like to write a shell script for a backend server using Spring Boot (v2.1.1) to start multiple microservices in a certain order - some services depend on other to be running.
What is the 'best practice'?
Of course i could run the .jars like this (original post):
#!/bin/bash
java -jar myjar1.jar &
java -jar myjar2.jar &
java -jar myjar3.jar &
But this would start the .jars simultaneously, afaik.
How can i ensure, that a certain service myjar1.jar started properly and after that, another service myjar2.jar is started. Because every service is a SpringBootApplication i assume that there are certain possibilities to do so?!
I read this SO solution but I don't want to create any symlinks, because i just need that for development purposes.

Well it is very specific to your service as to when it gets started.
At process level, as soon as you execute the command service is running, so you will need your service to share the state when its up.
One way i can think of is in your script start the service, expose health api and check if its up. if it is move to next one. You need to make use of curl and sleep command in your scripts.
But I would like to know why you want to do that. Specially for your microservices, your services should not depend on each other. They may need some data, but they should be resilient to the fact that services may come and go. You should have a very strong reason to do as you are doing, cause in real world env, it is very difficult to ensure order is maintained.

Related

Configure timing of opening ports in Spring-Boot application

Question:
Is there an option within spring or its embedded servlet container to open ports when spring is ready to handle traffic?
Situation:
In the current setup i use a spring boot application running in google cloud run.
Circumstances:
Cloud run does not support liveness/readyness probes, it considers an open port as "application ready".
Cloud run sends request to the container although spring is not ready to handle requests.
Spring start its servlet container, open its ports while still spinning up its beans.
Problem:
Traffic to an unready application will result in a lot of http 429 status codes.
This affects:
new deployments
scaling capabilities of cloud run
My desire:
Configure spring/servlet container to delay opening ports when application is actually ready
Delaying opening ports to the time the application is ready would ease much pain without interfering too much with the existing code base.
Any alternatives not causing too much pain?
Things i found and considered not viable
Using native-image is not an option as it is considered experimental and consumes more RAM at compile time than our deployment pipeline agents allow to allocate (max 8GB vs needed 13GB)
another answer i found: readiness check for google cloud run - how?
which i don't see how it could satisfy my needs, since spring-boot startup time is still slow. That's why my initial idea was to delay opening ports
I did not have time to test the following, but one thing i stumbled upon is
a blogpost about using multiple processes within a container. Though it is against the recommendation of containers principles, it seems viable for the time until cloud run supports probes of any type.
As you are well aware of the fact that “Cloud Run currently does not have a readiness/liveness check to avoid sending requests to unready applications” I would say there is not much that can be done on Cloud Run’s side except :
Try and optimise the Spring boot app as per the docs.
Make a heavier entrypoint in Cloud Run service that takes care of
more setup tasks. This stackoverflow thread mentions how “A
’heavier’ entrypoint will help post-deploy responsiveness, at the
cost of slower cold-starts” ( this is the most relevant solution
from a Cloud Run perspective and outlines the issue correctly)
Run multiple processes in a container in Cloud Run as you
mentioned.
This question seems more directed at Spring Boot specifically and I found an article with a similar requirement.
However, if you absolutely need the app ready to serve when requests come in, we have another alternative to Cloud Run, Google Kubernetes Engine (GKE) which makes use of readiness/liveness probes.

Quartz with centralized scheduling and monitoring

We are trying to revamp our batch job scheduling and monitoring process over the entire enterprise. Currently all our batch jobs are scheduled using Unix crontab and are monitored using log files generated by shell scripts.
This process has lot of disadvantages and as the number of applications grow this gets really complicated.
Two copies of applications need to be deployed one to App-Server and one as standalone(since business logic is shared between both). This is complicating our build process too.
There is no easy of use web-ui for us to see the status of jobs and manually run failed jobs remotely without getting onto the unix box.
There is no fail over or load balanced batch processing.
So I was thinking of using Quartz (with our existing Spring apps) in our applications and deploy them to App-Servers and no longer rely on the unix crontab.
Is there a way I can write a centralized web application from where I can schedule and monitor jobs running on different quartz schedulers on different app servers?
P.S: I know quartzdesk.com is one solution, but I don't want to enable RMI on my JVM.
You could use SpringBoot scheduler as an Orchestrator and call REST APIs for the remote (or local, if you are small) execution. This way, as your app grows you could easily leverage a load balancer.
If you have the possibility of using cloud services (like Amazon, Azure or Google Cloud), this could be done easily using their own load balancers. They also support docker and could take care of any peaks of utilization.

Stop WebSphere Liberty server if application fails to start

I'm looking for an option to stop my Liberty server if a specific application fails to start.
I can't find any option for this in the docs, the closest thing I've found to achieve this is health policies but they don't look to be a good fit.
You could write something (even as simple as a bash script) to check the logs for:
"CWWKZ0001I: Application {appName} started"
and if you don't see it in x time, then execute "/wlp/bin/server stop {serverName}"
Could do it all through mbean invocations via java or REST calls by checking the state of the app (WebSphere:service=com.ibm.websphere.application.ApplicationMBean,name=*) and if it's not 'Started' by x time, then invoke an api to stop it (for collective environment you could use WebSphere:feature=collectiveController,type=ServerCommands,name=ServerCommands, otherwise you could use the osgi framework api).

Running batch applications on Cloudfoundry: using tasks instead of long-running processes

I would like to run a batch application (that is a short lived process that should not be restarted) on Pivotal CloudFoundry.
I am not sure how to do that. My current batch app is restarted repeatedly by Pivotal CF.
It seems there's a new CF primitive called a task - as opposed to a long-running process. Tasks are supposed to be available on CF 1.7 (see https://stackoverflow.com/a/35512113/536299).
I was neither able to find relevant information in the CF documentation nor to figure out which version of the Pivotal CF is currently being run...
Can someone please help?
I just got relevant information regarding short-lived/one-off processes on CF. It currently seems to be very difficult to run short-lived/one-off processes on CF.
This will change when CF v3's tasks becomes generally available.
Here is the information I was given:
Batch jobs are a little tricky on PWS and PCF because at the moment
the platform expects your application to continue running forever.
Even if the app exits successfully, the platform considers it to have
crashed and will restart it. There is support in v3 of the platform
for one-off tasks like batch jobs, so this will get easier in the
future. For now, what you need to do is to make the app run forever.
One option is to add a loop to the main method in the app, the loop
would essentially run the batch job, pause for some set amount of time
and repeat indefinitely.
So bottom-line is wait for CF v3's tasks.
See here for documentation about tasks: http://v3-apidocs.cloudfoundry.org/version/release-candidate/index.html#tasks

Custom Windows 2003 Services

I have an .exe I want to start when the Win2k3 server boots. Does .exe needs to be setup as a custom service. If so, what is the process to setup the custom service?
I assume you don't really mean at boot time (you would have to write a driver service for that) but rather at user mode system start up.
If your process is uncomplicated you could just set it up as a scheduled task - with the trigger set to system start. If it needs to interact with the system more, i.e. needs to be paused, needs to be shutdown, warned of system events such as power events or shutdown, etc. then you should probably look to convert it to a Win32 service.
If you do need to convert to a service then start reading here and then continue with something like Richter's or Miller's books until you really understand what you are doing. Then write your service application.
If you want to create that service manually, you can use sc.exe for the job. However that exe must be capable to run as service of course.
XYNTservice a simple service that can start pretty much any program as a service.
http://www.codeproject.com/KB/system/xyntservice.aspx

Resources