Microservices is a hot topic in software development circles these days. And for some very good reasons.
Put simply, the traditional way of building enterprise applications—using a monolithic approach—has become problematic as applications get larger and more complex. So developers are turning to a microservices software development architecture, in which applications are structured as collections of loosely coupled services. This makes them easier to build, and—more importantly—much easier to expand and scale.
Let’s take a closer look at how a microservices approach differs from a monolithic one, and examine their relative strengths and weaknesses.
Monoliths: the way we were
Traditionally, software developers created large, monolithic applications. A single monolith would contain all the code for all the business activities an application performed. As the application’s requirements grew, of course, so did the monolith.
Here is a diagram of how many monolithic applications start out. You write a simple application, which is developed and managed by a single team.
But what happens if your application turns out to be successful? Users like it and begin to depend on it. Traffic increases dramatically. And almost inevitably, users request improvements and additional features, so more developers are roped in to work on the growing application. Before too long, your application looks more like this:
Your once-simple application has become large and complex. Multiple independent development teams are working on it at the same time.
But these so-called independent teams are actually not independent at all. They are simultaneously working on the same code base and simultaneously changing the same sections of code.
What happens when you have five independent development teams overlapping as they work on an application? It becomes virtually impossible to know who is working on what. Code changes collide. Code quality—and hence application quality and availability—suffers. It becomes harder and harder for individual development teams to make changes without having to calculate what the impact will be to other teams, and teams can lose sight of how their code might be incompatible with others, among other issues. This generally results in slower, less-reliable applications, not to mention longer and longer development schedules.
The repercussions are more than just technical: if it’s an important application to the business, development delays, poor application performance, and crashes can end up costing your company customers and money.
Fortunately, this scenario is not inevitable. You can rebuild and re-architect your applications to scale with your company’s needs, not against them. Using a modern, microservices-based application architecture is an increasingly popular technique for building applications that can scale without miring your organization in monolithic muck.
Microservices: A primer
So what exactly is a microservice architecture? According to Martin Fowler, the software guru who has written extensively about the topic, a microservice architecture consists of “suites of independently deployable services” organized “around business capability, automated deployment, intelligence in the endpoints, and decentralized control of languages and data.”
The main idea behind a microservice architecture is that applications are simpler to build and maintain when broken down into smaller pieces that work seamlessly together. When using microservices, you isolate software functionality into multiple independent modules that are individually responsible for performing precisely defined, standalone tasks. These modules communicate with each other through simple, universally accessible application programming interfaces (APIs).
Applications built using microservices possess certain characteristics. In particular, they:
- Are fragmented into multiple modular, loosely coupled components, each of which performs a discrete function
- Have those individual functions built to align to business capabilities
- Can be distributed across clouds and data centers
- Treat each function as an independent service that can be changed, updated, or deleted without disrupting the rest of the application
Microservice architectures let you split applications into distinct independent services, each managed by individual groups within your software development organization. They support the separation of responsibilities critical for building highly scaled applications, allowing work to be done independently on individual services without impacting the work of other developers in other groups working on the same overall application.
In short, your application can grow as your company and its requirements grow. Your application looks more like this:
This diagram shows an application constructed as a series of microservices. As you can see, each microservice has a clear team owner, and each team has a clear, non-overlapping set of responsibilities. In practice, however, some services may come from third-parties, connected via APIs, and may not be totally visible to the application owner.
A brief history of microservices
Martin Fowler has documented that "microservices" as a term was first used at a software architects’ workshop in 2011, when participants found they were individually exploring similar concepts in software architectures in parallel. The group confirmed the name microservices as describing this new paradigm when they met the following year.
James Lewis then gave a presentation at 33rd Degree in Krakow in 2012 in a talk entitled “Microservices—Java, the Unix Way” that outlined microservices as a way to more swiftly build software by dividing and conquering, using Conway’s Law to structure teams.
Microservices, for all its virtues, is not particularly fresh or innovative. Its roots go back three decades in the Unix world. And many people—including this author—say it’s little more than a new spin on service-oriented architecture (SOA) a design principle that was all the rage a decades ago. (SOA earned a poor reputation due to too many failed—and costly—implementations.)
Fowler identified many of the major characteristics that have made microservices unique, with perhaps the most important one being keeping services independent so they can be individually replaced without impacting an entire application. He also established such requirements as organizing services around business functions and using “smart endpoints and dumb pipes,” all of which are aspects of “SOA done right,” as described by industry expert Greg Young during a 2016 presentation at the Microservices Conference in London.
Since that time, use of microservices has accelerated. Indeed, according to Fowler, microservice architectures are fast “becoming the default style for building enterprise applications.”
Although conventional wisdom holds that microservices projects are best suited for implementing brand-new distributed software projects, a recent survey by Red Hat revealed that the majority of businesses using microservices are successfully deploying them to re-architect legacy applications. More than two-thirds (69%) of respondents said that they use microservices for both new applications and for modernizing existing ones.
And the benefits accrue quickly: according to the Red Hat survey, a third of organizations achieve advantages within two to six months of first deploying microservices.
Microservices and containers
It’s difficult to talk about microservices without also talking about containers, a concept that first surfaced in the 2000s with the FreeBSD project. Many developers feel that containers are a natural fit for microservices.
The services that make up an application can be placed within containers that possess the smallest libraries and executables needed by that service or application, making each container a self-contained package. Docker delivers an easy way to create, share, and test container images, and has become very popular among businesses that have committed to developing software using containers.
Although an application within a container operates independently from those in other containers, it still answers to directives from the kernel or other orchestration tool. Such orchestration tools are essential to manage large numbers of containers. Although Docker has its own orchestration capabilities, many dev, ops, and DevOps professionals prefer Kubernetes. (Originally designed by Google, Kubernetes is an open source platform that orchestrates the operations of multiple containers.)
Of course you can build microservices without using containers. But when it’s time to actually run an application made up of many different microservices, you’re going to want a way to manage it all. Containers and container orchestration are well suited to that task.
How microservices enable DevOps
The microservices approach also goes nicely with DevOps, which accelerates the process of getting software from development into production by breaking down barriers between software development and IT operations groups. In a DevOps environment, developers and operations engineers work together seamlessly in an iterative manner to produce higher-quality software faster.
Philosophically, this aligns well with microservice architectures, which helps you make rapid changes to applications within very short production schedules. By simultaneously leveraging microservices and DevOps, software organizations can accomplish things that would have been considered impossible not so long ago. For example, Amazon is able to release new code every 11.7 seconds, while Netflix deploys new code thousands of times per day.
10 key benefits of microservices
According to a recent survey by leanIX, organizations using microservices get new software to market five times faster than those that don’t. Most companies using microservices are so satisfied with the results that they plan to continue using them in the next six months. And 71% of them plan to increase their use of microservices in the next 12 months
The top 10 benefits that organizations realize from deploying microservices include:
- Improved scalability. Because microservices let you independently scale services up or down, the ease—and cost—of scaling is dramatically less than in a monolithic system. Adding new capabilities usually means adding discrete new microservices, not redoing the entire application, which increases both development speed and application stability.
- Better fault isolation. If one microservice fails, all the others will likely continue to work. This is a key part of the microservices architectural design.
- Optimized scaling decisions.With microservice architectures, scaling decisions can be made at a more granular level, allowing more efficient system optimization and organization.
- Localized complexity. Microservice architectures let developers think about services as black boxes. Owners of the service need to understand the complexity of only what is within their service. Other service owners need to know only what capabilities a service provides, without having to worry about how it works internally. This compartmentalization of knowledge and complexity makes it easier to create and manage large applications.
- Increased business agility. Microservices are relatively small and simple, and failure of a microservice affects only that service—not the whole application—so enterprises can afford to experiment with new processes, algorithms, and business logic. Microservices give you the freedom to experiment and “fail fast.”
- Increased developer productivity. New developers can get up to speed rapidly, since it’s easier to understand a small, isolated piece of functionality than an entire monolithic application.
- Simplified debugging and maintenance. For the same reasons that building individual microservices is easier than coding for a monolithic architecture, developers can be much more productive when debugging code and performing maintenance.
- Better alignment of developers with business users. Since microservice architectures are organized around business capabilities, developers can more easily understand the user perspective and create microservices that are better aligned with the business.
- Future-proofed applications. When innovations happen and new or updated technology disrupt your software development process, microservice architectures makes it easier to respond by replacing or upgrading the individual services affected without impacting the whole application.
- Smaller and more agile development teams. In modern software organizations, teams are often organized by the microservices they work on. These teams involve fewer people, and they’re more focused on the task at hand. Jeff Bezos’s famous “two pizza rule”—claiming that a software team that couldn’t be fed with two pizzas was too big—fits perfectly into the microservices philosophy.
6 potential drawbacks of microservices
Nothing is free, however, and microservice architectures do carry their own costs.
- Microservice architectures can be complex. While individual microservices may be easier to understand and manage, the application as a whole may end up with significantly more moving parts. There are often more components involved, and those components have more interconnections. Those interdependencies increase the application’s overall complexity, which can create problems.
- A microservices approach requires careful planning. Because all the microservices in an application must work together, developers and software architects must carefully plan out how to break down all the functionality and dependencies. You can also run into data challenges when starting an application from scratch or modifying a legacy monolithic app. In addition to carefully mapping out individual microservices, multiple iterations can be required until you get it right.
- Proper sizing of microservices is critical, and hard to calculate. If you make your microservices too big, you can end up with all the drawbacks of monoliths. If you make them too small, you move the complexity out of the individual services and into the dependency maps, which makes the application harder to understand and manage at scale. Worse, dealing with complex dependencies typically requires more experienced—and higher paid—developers and architects.
- You may have little control over third-party microservices. Many microservices architectures include services from third-parties, maintained by teams that you don’t have access to. Third-party services can change their APIs (or dependencies) at any time—and in ways that may break your application. If they do modify their APIs, you need to know and be able to respond ASAP.
- Downstream dependencies are difficult to track. One key to microservice success is to limit interdependencies and carefully track ones that you can’t avoid. The application must be able to survive failures of individual microservices, yet downstream problems often happen, and can cascade through the ecosystem. Building fault-tolerance into an application built with microservices can be more complex than doing so in a monolithic system.
- Multiple microservices may offer bad actors more opportunities. As microservices grow in popularity, they may increase your applications’ vulnerability to hackers and cybercriminals. Because microservice architectures allows you to use multiple operating systems and languages when building an application, there’s the possibility of having more “soft targets” for malicious intrusions. In addition, you may not have visibility into the vulnerabilities or behavior of third-party services used by your applications.
Microservices, when used effectively, pay off
Used effectively, microservice architectures allow you to scale your application as the number of developers working on your application increases. The key is to build applications without creating a complex, unwieldy beast at the macro level. That means keep tracking each time a new service is added to your system or a new connection between microservices is made.
It also means examining the complexity increase and making sure it is warranted and well understood. Regularly examining the entire application system is critical to keep an interconnected set of microservices working effectively and reliably.
Although not a panacea, the benefits of microservices are clearly worth it for increasing numbers of modern software organizations. By changing how software development teams are structured, organizations can create teams centered on specific business services and give them both the responsibility and the authority to act as they see best. This approach lets teams quickly move with the business as it evolves in response to market demand without disrupting central business activities. This alignment alone is worth the price of admission.
Monitoring solutions such as New Relic can be used to help track the interconnection dependencies between microservices. New Relic APM, along with products such as New Relic Synthetics and New Relic Alerts, can monitor the performance, operational characteristics, and SLAs of those connections, and alert you when problems are detected.
The views expressed on this blog are those of the author and do not necessarily reflect the views of New Relic. Any solutions offered by the author are environment-specific and not part of the commercial solutions or support offered by New Relic. Please join us exclusively at the Explorers Hub (discuss.newrelic.com) for questions and support related to this blog post. This blog may contain links to content on third-party sites. By providing such links, New Relic does not adopt, guarantee, approve or endorse the information, views or products available on such sites.