What I need is to deploy separate parts of application (like 1 queue listener only) per pod in the cloud yet keep the monolith code architecture.
I agree with @jacky-neo's answer in terms of the appropriate architecture/best practice, but that may require you to break up your monolithic application.
To solve this without breaking up your monolithic application, deploy multiple instances of your monolith to Kubernetes each as a separate Deployment
. Each deployment can have its own configuration. Then you can utilize feature flags and define the environment variables for each deployment based on the functionality you would like to enable.
In application.properties
:
myapp.queue.listener.enabled=${QUEUE_LISTENER_ENABLED:false}
In your Deployment
for the queue listener, enable the feature flag:
env: - name: 'QUEUE_LISTENER_ENABLED' value: 'true'
You would then just need to configure your monolithic application to use this myapp.queue.listener.enabled
property and only enable the queue listener when the property is set to true
.
Similarly, you could also apply this logic to the Spring profile to only run certain features in your app based on the profile defined in your ConfigMap
.
This Baeldung article explains the process I'm presenting here in detail.
For the scheduled task, just set up a CronJob
using a curl
container which can invoke the service you want to perform the work.
Edit
Another option based on your comments below -- split the shared logic out into a shared
module (using Gradle or Maven), and have two other runnable modules like web
and listener
that depend on the shared
module. This will allow you to keep your shared logic in the same repository, and keep you from having to build/maintain an extra library which you would like to avoid.
This would be a good step in the right direction, and it would lend well to breaking the app into smaller pieces later down the road.
Here's some additional info about multi-module Spring Boot projects using Maven or Gradle.