7

My company have recently embark on a platform architecture change from monolithic to microservice architecture. The entire migration might take years so as of now, we would still need to maintain the current monolithic application while slowly dismantling the application.

We dismantle the monolithic application via service oriented architecture in interim for some module (where database is still connected to the monolithic application's database) while some we directly transition to a microservice (the microservice owns its own database if applicable).

We practice releasing feature whenever it is ready instead of following a release window. Each team have their own stagings to manage this thus we have multiple stagings environment (11 in total) each with its own set of the legacy monolithic application.

enter image description here

While transitioning to the microservice architecture (while i understand that when we fully transition to microservice architecture there will only be 1 staging for the entire company), we would need to maintain all those stagings which that means we would need to have a copy of the microservice in each staging environment.

enter image description here

(Did not mean to guide the answers in the direction of this solution. Preferable if there are any answers in a different direction so we can have more options and variations to consider the pros and cons) One of the idea we have is that for each db, we have an additional column to mark which staging this row of data is for. Therefore we can maintain 1 single instance of the microservice for multiple staging. The issue is that for every API call, client side need to specify which staging it is for. It complicates the development of each service (need to cater for which staging's database to filter out), makes the endpoint harder to call (since you need to specify which staging database you need to access) and more important is these are redundant code that is not suppose to be there in production.

The issue we face is as the number of microservices grow, that would take up a lot of server resources (we decided to use on premise server to host our kubernetes and Proxmox VM for the legacy monolith). Is there any infrastructure architecture that would reduce the resources that is required for this?

WKL
  • 504
  • 1
  • 5
  • 17

4 Answers4

0

You could make the Quality of Service for your microservices burstable, by reserving a relatively low amount of memory and cpu for each of the microservices. Then you can overcommit your nodes and rely on the assumption that not all staging areas will need to run at peak performance at the same time.

If many or all microservices share the same database version, perhaps you can host them in separate database schemas on a single high-available database deployment, also reducing the resource footprint.

Of course, this depends on the planned usage of the staging environments. If all teams have their end of sprint demos at the same time the cluster may get overloaded at the peak hour right before then.

flup
  • 26,937
  • 7
  • 52
  • 74
0

I do not fully understand all possible details that you may face, but some points are the following:

  • When migrating to a new microservice architecture via following sth like the Strangler pattern you have to decide who/ where is the source of truth of your data (does not have to be the same for all data).
  • For microservices (MSs) that do not alter the state of the data (e.g. a new search microservice) usually I stream data from the source of truth (e.g. RDS table of the monolith) to other more flexible/ microservices friendly medium (in our case we selected Apache Kafka and that medium is a Kafka topic). The MS reads events from the topic and creates its internal view of the world (i.e. the search example streams events to Elastic Search).
  • For MSs that also alter the state of the source of truth, it is more complex. One good approach in my view is to keep a state of the "source of truth" in your new microservices environment (e.g. accumulate events in a topic that represent an order) and asynchronously stream back to the monolith DB.
  • Different teams (focusing on different new microservices) will own their own topics.
Vassilis
  • 914
  • 8
  • 23
-1

In your case, Kubernetes on-premise can be a solution for you and your team.
You can create 2 or more cluster for your infrastructure. My suggestion is at least 2 cluster. First one is for developing, testing and staging, second is for the production environment.

Now you can confuse how 2 clusters can manage your 11 different staging environment. On the Kubernetes environment, there are namespaces you can create with different names and you can isolate those namespaces. So, in 1 Kubernetes cluster, you can have many more staging or testing or development environment.

But there are few pit holes, you need to worry about. You can search about, I can give suggestions about them. First of all, always have back up plan to re-create your cluster. In some really unlucky situations, some hardware issues or networking cases, Kubernetes cannot connect to worker nodes, in such case, you should ready to create your cluster from zero in minutes.

About your monolithic application, your method is the best way, slowly dismantling it. About the Database side, if it's possible, keeping monolithic DB and creating new DB's for microservices would be better for the future, because you can review your needs and maybe adding some extra fields for analysis or metrics on microservices' DBs.

Before you dismantle your monolithic application, you can even try to navigate traffic between your monolithic app and microsevices with Istio or Linkerd.

  • We are already using Docker & Kubernetes for the new services. I think our concern is more on when we scale the amount of new services that we create, we have to create 11 of each service (one for each staging environment). Updated the question to better reflect the existing infra architecture – WKL Feb 25 '19 at 11:01
-1

If I understand your concern correctly, then you are planning to use a dedicated server for each hexagon, rectangle and DB node in your micro-services based deployment diagram.

The good news is that you can each of those services in same physical box without much operational overhead while making the most out of your hardware resources. Docker containers are answer to that. You can create light-weight micro-containers that can share the same hardware resources. Of course you need to consider on multiple aspects to make sure that you are not overcommitting your resources. Here is a nice explanation on what affects maximum number of containers that can run on a docker host. You will get benefited with a lot of other advantages like ease of deploying new version, rollback to older version, super quick dev environment setup etc.

Docker deployments are getting more and more common even in production by using container orchestration system like Kubernetes or DC/OS.

Vishal Shukla
  • 2,848
  • 2
  • 17
  • 19
  • We are already using Docker & Kubernetes for the new services. I think our concern is more on when we scale the amount of new services that we create, we have to create 11 of each service (one for each staging environment). Updated the question to better reflect the existing infra architecture – WKL Feb 25 '19 at 11:00
  • I see. In micro-service based architecture, how do you deploy each service container? Is that each in a different hardware? If so, it isn't necessary to have a separate hardware resource for each service anyway, just run multiple all containers for 1 staging environment in 1 box. Am I still missing something? – Vishal Shukla Feb 25 '19 at 12:28
  • We have multiple hardware but we are not deploying in any specific hardware. Kubernetes takes care of that. I think the problem we have is that it is too many staging and it will end up taking up too much resource. – WKL Feb 26 '19 at 06:24
  • One of the idea we have is that for each db, we have an additional column to mark which staging this row of data is for. Therefore we can maintain 1 single instance of the microservice for multiple staging. The issue is that for every API call, we need to specify which staging it is for. It complicates the development of each service (need to cater for which staging's database to filter out), makes the endpoint harder to call (since you need to specify which staging database you need to access) and more important is these are redundant code that is not suppose to be there in production – WKL Feb 26 '19 at 06:31
  • I don't think additional column is an option, as I assume idea of staging environment would also be to have possibility to deploy different version of the code in different environment. I assumed you anyway need those staging environment and separate version of service for each of them. You are looking for some way to work around that and reduce them? – Vishal Shukla Feb 26 '19 at 06:37
  • Exactly. Looking for a way around this and reduce them while maintaining the 11 distinct databases for each staging environment – WKL Feb 26 '19 at 09:04
  • Instead of adding column, may be you can use DB schema discriminator coming to micro-service and have a component responsible only to chose the DB schema to be used and provide corresponding DB Connection object, which may correlate to a specific staging environment. Hence, you won't clutter your prod code with unwanted code too as you mentioned in your earlier comment. Does that make sense? – Vishal Shukla Feb 26 '19 at 09:08
  • @VishalShukla I'm unfamiliar about DB schema discriminator. I tried to google but I can only find about Mongoose having this as the feature. does this mean the microservice have to implement some of the code that selects which DB/schema? – Zakir Hyder Feb 28 '19 at 09:29
  • @ZakirHyder yes, by discriminator I just mean that use a flag to indicate the environment and eventually select DB/schema. It can be done in clean way by centralizing db selection code and passing the flag/discriminator in ThreadContext. – Vishal Shukla Feb 28 '19 at 09:34
  • sorry, it does seem like same thing as adding "additional column". so instead of adding column this will have system which returns db name so to speak. The api still needs to cater for flag/discriminator, so the client needs to send this flag. If I understadn you correctly – Zakir Hyder Feb 28 '19 at 09:45
  • "The api still needs to cater for flag/discriminator, so the client needs to send this flag." -- Right. It was a constraint mentioned in the question and discussion in this answer. I don't think this is how micro-services are supposed to be developed. But given the constraints of the question and the solution asked, this is the best I can think of. – Vishal Shukla Feb 28 '19 at 10:17