Microservices database architecture - spring

I have a question about microservice architecture
for example if i have two microservice "UserService" and "TaskService"
and i have the database for my systeme with two table "USER" and "TASK"
We know that one of the Microservices rules is that each Microservice has its own database
So I don't know how to distribute my database for this two microservices ?
set for the database for the "UserService" microservice two tables "USER" and "TASK"
and set for the database for the "TaskService" microservice two tables also "USER" and "TASK"
or
set for the database for the "UserService" microservice the table "USER"
and set for the database for the "TaskService" microservice the table "TASK" but the problem here is how to link the two tables "USER" and "TASK" because each one is in a different database

The first question you have to ask yourself is if in this case you really need a microservice architecture. If as you say, the service has only two tables, and the two are closely related (so both will propably belongs to the same bounded context). The most probably answer is no.
Because this way you will add more complexity and latency to the system.
With this in mind, If you really need this architecture, because the real application is more complex and you have identified that this two services belong to different bounded contexts, I mean their functionality are not closely related, the way to solve this is that each microservice owns its own database with its own table.
So the user service will have its own table as well as task service. If there is a use case in user service that needs information of task service or viceversa. You can do a request from origin service to target service to retrieve this information or if you really need to decouple the two and/or you have performance requirements, then the solution could be to have a read only table with the other service information that you need and update it by subscribe to the changes of the table owner using kafka for example or another message broker

Related

How to split monolothic application into microservices when most operations on one aggregate?

I am splitting a monolothic application into microservices based on this schema
https://gist.github.com/lithdew/0b6f892b927333f76dc4bdcf34e4d9ec
Following DDD, I found 4 aggregates for this schema: User, JobTitle, Skill and Course. So there should be 4 microservices corresponding Account, JobTitle, Skill and Course.
The tricky thing is when I come across all APIs providing to Front End, 90% of them are related to User dependent Entities such as user_skills, user_job_titles ...
If I follow the DDD, then Account microservice would be very big, most of logic will go inside this microservice and the others would be tiny. Base on this, I come up with 2 solutions:
I split the application into 2 microservices: Account microservice for User aggregate and Insight microservice for JobTitle, Skill and Course aggregates. The problem with this solution is that it will create a cluster communications between Account and Insight since most of time Account need data from Insight microservice for it's business logics. And the original problem that Account microservice helds most of APIs for FE is not eliminated.
Keeping 4 microservices Account, JobTitle, Skill And Course. And pushing User dependent Entities into other corresponding microservices. For example user_skills will go into Skill microservice. This solution looks better but it will break DDD aggregate principle and could bring more problems later
How should I split this monolothic application into microserices?
I don't know exactly how many dependent relations the user entity has with the other aggregates, but in this case you could replicate the relation data in your user microservice and keeping it updated using events.
For example. If you have a table called user_skills then you can place it in the users domain and when a skill changes in the skill microservice, it will write an event in some sort of message broker like kafka and user microservice will be listen to consume that event and update its user-skill table accordingly.

Can I keep a copy of a table of one database in another database in a microservice architecture?

I am currently new to microservice architecture so thanks in advance.
I have two different services a User Service and a Footballer Service each having their individual databases.(User database and Footballer database).
The Footballer service has a database with a single table storing footballer informations.
The User service has a database which stores User details along with other user related data.
Now a User can add footballers to their team by querying the Footballer service and I need to store them somewhere in order to be displayed later.
Currently I'm storing the footballers for each user in a table in the User database whereby I make a call to the Footballer service to give me the details of a specific footballer by ID and save them in the USer database by mapping against the USer ID.
So is this a good idea to do that and by any chance does it mean im replicating data between two services
and if it is than what other ways can i achieve the same functionality ?
Currently I'm storing the footballers for each user in a table in the User database whereby I make a call to the Footballer service to give me the details of a specific footballer by ID and save them in the USer database by mapping against the USer ID.
"Caching" is a fairly common pattern. From the perspective of the User microservice, the data from Footballer is just another input which you might save or not. If you are caching, you'll usually want to have some sort of timestamp/version on the cached data.
Caching identifiers is pretty normal - we often need some kind of correlation identifier to connect data in two different places.
If you find yourself using Footballer data in your User domain logic (that is to say, the way that User changes depends on the Footballer data available)... that's more suspicious, and may indicate that your boundaries are incorrectly drawn / some of your capabilities are in the wrong place.
If you are expecting the User Service to be autonomous - that is to say, to be able to continue serving its purpose even when Footballer is out of service, then your code needs to be able to work from cached copies of the data from Footballer and/or be able to suspend some parts of its work until fresh copies of that data are available.
People usually follow DDD (Domain driven design) in case of micro-services :
So here in your case there are two domains i.e. 2 services :
Users
Footballers
So, user service should only do user specific tasks, it should not be concerned about footballer's data.
Hence, according to DDD, the footballers that are linked to the user should be stored in football service.
Replicating the ID wouldn't be considered replication in case of microservices architecture.

How can I divide one database to multi databases?

