00:00:11.059
Hello, my name is Sebastian Sogamoso, and I live in Bogota, the capital of Colombia in South America. You can find me at Seva Soga on GitHub. I work for a startup called Ride, where we are reinventing the way people commute to work. You should definitely check us out! Today, we are going to talk about microservices.
00:00:34.260
I don't want to give a lecture about microservices; there are many excellent resources out there that you should explore. Instead, I want to discuss why I believe that microservices can sometimes be a bad idea, and not just sometimes, but quite frequently.
00:00:59.100
Let's begin by defining what microservices are. Microservices are a particular way of designing software by creating many small applications that can be independently deployed. There has been much discussion about whether microservices merely represent a subset of service-oriented architecture, and to some extent, they do. Microservices are a segment of service-oriented architecture with a defined set of rules. One might say that microservices are to service-oriented architecture what Scrum is to Agile. Additionally, microservices are not just a trend among hipster developers; people have been implementing microservices for about ten years now. It’s simply a name given to a certain set of rules in service-oriented architecture.
00:01:49.560
A point of contention among practitioners is how large a microservice should be. The issue is that microservices are designed to fail—which is in their name. The term micro suggests that they should be very small, but size isn't necessarily the most critical aspect; it’s just one part of what defines microservices. Many people argue that the definition of a microservice hinges on the number of lines of code it has, but that can be misleading as it varies widely depending on the programming language. Others, like Amazon, suggest determining a microservice's scale by the size of the team developing it. While this has some merit, I don’t see it as a definitive approach.
00:02:48.720
Another approach suggested by experts like Chad Fowler defines microservices by their size, claiming they should fit on a developer's screen with their hand. If a service expands beyond this, it no longer qualifies as a microservice. However, I find this criterion somewhat limiting. Instead, I think we should consider concepts from cognitive psychology. Cognitive load refers to the amount of information a person is trying to process at any given time, while cognitive limit refers to the maximum number of chunks of information one can handle in working memory. A service can be called a microservice if the cognitive load it represents is less than the cognitive limit for the developers handling it.
00:03:54.659
When talking about groups of people, the cognitive limit tends to decrease as the team size increases. Thus, the larger the team, the lower the cognitive limit, which can be a challenging dynamic. To illustrate my perspective on microservices, I’d like to share a personal story for context.
00:05:14.100
My first job was at a sports stadium where I sold hot dogs during games. Surprisingly, I excelled at it, leading my manager to delegate additional responsibilities like selling foam fingers and making public announcements during innings. I was always up for the challenge and managed to juggle all these tasks, even mowing the lawn before each game. Eventually, due to staff shortages, I was asked to help people find their seats, which happened to coincide with a One Direction concert at the stadium. That day was chaotic, and I decided it was best to resign.
00:07:36.060
At this point, you might realize that this story is not entirely true; it’s more of a metaphor. I’d like to pose a question to everyone: please raise your hand if you have a system that exceeds your team’s cognitive load and wish to break it down into smaller systems.
00:08:05.940
This is a situation common in software development, especially when dealing with monolithic applications. Earlier today, DHH discussed monolithic applications, and I find myself disagreeing with his definition. So let's delve a bit deeper.
00:08:34.380
I believe that having a single Rails application does not necessarily mean you have a monolithic application. What makes an application monolithic is typically poor object-oriented design. Having a single Rails app does not automatically label it as a monolith. A single Rails app can be well-designed and executed.
00:09:59.040
For example, a recent talk highlighted how Cookpad, a Japanese company, has built what could be the world’s largest Rails application, effectively handling vast amounts of traffic with only one Rails app, possibly running on around 300 servers. Therefore, while some systems might be monolithic in design, it doesn't have to be the case.
00:10:40.920
When you’re working within a monolithic application, you typically cannot reuse parts of your system without messing with the entire system. This is known as 'shotgun surgery' and is a frustrating experience for many developers. Having established this distinction between a well-structured system and a monolithic system, let's discuss when it might be appropriate to transition to microservices.
00:11:06.600
Many people mistakenly believe that converting a poorly defined single Rails app into microservices will somehow improve its design. This notion is a fallacy. When you smash a banana, for instance, you don’t get smaller well-defined bananas; you just end up with a squishy mess.
00:11:43.500
If you cannot effectively design a single application, you likely will struggle with designing a microservices architecture. This concept resonated with a tweet I came across, highlighting that if your design skills are lacking in a monolithic app, they won’t magically improve when you switch to microservices.
00:12:20.220
So when should you actually adopt microservices? A solid reason to do so is when you need a specific part of your system to scale differently than the rest of the system. This has happened to us at Ride, where we had to choose whether to scale the whole application or just a specific part that had unique performance needs.
00:12:53.520
Another reason to consider microservices is when you need parts of your system to be easily replaceable. Many large companies struggle with outdated systems built on old technologies, leading to a lack of resources for maintaining them. When you have business logic well-distributed across microservices, it becomes easier to replace a failing microservice with a newer technology without the daunting task of rewriting the entire application.
00:14:27.979
Another reason to consider microservices is when you want to deploy some parts of your system more frequently than others. If you notice specific components of your application often require updates due to changing business logic or other reasons, a monolith can become cumbersome. Deploying a large app often means sitting on many changes before pushing them out, increasing the risk of failure.
00:15:04.500
For those interested in different technology stacks, microservices offer the flexibility to use varying technologies for individual services. However, be cautious; extreme diversity in programming languages can lead to significant challenges in maintenance and complexity. We at Ride use a request for comments (RFC) process before creating a new service to validate the intended tech stack.
00:15:51.060
The most crucial aspect is that your team should possess the necessary skills to support the microservices architecture. Ensure your team can provision new servers, set up monitoring, and respond to failures quickly. Rapid deployment is vital; new microservices should be able to be deployed to production in minutes, not hours or days.
00:16:42.000
If your team lacks these capabilities, it may be best to postpone transitioning to microservices. However, if your team is ready, it’s essential to acknowledge the potential downsides. The most notable downside of microservices is the increased DevOps effort; teams must be proficient in managing numerous services running concurrently.
00:17:16.620
Another challenge is managing logs for each service, which complicates debugging efforts. Centralized logging is necessary to monitor the entire system effectively. Unique identifiers for each request can facilitate tracing issues across services.
00:18:05.400
Another critical aspect to prepare for is the inevitability of failure. While failure management is vital in any architecture, it's particularly challenging in a microservices environment due to the complexity involved. Common failures include network partitions, service unavailability, or data inconsistencies, which all require planned strategies.
00:18:55.200
The CAP theorem highlights the trade-offs necessary to ensure availability and consistency in distributed systems. As you design your microservices architecture, it's crucial to understand these principles and how they relate to your business requirements.
00:19:43.560
When you take the plunge into building microservices, it's beneficial to employ the bounded context pattern to manage complexity. This involves recognizing that each model may behave differently based on its specific context, which can help reduce the overall complexity of your application.
00:20:35.520
Incorporate executable specifications for each microservice, which allows you to conduct tests based on clear contracts. Synchronous communication is generally preferable to asynchronous communications whenever feasible to ease fault tolerance. Opting for schema-based formats over schema-less ones can also streamline data exchanges between services, making future changes considerably more manageable.
00:21:44.760
When embarking on new microservices, don't obsess over perfection. Start by creating a minimum viable product and iterate as you move forward. It's crucial to avoid sharing databases between microservices, as this creates unwanted coupling that detracts from modularity and can lead to severe maintenance headaches.
00:22:45.300
Be mindful of organizational biases, as mentioned by Conway's law, which suggests that a system's design often reflects an organization's structure. Translation: design systems based on functionality rather than trying to mirror the organization. Finally, remember that a vital 'Golden Rule' of microservices is to allow for independent service deployment. If you're struggling with coordinated deployments, you may negate many benefits of microservices.
00:24:46.800
To summarize, while transitioning to microservices can simplify certain aspects of complexity, ensure this change ultimately benefits your overall system. As Michael Feathers wisely puts it, managing complexity is crucial when adopting this architecture. Embrace microservices if it helps you better manage the complexity of the system you are developing. Thank you for your attention!