© Akos Hochrein 2019
A. HochreinDesigning Microservices with Djangohttps://doi.org/10.1007/978-1-4842-5358-8_1

1. What are services?

Akos Hochrein1 
(1)
Berlin, Germany
 

Services have been around humanity since before the agricultural revolution. Whenever we go into a store or a restaurant, we are using a service. Some services are more complex than others and provide goods to us that are more tailored to our taste or require less effort to work with, whereas some of them are more specialized, focusing on a single task and doing that really well. Let’s take a look at a simple example.

Both a market and a restaurant qualify as services, and even though, they provide us with different things, both of them give us the general item of food. When you enter a market, you can buy various ingredients from various sellers. Later on, you can combine all of these ingredients into various dishes of your liking at home. A fancy restaurant, however, will provide you with delicacies made on the spot. There are many processes and systems working in the backend of a restaurant, most of it you have no sense of, but after your request if processed, you get your meal delivered.

The restaurant/market-stall analogy is just one of many that we can bring up when we are talking about services. Conceptually, they work the same way as services in software.
  1. 1.

    You, the client, approach the service with a request.

     
  2. 2.

    The service, in our case the restaurant, receives your order.

     
  3. 3.

    Some algorithms and processes in the background (the recipes and the chefs) prepare a response for you.

     
  4. 4.

    You receive the aforementioned response (most of the cases, at least).

     

A service could be your application that serves people on their phone information on the number of times they left their home yesterday. Or a service could be a massive continuous integration system that you only see a small portion of that runs your application’s tests. A service could also be something tiny in software, an application that provides an interface to get information about what time it is in Budapest, Hungary.

In this book, we are going to focus on services that reside on the web, serving data to the end users and to other, internal services alike. Let’s begin by taking a look at the different definitions that emerged in the industry.

Service Lingo

In the past couple of years, there has been a lot of buzz around service design, software as a service, microservices, monoliths, service-oriented architecture, and so on. In the next figure, it is plain to see that microservices are becoming more and more popular. Figure 1-1 provides a graphical view of Google searches of “microservices” over the past five years.
../images/481995_1_En_1_Chapter/481995_1_En_1_Fig1_HTML.jpg
Figure 1-1

Popularity of the term “microservices” since 2014, Google

In the following sections we will try to make some sense on what each of these mean and what are the important terms you need to remember when you are working in systems like these. Please keep in mind that these terms are not etched into stone.

Software as a Service

The term “software as a service ” (or SaaS) mostly describes a licensing model, where you can pay for the usage of some sort of online service. Most of these software live in the cloud and provide various ways for the end user to modify and query data in their systems. One example here is Spotify, an online music streaming software, which end users can use to listen to music and create their own playlist. Furthermore, Spotify has an extensive software interface and packages which engineers can use to fetch and modify data in the Spotify cloud programmatically.

Service-oriented Architecture

Service oriented architecture (or SoA) is probably one of the favourite terms in the industry. In simple terms, this style of architecture design supports services more than anything. A service, as we learned above, needs to serve some sort of business need and needs to be modeled around real world requirements. Services need to be self contained and have a clean interface with which they can be communicated with. They are deployed and developed independently and represent a unit of functionality on an abstract level. The architecture also involves the communication protocols used between these services. Some software as a service companies use service-oriented architecture to deliver quality products to their end users.

Monolithic Service

One of the dreaded words of the decade for software engineers. Monolithic applications and monolithic services are single services that grew too big to be able to reason about. What “too big” means exactly will be one of the core topics of this book. We will also see that this dreaded word does not necessarily mean something bad.

Microservice

The other dreaded word of the decade for software engineers (although, for different reasons). A microservice, in short, is a service that lives in a service-oriented architecture and is easy to reason about. These are loosely coupled, lightweight components which have a well defined interface, a single-purpose and are easy to create and dispose of. Due to the fine-grained nature, more people can work on them in parallel and ownership of features becomes a cleaner problem to solve for the organization.

Now that we’ve taken a look at the high level definitions, let’s do a deep dive into monoliths.

Understanding the Monolith

As we’ve learned, monoliths are codebases that grew too big and too difficult to reason about by a single developer or even a team of developers, their complexity has reached a point where changing even just a couple of lines of code can have unintended and unknown consequences in other parts.

The first thing we need to lay down here as a foundation is that monoliths are not inherently bad. There are multiple companies that have built successful IT businesses on monolithic applications.

As a matter of fact, monoliths are actually great for growing your business. With small administrative overhead, you can add more features to your product. The ease of importing modules with just a couple of key combinations in your IDE makes development a breeze and gives you rushing confidence about delivering a lot of code (be it high quality or low quality) to your employer. Just like most growth processes in life, companies, and with that, software, needs to start fast and go through rapid iterations. Software needs quick growth so the business can get more money, so the software can grow more, so the business can get more money. You get where this is growing. So the next time you attend a conference and hear a speaker say that monoliths are systems of old design, make sure to take it with a pinch of salt. As a side note, I would like to mention, that if your startup is struggling with the maintenance of your legacy monolithic application, it is usually a sign of a healthy business.