I want to decompose my application to adopt microservices architecture, and i will need to come up with a solid strategy to split my database (Mysql) into multiple small databases (mysql) aligned with my applications.
TL;DR: Depends on the scenario and from what each service will do
Although there is no clear answer to this, since it really depends on your needs and on what each service should do, you can come up with a general starting point (assuming you don't need to keep the existing database type).
Let's assume you have a monolithic application for an e-commerce, and you want to split this application into smaller services, each one with it's own database.
The approach you could use is to create some services that handles some parts of the website: for example you could have one service that handles users authentication,one for the orders, one for the products, one for the invoices and so on...
Now, each service will have it's own database, and here's come another question: which database a specific service should have? Because one of the advantages of this kind of architecture is that each service can have it's own kind of database, so for example the products service can have a non relational database, such as MongoDB, since all it does is getting details about products, so you don't have to manage any relation.
The orders service, on the other hand, could have a relational database, since you want to keep a relation between the order and the invoice for that order. But wait, invoices are handled by the invoice service, so how can you keep the relation between these two without sharing the database? Well, that's one of the "issues" of this approach: you have to keep services independent while also let them communicate each other. How can we do this? There is no clear answer here too... One approach could be to just pass all invoices details to the orders service as well, or you can just pass the invoice ID when saving the order and later retrieve the invoice via an API call to the invoice service, or you can pass all the relevant details you need for the invoice to an API endpoint in the order service that stores these data to a specific table in the database (since most of the times you don't need the entire actual object), etc... The possibilities are endless...

In microservices does it makes sense to have one microservice with two database connections?

I'm beginning with microservices but what I'm about to do seems to be a bad practice. Let's imagine I have an user microservice and an order microservice.
Now, if I want to create a report based on user and orders I would need to consume both user and order microservices through their apis. Would it make sense to have a report microservice with database connections to both user and order microservices?
While I was reading microservices.io decomposition section they say that doing joins into our queries becomes harder, so why create endpoints to handle "possible joins"(suggested by the article) for reports instead of giving read access to each database(imagining a database per microservice)?

Distributed database design style for microservice-oriented architecture

I am trying to convert one monolithic application into micro service oriented architecture style. Back end I am using spring , spring boot frameworks for development. Front-end I am using angular 2. And also using PostgreSQL as database.
Here my confusion is that, when I am designing my databases as distributed, according to functionalities it may contain 5 databases. Means I am designing according to vertical partition. Then I am thinking to implement inter-microservice communication services to achieve the entire functionality.
The other way I am thinking that to horizontally partition the current structure. So my domain is based on some educational university. So half of university go under one DB and remaining will go under another DB. And deploy services according to Two region (two for two set of university).
Currently I am decided to continue with the last mentioned approach. I am new to these types of tasks, since it referring some architecture task. Also I am beginner to this microservice and distributed database world. Would someone confirm that my approach will give solution to my issue? Can I continue with my second approach - horizontal partitioning of databases according to domain object?
Can I continue with my second approach - Horizontal partitioning of
databases according to domain object?
Temporarily yes, if based on that you are able to scale your current system to meet your needs.
Now lets think about why on the first place you want to move to Microserices as a development style.
Small Components - easier to manager
Independently Deployable - Continous Delivery
Multiple Languages
The code is organized around business capabilities
and .....
When moving to Microservices, you should not have multiple services reading directly from each other databases, which will make them tightly coupled.
One service should be completely ignorant on how the other service designed its internal structure.
Now if you want to move towards microservices and take complete advantage of that, you should have vertical partition as you say and services talk to each other.
Also while moving towards microservices your will get lots and lots of other problems. I tried compiling on how one should start on microservices on this link .
How to separate services which are reading data from same table:
Now lets first create a dummy example: we have three services Order , Shipping , Customer all are three different microservices.
Following are the ways in which multiple services require data from same table:
Service one needs to read data from other service for things like validation.
Order and shipping service might need some data from customer service to complete their operation.
Eg: While placing a order one will call Order Service API with customer id , now as Order Service might need to validate whether its a valid customer or not.
One approach Database level exposure -- not recommened -- use the same customer table -- which binds order service to customer service Impl
Another approach, Call another service to get data
Variation - 1 Call Customer service to check whether customer exists and get some customer data like name , and save this in order service
Variation - 2 do not validate while placing the order, on OrderPlaced event check in async from Customer Service and validate and update state of order if required
I recommend Call another service to get data based on the consistency you want.
In some use cases you want a single transaction between data from multiple services.
For eg: Delete a customer. you might want that all order of the customer also should get deleted.
In this case you need to deal with eventual consistency, service one will raise an event and then service 2 will react accordingly.
Now if this answers your question than ok, else specify in what kind of scenario multiple service require to call another service.
If still not solved, you could email me on puneetjindal.11#gmail.com, will answer you
Currently I am decided to continue with the last mentioned approach.
If you want horizontal scalability (scaling for increasingly large number of client connections) for your database you may be better of with a technology that was designed to work as a scalable, distributed system. Something like CockroachDB or NoSQL. Cockroachdb for example has built in data sharding and replication and allows you to grow with adding server nodes as required.
when I am designing my databases as distributed, according to functionalities it may contain 5 databases
This sounds like you had the right general idea - split by domain functionality. Here's a link to a previous answer regarding general DB design with micro services.
In the Microservices world, each Microservice owns a set of functionalities and the data manipulated by these functionalities. If a microservice needs data owned by another microservice, it cannot directly go to the database maintained/owned by the other microservice rather it would call an API exposed by the other microservice.
Now, regarding the placement of data, there are various options - you can store data owned by a microservice in a NoSQL database like MongoDB, DynamoDB, Cassandra (it really depends on the microservice's use-case) OR you can have a different table for each micro-service in a single instance of a SQL database. BUT remember, if you choose a single instance of a SQL Database with multiple tables, then there would be no joins (basically no interaction) between tables owned by different microservices.
I would suggest you start small and then think about database scaling issues when the usage of the system grows.

Resources