Caching H2 database in multiple pods on Openshift - spring-boot

I am developing a high performance service in spring boot. It is deployed to Openshift and running in multiple pods.
Now I need some configuration which is stored in a database and read by all pods. Data can be changed through a web app.
I would like to do some performance tuning on the database part. What is best to do?
Migrate to a H2 database running in a single pod and the other ones connect to this?
Or some kind of redis caching?
Is there any kind of best practise or recommendation to do this?

Related

Spring Cache Persistence in Kubernetes Deployment

Have seen a super weird issue in our aws kubernetes cluster deployment where the in-memory spring cache appeared to be persistent even after a rollout restart and pod deletion. Is that even possible for an argument sake? Deletion of a pod should have deleted the container which should thereby the underlying memory.
Please share your thoughts, as there is no logs associated to share except the observed behavior.
Environment Details:
Spring Boot 2.7.x
AWS EKS 1.21
Java 17
Spring Cache is an abstraction that provides automatic integration with various persistence technologies besides a simple in-memory cache.
If you have redis configured, for example, and are using spring boot, a default redis caching will take place.

Does Spring Boot supports Master Slave config of RDBMS DB

I have a multiple Spring Boot based Micro services which connect a DB2 data base (Master BD). We want to have same replica of Master DB which is called Slave DB2 DB. Every month we have some maintenance on master DB for 5-10 hrs during this time we want all our apps to automatically connect to Slave DB after this time period apps should switch back to Master without manual intervention.
Is this possible to achieve in Sprint Boot. I thought of using Spring Cloud Hystrix but is it correct architectural pattern. Any other better approach.
It's possible to do this on the infrastructure level, your apps does not need to know that there was a failover.
If you want to solve this on the application side, you can use Spring Cloud Circuitbreaker (Hystrix is deprecated, but you can use it with Resilience4J).

Understanding Microservice Architecture

Since I am trying hard to understand the microservice architecture pattern for some work, I came across the following question:
It's always said that a microservice usually has its own database. But does this mean that it always has to be on the same server or container (for example having one docker container that runs a MongoDB and my JAR)? Or can this also mean that on one server my JAR is running while my MongoDB is located somewhere else (so two containers for example)?
If the first one is correct (JAR and database within one container), how can I prevent that after some changes regarding my application and after a new deployment of my JAR my data of the MongoDB is resetted (since a whole new container is now running)?
Thanks a lot already :-)
Alternative opinion:
In 99% of real life cases you musnt have a single container that runs
database and the application, those should be separated, since one
(db) is keeping state, while the other (app) should be stateless.
You don't need a separate database for microservice, very often a separate schema is more than enough (e.g. you dont want to deploy a separate Exadata for each microservice :)). What is important is that only this microservice can read and write and make modifications to given tables others can operate on those tabls only through interfaces exposed by the microservice.
First of all each Microservice should have its own database.
Secondly it's not necessary and also not recommended to have the Microservice and its database on the same container.
Generally a single Microservice will have multiple deployments for scaling and they all connect to a single Database instance which should be a diff. container and if using things like NoSql DB's its a database cluster.
Yes, Each Microservice should have its own database and if any other Microservice needs data owned by another microservice, then they do it using an API exposed by Microservices. No, it's not at all necessary to have the Microservice and its database to be hosted on the same server. For Example - A Microservice can be hosted on-premise and its database can live in the cloud like AWS DynamoDB or RDS.

How can you scale a Spring Boot application?

I understand that Spring Boot has a built-in Tomcat server (or Jetty) which facilitates rapid development. But what do you do when you need to scale out your application because traffic has increased?
As pointed out in the comments, there is no silver bullet here, it depends on your infrastructure and there are several tools out there to help you, you only need to choose what works best for you.
For load balancing you can either choose something like an Nginx or leave it to spring cloud which also has a lot of other handy features for scaling/clustering.
Scaling shouldn't be very hard because spring boot runs on it's own server.
Some tools that help with scaling/clustering:
Spring boot app:
If you are going to scale, your app has to be near-stateless (e.g: you cannot have a scheduled task or something like that because when you scale to x instances, they are executed x times).
You can use the spring cloud project for extra added features like service discovery and other goodies that make scaling easier (e.g: When you spin up a new instance, it can get the config easily from a config server, 'register' to ease the loadbalancing between services, have cluster-like behaviour, etc...).
Infrastructure and containers:
Docker is a no-brainer here to handle easy launching of your applications and their replicas, if needed. If you can go further with resources and go with Kubernetes but it all depends on the use case.
Various servers (nodes), in case one of them fails and to easily distribute loads.
Ngnix for load balancing is pretty straightforward if you already don't have something done with spring cloud.
Database:
You really do NOT want to go with MySQL here because it can not scale well as your spring apps. You can choose something like Cassandra or Redis but that would mean restructuring your data model. Maybe the least-painful transition from MySQL to something NoSQL that can scale is a MongoDB (imho: Cassandra performs better).
Logging:
This can be a nightmare but spring also has a solution for this. Check out zipkin and spring sleuth.
Also, there are a lot resources here that talk a lot about architecture in general and how it is necessary to change the mindset when trying to run distributed services.
Hope this helps.
Update 2021-02-23
Today, Kubernetes is pretty much a de-facto standard when we talk about scaling and is preferred because of the rich set of features that you will be able to leverage and focus your app purely on business domain logic and can remove things like spring cloud for service discovery. If you can use some public clouds like EKS and GKE, you are better off without having to manage the clusters by yourself.
It provides autoscaling and built-in healthchecks. Starting from Spring Boot 2.4, you have many added benefits for running Spring Boot on K8s like dedicated healthcheck endpoints for liveness and readiness probes, graceful shutdown, etc....
On the database side, aim for something that is managed and scales easily such as AWS Aurora or similar.
An important thing to mention when managing spring boot services at scale is probably configuration management. A very useful solution that you can use out of the box is Consul. This will enable you to hot reload the configuration which is important when you have 50 services that you need to restart only to change one boolean variable. Depending on how big is your application, the startup can be costly, in terms of time as well as CPU/memory resources

enable hibernate app to use clustered hazelcast

our prod environment architecture is decided to be like this:
2 machines that each of them have 2 tomcat instances (on vm). there is spring web app with hibernate running on tomcat.
there are also 2 db instances distributed to both machines.
so, we think that hazelcast fits this achitecture well. hazelcast will be second level cache for hibernate, it will manage clustered cache over db instances.
we installed hibernate server and defined our clusters on it.
i've searched offical hazelcast doc and several sites but i couldnt find the way to configure hibernate to use this hazelcast server as L2 cache.
we dont want to change our existing app. we'll keep using hibernate as it is. is it possible? if so, how we can configure hazelcast server on our web app?
I think it is important to understand that your probably don't want to have a standalone Hazelcast cluster/server; what you normally do is to embed Hazelcast within your application.
Like Miko said, you can just enable Hazelcast to be used as second level cache; no need to make any fundamental changes.
I also don't understand what you mean with 'hibernate server', because Hibernate is just an OR mapper library and has no concept of server.
So can you tell a bit more what you want so we can help you out?

Resources