5

I have a monolith application on a server and I want to break it into multiple microservices.

Because of that for the moment I have to use the same database for all the microservices and each microservice accessing only his own tables.

So my question is how can I reuse the database connection among microservices and still keep the independently of one another because at some point in the future I may want for some of them to use another database .

I ask this question because I think is an overhead to make a new database connection for each microservice if they all use the same database because a single page logic can use more then 10-20 microservices .

  • 3
    I wouldn't worry about the connection overhead. I'd worry far more about microservices limiting the scope of atomic operations. – CodesInChaos Apr 28 '16 at 8:31
  • 3
    I may just be old, but the idea of a single page that shows things that come from a single database, but has 10-20 microservices in between just sounds like daft design. What's wrong with the monolitihic application, especially if it is so small that it can run on a single server? – RemcoGerlich Apr 28 '16 at 8:55
5

The fact that those different processes use separate connections is (mostly) irrelevant.

The usual concern is that opening and closing a connection is expensive in terms of time and CPU resources. With many databases, this concern is invalid because of connection pooling: there is an overhead the first time you connect to the database, but the next time you need to do a query within the same process, an existent connection is reused under the hood, even if in code, you explicitly closed the connection.

What will happen in your case is that you'll pay the cost of opening twenty connections the first time when twenty microservices start after, for instance, the server reboots. Once this is done, each service will reuse connections already opened before.

What would be a problem is if you have a lot of microservices accessing the database, or if the database, for a given reason, cannot accept too many connections. Since you are talking about twenty microservices, I won't be concerned; for instance, “SQL Server allows a maximum of 32,767 user connections.” (source) If you use a more exotic database or a database which has an exotic configuration or if each service needs, for some reason, to open many connections at once, this could indeed become an issue.

  • The cost of opening and closing connections is not the only thing to be concerned with. Databases perform best when the number of connections is in the ballpark of 2 * # of CPU cores on the database. If your database only has 4 cores, you probably want to keep only around 10 connections open at a time. This is going to be a problem if you have 20 microservices. If you have to do HA and now you have 2-3 copies of each microservice, you're going to end up with way more connections than is optimal. I haven't seen a good way of doing connection pooling well with microservices yet. – Dogs Aug 3 '18 at 17:06
  • @Dogs: oh, thanks, that's interesting. Do you have any reference to back up the claim that “databases perform best when the number of connections is in the ballpark of 2 * # of CPU cores on the database”? I never heard of that, so I'm curious to find more. – Arseni Mourzenko Aug 3 '18 at 20:48
  • 1
    Mostly personal experience, but I would also cite the PostgresSQL docs (wiki.postgresql.org/wiki/Number_Of_Database_Connections) and HikariCP's wiki (github.com/brettwooldridge/HikariCP/wiki/About-Pool-Sizing). If your queries take 1ms to execute, you should be able to serve 20,000 queries/second with those 20 connections and not need more than that. In general, keeping thread/process counts close to the number of cores is a best practice regardless of what you're tuning, be it a ForkJoinPool, a JDBC connection pool, an HTTP connection pool, a large batch process. – Dogs Aug 4 '18 at 23:48
1

Microservices are separate processes, so they can't share database connections.

You split an application into microservices for scalability, resilience, and easier development with large teams. For these benefits, you have to pay a price in (per-instance) performance and more complex infrastructure. Probably the cost of your microservices having to communicate with one another over the network is greater than the cost of having to manage separate DB connection pools.

If the expected benefits are not greater than the costs, just don't do it. Microservices are great for some use cases but they are in no way a silver bullet and in certain cases, benefits will be outweighed by the disadvantages.

  • The other big (potential) win is reducing coupling, so no one microservice implementation ends up constrained by things like the shared dependencies or the programming language or the build system used by conceptually unrelated services. – Ixrec Apr 28 '16 at 9:15
0

Actually there are patterns that defend both cases separate databases and shared databases.

A single database is simpler to operate and a developer uses familiar and straightforward ACID transactions to enforce data consistency. On the other hand a developer working on, for example, the OrderService will need to coordinate schema changes with the developers of other services that access the same tables. This coupling and additional coordination will slow down development.

More information at http://microservices.io/patterns/data/shared-database.html

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.