In this series, we’ve laid out a set of principles to help you determine when using microservices is a more effective framework. Today we’ll look at the second principle in detail: the independent lifecycle.
The concept of an independent life cycle is huge. The multiple change speeds discussed earlier are part of this concept. We often find that parts of code need to be committed to the production process alone. How can this situation and microservices help?
An all-in-one approach often hampers our ability to deliver quickly, run A/B tests, and understand our users. Think back to the widget. IO example, which looks like this:
In our hypothetical scenario, business leaders identify new business opportunities that need to be brought to market quickly. General integration applications didn’t allow us to iterate fast enough, so we made “Project X” a standalone microservice. “Project X” has its own code repository and deployment pipeline and thus has an independent life cycle. This will help us develop “Project X” as we learn more about business opportunities.
Independent lifecycles improve developer productivity
Quick to market is not the only reason we deploy a separate life cycle for our modules. We can also increase developer productivity!
Few developers would say that an all-in-one app helps them be productive. They need to wade through lengthy developer setup guidelines. Construction takes many days, and it can take a developer months to get up to speed on a project. By narrowing down the scope, developers can bury their heads in microservices in a day or two and build in minutes or less. If the build breaks, engineers know right away, and they can take immediate action to fix the problem.
A smaller code base also means it’s easier to test microservices.
Tools such as the Spring Cloud Contract can help us ensure that our services work well and work well with other services. Do not have to deal with an integrated application of the 80-hour regression suite. Instead, you can build a fine-grained set of tests for microservices that are executed on each commit. Rather than a “one size fits all” testing approach, appropriate tools and techniques can be used to specify the individual environments of microservices. Instead of one-off performance tests, microservices can be reviewed on an ongoing basis. As a result, the quality of the code is greatly improved.
From Code to Production: A Tale of Two Cities in two Life Cycles
Let’s compare integrated applications and microservices more concretely from a lifecycle perspective, that is, how new code moves from a developer’s laptop into production.
Not so long ago, many IT departments took a single-software development approach. Projects are done in a typical waterfall fashion, with quarterly or annual releases. The code may need approval from one or two review committees before it goes into production. This seems very logical, but it often leads to anxiety and sleepless nights and weekends, like a war. The shared life cycle means that each module is constrained by the module that takes the longest to “commit to production”; It also means that every line of code goes through the same process, regardless of which stages are most appropriate.
The point of microservices is flexibility, including a custom deployment pipeline. We no longer have to push every line of code through exactly the same process. Similarly, microservices give us the ability to choose the best technology for the job and the freedom to use the appropriate combination of tests, code inspection tools, and code quality scans for each microservice.
Fine-grained components, or microservices, also make it easier to align with architectural goals. When refactoring code, it is critical not to violate key elements of the architecture. But how do we ensure that many developers working as small, independent teams adhere to this? The answer lies in fitness functions, derived from evolutionary computing, that allow us to test architecture fundamentally. For each microservice, we can select appropriate fitness functions to ensure that the design evolves to support key quality attributes.
Hypothesis-driven development
An independent lifecycle makes our lives better and allows us to make more informed decisions about how software evolves. Over the course of my career, I’ve had countless debates with fellow software engineers and customers about potential solutions to given scenarios. There are always strong ideas, but data is hard to come by. We can only make decisions based on what little information we know and in the expectation of the best results.
Of course, even if we were wrong, the long deployment cycle caused us to change course months later. These limits make us conservative. We were afraid to alienate our users by trying to break the rules.
Predictions are hard, especially about the future. – Niels Bohr
The science of hypothesis driven development is simple. Form a hypothesis based on your observations, and then design experiments to test the theory. What if we took high school science lessons and applied them to software? By leveraging hypothesis-driven development, we can make more informed decisions around software. Independent life cycles make this possible!
By taking hints from a traditional user story, we can get something like the following:
Such as:
We can usually turn this structure into a fitness function and execute it periodically on our code.
When a service has its own “commit to production” process, we can run multiple trials in response to actual results, rather than spend a lot of time debating the future. Today, companies like Google and Amazon run multiple trials a day. They continuously perform A/B testing to get hard data on the impact of A given design on key metrics. What customers don’t want to continually improve their products to fit more closely with their needs? On a more practical level, what companies wouldn’t want to deliver this kind of service? This is another reason why microservices are so popular!
Master the independent deployment pipeline of microservices
Of course, your microservices still have to run. This raises several interesting questions: How do you get the service to work? How do you know you can trust them?
When we call an application or microservice “production-ready,” we place a great deal of trust in it, that we believe it will work in a reliable way and get the job done.
– Susan j. Fowler
The key is to deploy the pipeline.
The deployment pipeline provides us with a stable production path. If you deploy once or twice, you won’t become an expert on a given task. As knowledge builds on repetition and is deployed frequently, you develop digital muscle memory. If we only unit tested or checked our code randomly, we wouldn’t have improved much. If we let the code go through the same process every time we commit, we have a trusted process in place.
To ensure that the code we deploy to production meets expectations, it should go through a rigorous process. Tools such as Concourse, Visual Studio Team Services, and Jenkins can help you create a robust pipeline. We can design appropriate “thresholds” and trust our code to overcome the challenge.
These assembly lines were once a one-off product of customisation. Now, we can start with projects such as Spring Cloud Pipelines or dotnet-pipelines. By following the Build /test/ Stage/PROd flow process, we can quickly deploy and run in the environment. By shortening the “from conception to production” cycle, we can be confident that the code will do what we expect.
conclusion
Speed to market is all about success or failure. Sticking to an old process because “that’s how we’ve always done it” is a recipe for failure. Fortunately, in 2018, we offer proven models and practices that can help shorten your time to market!
Given the need for rapid iteration, an independent lifecycle is probably one of the least appreciated advantages of microservices architecture. Figuring out which parts of your code need to have their own “commit to production” process can be a valuable learning tool.
Separate lifecycles are only part of the microservices puzzle! Stay tuned for “standalone extensibility” in the next part of this series.
Check out previous articles in the series:
-
Micro services are so hot, should I also use micro services?
-
Micro services are so hot, should I also use micro services?
Click to read the original article to view the English blog