However, tendency shows that this rapid growth tends to slow down as often over time reliability and scalability of software gets more and more important. Having a single application might earn your team fast deployment and easy-to-maintain infrastructure, but it also means that the mistake of a single engineer can bring down a whole application. The more people start working on a single application, the more they start disturbing each others work, the more they need to have unnecessary communication and the more they need to wait for their builds and deployments.

Imagine the following situation: you’re an infrastructure engineer working for a company that streams videos as a service over the internet. The company is struggling, but somehow the CMO manages to get the government of your country to stream the presidential election speech. This is an amazing opportunity for your company to grow, so there’s a lot of investment going into making sure that the system takes the load well. The weeks before the event, you’ve done plenty of load tests and instructed the backend engineers to fix certain parts of the code that is not performing as it is supposed to. You’ve convinced the COO to pour some money into heavier infrastructure, so the load will ease over the system. Everything looks perfect for the speech and you’re anxiously waiting for it with your colleagues at the time of the event to experience the marvel of what you’ve been working on with such dedication in the past couple of weeks. Then it happens. Right before the speech, the stream stops. You have absolutely no idea what is happening and start furiously looking for answers. You try to SSH into the machines to no avail, getting rejected without remorse and the minutes are passing. It’s been 13 minutes for the outage and the speech is nearly over. Twitter is on fire tagging your company on where they can watch the presidential speech and blaming the incompetence of the CEO. In a furious rage, decide to hard reset the machines on the cloud provider website that you’re using, but it’s too little too late. The event is over. Millions are disappointed and the company is not in a very good shape to get the next round of investment. 2 days later you get back to work and start doing some investigation on what had happened. Turns out, the ads team has rolled out some changes 2 days earlier that caused a memory leak in the backend application. The memory on the servers got full and blocked all processes. This was when you started dreaming of a better and more reliable future for your company’s infrastructure.

Figure 1-2 is a simple illustration of what had happened at this video streaming company in the application.
../images/481995_1_En_1_Chapter/481995_1_En_1_Fig2_HTML.png
Figure 1-2

A full outage caused by a tightly coupled broken component

The story above, albeit completely made up, happens in the life cycle of every successful software system and every successful software company. If you think Facebook or Google have never had hour long outages at important moments in their lifetime, you’re very much wrong. You can find documentation about various Google1 outages online, with (sometimes) detailed descriptions on what parts of the system caused this and that parts to be down for this and that amount of time. After these outages they learn, adapt and make their systems more resilient so the same problem doesn’t occur again.

There is an aspect of monolithic applications that many people don’t think about that I like to call the “monolithic waterfall” or “cascading monolith” architectures. This basically means that when you’re working on a monolithic application you’re almost encouraged to design the architecture of your code and your data in a monolithic way. Designing interfaces around your modules becomes a chore and just overhead, so you just import the line that you need. Adding a new database for subscription information takes way too much time and would just introduce more complexity, so you create the models in the same database as your user and product information resides. If you’re working on a monolith, all layers of your code and architecture will be monolithic. Naturally, strict coding guidelines, architecture principles and a challenging engineering culture can build and maintain a monolith with clear internal interface boundaries that can later be broken down into microservices with more ease.

Now, it would not be fair to not mention the benefits of monoliths again here at the end of this part. All horror stories above and negativities aside, the recommendation is to grow your business and your engineering by utilizing the monolithic model. Just make sure to keep a tight grip on the steering wheel and everyone is on the same page about technical debt.

Now that we have an understanding of how a monolith looks and acts like, we will take a look at it’s counterpart for the book, the microservice.

Understanding the Microservice

Just to recap: a microservice is a single purpose software application that resides somewhere on the web, is a small-ish codebase and can be reasoned about easily even by a single engineer.

Just like we learned about monoliths that they are not the spawn of Satan, we are going to learn about microservices that they are not a silver bullet either.

Let’s go back to our infrastructure engineer in the previous story. After the incident he ran a post mortem (if you don’t exactly know what that is, don’t worry, we will explore it later in the book) with the rest of the company and came to the conclusion that one of the best solutions that the company could take to avoid such catastrophes as they had a couple of weeks ago during the New Year’s Speech, is to adapt and implement a microservice based architecture and leave the monolith behind. He outlined the costs that it would take from the engineers and the investors and made sure that everyone understands the benefits and drawbacks of a migration. Soon later, the board gave a go to the project. Some time later the company already had a dozen of services running in the cloud (still including the remainders of the monolith), and another campaign kicked in. This time the load was high, but the system kept resilient. Despite the chat services going down, the video playback still worked, making sure that the company reputation is intact and the investors have put their money in a good place. Our engineer went back to bed knowing that there will be no issues ever again around the core business and lived happily ever after. In the following figure 1-3, we can see how we lost our coupled architecture from our previous figure and only have a partial outage now.
../images/481995_1_En_1_Chapter/481995_1_En_1_Fig3_HTML.png
Figure 1-3

