SDD 2023 started out with a fullday workshop and I choose to attend Alan Holubs workshop on microservices. I have attended talks with Alan Holub before, and he is truly a great speaker. He is very good at getting the audience involved and he does have some opinions that can be a bit provocative. But I actually like the provocative opinions, because it really makes you take a step back and see the way we do things from another perspective and that is something that can be really rewarding in the long run.

So what is a microservice? 

  1. An application single, small and clear responsibility
    1.  A biproduct is that the code base is very small 
  2. Independently deployable
    1. Can be deployed without other applications needing to know and without other applications needing to be deployed simultaniously
  3. Decentralized
    1. Can be deployed anywhere and do not rely on other services or applications being deployed in the same datacenter or environment
    2. Cannot share a database with other applications or services
    3. Should enforce authentication and authorization
  4. Fully autonomous
    1. Can handle faults and spike loads. Will not let faults ripple to other services
  5. Highly observable
    1. There is a need for good logging and monitoring of a microservice in order for the team to react, analyze and solve problems very fast

One of the main differences from the monolithic architecture, is that microservices are completely independent. That means that they do not share a database with other microservices. They might have a database of their own, to support the work that they are doing, but they will never have access to a database that is shared between other microservices. This is a quite a big change, when you compare to the way a monolithic application works, where each service in the monolith have access to the same database.  

"You want to avoid a situation where one change results in deployment of multiple services" - Allan Holub

Notify the tiny titans

All data that the microservice need must be served when the microservice is invoked. This typically happens in one of two ways. Either the microservice has a subscriber that subscribes to messages on an event bus (ie. RabbitMQ, Azure Service Bus, ZeroMQ) - this is the most normal and effective approach. Some microservices have a requirement to be able to receive requests from "the outside world" and have a REST interface. This approach should be held to a minimum due to the performance hit of HTTP requests.

Microservices are hard

Microservices is not a silver bullet though. The architecture has to be well planned and implemented with good attention to detail - if it's not, it can be even more complex than the good old monolith architecture that we all (most of us anyway) are trying to get away from. But if you implement it with a solid plan and attention to detail, microservices can be a very liberating architecture to work with. But it is very important to understand that creating a microservice architecture will introduce complexity and will require you to handle problems that is not prevalent in a classic monolithic architecture.

Tiny footprints for tiny titans

In order to mitigate the complexity that is introduced to the overall architecture, when you start to implement microservices, it is recommended to keep the implementation of the individual microservice as simple as possible. For instance if you need to temporarily store some data, then save it in a file using JSON. File read and writes are plenty fast and as long as it is not holding thounds of rows of data, a file can fulfill the need. Do not be tempted to add a database unless you absolutely need it. It will only add to the complexity of the overall solution, because you need to set up the pipeline to maintain the databaes (and you have to pay for it as well!).

Conclusion

In the vast software kingdom, microservices have emerged as the rulers, dethroning the monolithic giants of the past. Their agility, decentralization, and scalability have paved the way for a new era in software development. As we conclude this exploration, it's clear that the tiny titans of microservices will continue to shape the software landscape, offering new possibilities and unleashing the potential for innovation. Long live the reign of microservices in the software kingdom!

Jules Mays full-day workshop called "Coding like your life depends on it" covered a lot of ground. The main subject is how we, as developers, should tackle everyday work. It does not matter if it is a new feature or a bug fix, we have to "code like our lives depends on it".

 

There were a lot of very complex topics - too complex to cover in a summary-style blog post like this (and there is definitely some things that I will have to investigate further, before fully understanding it). However, there were a few points that really struck home for me. The points that Jules May made about software are absolutely spot on. We cannot take quality for granted!

 

Software quality

It is in the nature of the beast that we as humans are flawed. This also applies to programmers. All programmers introduce bugs in their code, no matter how skilled they are. The question is how we handle those bugs and the measures we take to discover bugs as soon as possible. We must realize that the earlier in the development process we find and fix bugs, the cheaper and faster it is. 

 

As a developer, we face many challenges. Our main responsibility is to implement features described by the business. This is something that we are comfortable doing. But we also have the responsibility to demand of the business that bug fixing and technical debt must be prioritized. All too often the business only have focus on which features should be implemented next, so that the sales department has a new shiny gadget they can sell. However if the business does not embrace the fact that all software systems have technical debt - and that the technical debt is exponential over time - the software will suffer a slow and painful death. Each new change will be more and more time-consuming to implement, eventually making it impossible to keep working on.

 

To prevent the total collapse of a codebase, it is empirical that the developers take responsibility for the code base and clearly communicate that the quality of the code base must be prioritized on equal terms with new features. The developers must do this since the business does not have the skill set required to recognize the importance of eliminating technical debt and improving the quality of the codebase.

 

"Software quality is not a luxury that we can take for granted - Jules May"

 

Keep asking 'why'?

In criminology, the broken window theory, states that visible signs of decay eg. a broken window that is not replaced in a building, will create an environment that encourages additional disorder. The same concept applies to a codebase. If there's no structure and/or the quality of the existing code is not up to par, chances are that the next time someone makes changes to the codebase, the new code will be of equal or worse quality. This will make the overall quality of the code deteriorate more and more over time.

 

To mitigate this, developers should be encouraged to take responsibility for the changes they make. One of the ground pillars of this is understanding the general architecture and adhering to it when adding new features. It is also important to find the root cause of a bug when trying to fix it.

 

"Find the defect that is causing the malfunction, instead of just patching up the malfunction - Jules May"

 

A good way to try to get to the button of a malfunction and thereby find the defect that is the culprit, is to open the debugger and keep asking 'Why did this happen?'. Keep asking 'why' until it is not possible to ask the question anymore; then you have found the defect that should be fixed. Doing this will improve the quality of the codebase immensely.