How to build Microservices wrong
Microservices have got a lot of traction last year. It’s always interesting to read about success stories other people have; they tend to inspire you to try this new trend out in your own project.
However, there are several traps you can fall into if you follow this trend without deep understanding of its fundamentals. Today, I’ll share some bad practices I saw one particular company used on its way to adopt microservices architecture.
Bad practice #1: External architect
One of the most important attributes of microservices is product team responsibility. That is, the team that builds a microservice has to own it and take full responsibility for it.
The company I write about had a separate architect instructing teams how they should implement their microservices. His daily job was designing architecture for new features, deciding what 3rd party libraries and products they should use and so on. Those teams then implemented these decisions in code.
Such approach has a devastating effect. Developers don’t feel themselves responsible for the product they develop. Moreover, as the architect tries to manage multiple teams, he doesn’t have enough time to dive into development process. It leads to breaking the feedback loop as the architect doesn’t spend enough time on the product to analyse how his decisions affect the code. Such approach actually has its own name given by Joel Spolsky: hit and run micromanagement.
Can this situation be fixed? Sure. The architect should delegate the right of making decisions to the teams. Instead of trying to be a lead developer for each of them, the architect has to become an internal consultant. That is, giving advices about how functionality may be implemented, he shouldn’t insist that his opinion is the one they must follow. The team has to make the final decision by its own.
Sometimes, micromanagement approach is justified by stating that the developers aren’t qualified enough to make such decisions. The problem with this justification is that an external architect isn’t able to make qualified decisions either. No matter how smart or technically advanced the external architect is, he isn’t able to do it because he can’t see the whole picture. In order to make right decisions, the architect has to deeply dive into the problem domain, start working with code and talking to customers. And when he does all of this, he is no longer external.
Bad practice #2: Dedicated DBA
The second practice I faced at that company is having an external DBA. Similar to the external architect, that DBA took full control of how database should look like in each of the products. A microservice team had to receive an approval for every non-trivial change in database it was going to make. Moreover, developers couldn’t even backup, restore or profile their database because they didn’t have required permissions. For each of those, they had to ask the administrator.
Of course, the DBA didn’t dive into the development either, so the resulting database structure was rarely optimal. Without day-to-day work with the product, an external DBA can’t make qualified decisions about how the database should look like, no matter how smart this person is.
Needless to say, developers should have the full control for the database they use. There can be a separate DBA, though, but his role should be restricted to being a consultant. More preferably, a microservice team should have a developer that has experience of being a DBA. But, again, this person should be a part of the microservice team.
Bad practice #3: Shared code base
The third practice I consider bad was how shared libraries were used. The company had its own set of utility libraries which was propagated to the teams. The problem was that most of the developers didn’t have access to their source code. In order to find out how a library works, the developers had to decompile it. Moreover, if the library contained a bug, the process of fixing it could last for ages.
One of the core practices in software development is code reuse. But to make this process clear and straightforward, this code should be placed in shared repositories which every team member should have access to. Also, every developer should be able to send a pull request which then should be accepted if, of course, it passes a code review.
As shared libraries are used by every microservice team, no single team should have an exclusive right of controlling them. Teams should share responsibility for such libraries.
Also, shared code should contain utility logic only. Some companies tend to share domain logic which completely breaks one of the main purposes of microservices: setting up clear boundaries between contexts.
Bad practice #4: SDKs over APIs
Another practice the company had is preferring SKDs over APIs. While it’s a common practice for vendors like Amazon to distribute libraries for their APIs, this approach doesn’t make a lot of sense in microservices environment.
Firstly, if you really want to make a good use of the benefits microservices architecture introduces (like using different platforms for different products), you will have to produce SDK libraries for every platform you use. In practice, it leads to sticking to one major platform that every team has to use. But even after that some developers - for example, mobile developers - are left abundant because there’s no simple way to use the same SDK on their platform.
Large vendors ship their SDKs to gain a competitive advantage over their rivals. They really want to lower barrier of entry to get more developers using their products.
You don’t have to do it if you are developing an in-house software. Moreover, you shouldn’t do it. SDKs introduce another level of complexity, making microservice team support not only API to their product but also the code that uses that API. It’s like common backward comparability problems multiplied by two.
In most cases, API can be made simple enough to use it without any SDK library. Leave your developers freedom to choose how they want to use it.
Bad practice #5: Shared environment
Having a dedicated DBA led to using the same database instance for each of the products in that company. The database very quickly became a mess; there were dozens of tables pertaining to different products. Some of them were dead already but no one deleted them because everyone was afraid of corrupting someone else’s product.
This practice, of course, broke one of the main principles of microservices architecture: organization around business features. Every microservice should have its own database instance.
Bad practice #6: Outsourcing
The company tended to outsource some of the microservices to external companies. The reason for that was that the internal developers didn’t have required experience with the technology the company was going to use.
While it’s totally fine to have distributed teams, outsourcing the whole product is a bad idea because after product ends, the knowledge of how to use that technology will leave with the external team.
A better practice would be getting some members of that team to side-by-side work with your developers. That way, your developers will quickly adopt the required experience.
Microservices architecture can bring you a competitive advantage. But in order to get it, you should implement microservices very carefully. Every aspect of your development process should be weighed consciously, don’t fall into cargo cult programming.
comments powered by Disqus