Components that are loosely coupled might only cause partial outages

Is that it? Well, no. In the above story our company had a service that ran the chat systems, but the core business was still most likely residing in the monolith. If the chat system were there, it is completely possible that this marketing campaign would have been a disaster as well, causing the end of the company for real. In conclusion, building or extracting even small modules in your system can cause big wins in critical situations.

You can hear dozens of these amazing stories when you go to conferences, I myself gave a couple of them. In most of these success stories there is a small but significant thing that the presenters (including myself) don’t really like to talk about. This is the amount of time that was invested into making sure that a systems that is described above works on a software level and works on an organizational level as well. In most cases implementing a working microservice architecture takes years of engineering work which involves not just coding, but architectural plans, vast amounts of tooling, research of current systems, release plans, meetings, meetings and meetings, and last but not least, patience.

Keep in mind that a switch like this can be an excellent way to enable engineers in your organization to grow and to test their knowledge not just in technical but organizational matters as well. It’s a great opportunity to retain senior engineers at your company and to enable regulars and juniors to explore new frontiers of the full stack that they didn’t need to touch yet.

At this point, it might seem like a great idea to start your entre architecture with microservices. Let’s explore this option in the next section.

Early Design Choices

Speaking from experience, one of the biggest mistakes a company can make nowadays is starting building their architecture using microservices. Albeit the tooling of today is vastly superior to the tooling of let’s say 5 years ago. We have amazing orchestrators, like Kubernetes, containerization tools, like Docker, various services on AWS, like EBS that help us build and deploy services. However, despite the amazing tooling, development could go to hell very quickly.

The thing that a business needs in the beginning (as we already talked about this briefly) is agility. Rapid changes on the data, logic and presentation level to ship as many user features as possible. Designing and building services, on the other hand, take time, dedication and hardcore processes. Subsequently, starting your engineering culture and development processes with a microservice architecture might lead to a disaster.

I myself worked in a system that was designed from the get go to be “microservice” oriented. On paper, everything looked fantastic. The services had clear interface definitions and all of them had owners. These services got compiled together and communicated with each other through an asynchronous, event based system. The build process used a very established build orchestrator as the base system and was optimized to help all the engineers succeed. After so much praise you can expect that the result was negative. Yes, it was. Everything looked perfect in theory, but most of the things failed in practice. The systems were too distributed and dependencies became a burden instead of enablers. Engineers needed speed and not a system where they needed to bump versions every single component when they updated another one. Maintaining the interface definitions became a nightmare after a while as it was difficult to understand cross-dependencies and versioning among the components. Engineers were looking for customized and unregulated shortcuts more than they were engaged in the current working methods. The build system, albeit very professional, was deemed to be too early for it’s time, slowing down developers more than enabling them to speed up development.

Later on the company decided to merge together the microservice architecture into a monolithic application and things started to speed up afterwards. Ultimately proving the system to be successful. Eventually the codebase grew too big and teams started to think about ways of splitting it again.

Was it a bad idea to start with microservices? Was it a good idea to move to a monolith, whereas the engineering norms dictate that you should be moving into another direction?

The answer to the first question is not so obvious. If the company was bigger, the engineering culture was designed around this type of architecture, and there would’ve been more time invested into tooling, then probably it would’ve worked out. However, mid to small size companies often cannot afford the dedicated engineers for tooling. Large companies, with spare capacity on their hand, on the other hand can design their systems using these philosophies from the get-go.

As for the second question, no matter who you ask, the answer will be a resounding yes. In this story, one of the great exemplars is the ability to be able to look back and take two steps backwards to make a gigantic leap forwards on the long run.

One of the morals of the story is that in order to make this leap, you need to understand not only the technologies and the best practices in the industry, but you also need to understand your business, organization and the people who work at your company as well. What might work for other companies (and in some cases even just other teams in your engineering organization) might be a huge misstep for you.

Summary

In this chapter, we have learned the basic linguistics that you can use when talking to your colleagues about microservices over office coffee. We’ve also learned that monoliths are not inherently bad, they can even help grow your business just as rapidly as microservices can slow you down if you use them at the wrong time, but in the long run, can change the way how your users interact with your systems for the better. In the rest of the book, we are going to explore exactly what is required of you, the engineer, product owner, architect, to make sure that adapting to this mindset of development will be a good addition to your company and not an agile disaster.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.117.103.219