Academia.eduAcademia.edu

. Carnell SMiA MEAP Microservices

MEAP Edition Manning Early Access Program Spring Microservices in Action Version 1 Copyright 2016 Manning Publications For more information on this and other Manning titles go to www.manning.com ©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders. https://forums.manning.com/forums/spring-microservices-in-action welcome Thank you for purchasing the MEAP for Spring Microservices in Action. It is an exciting time to be a Spring developer, because the Spring Framework has done something that very few frameworks have been able to do: stay relevant in the face of constant technical change. As more and more applications have moved to the cloud, the Spring development community has responded with Spring Boot and Spring Cloud. These two Spring frameworks will allow you to quickly build microservices that are ready to be deployed to a private corporate cloud or a public cloud like Amazon Web Services (AWS) or Pivotal’s CloudFoundry. You do not have to an in-depth cloud experience to benefit from this book. To take advantage of this book you should have an established background in Java and Spring (2-3 years). Some building web-based services (SOAP or REST) is helpful. Other then that, you just need a willingness to learn. I first encountered Spring Boot and Spring Cloud while working as an Integration Architect at a Fortune 500 financial services company. More and more of my job did not involve building applications, but rather building services that were going to be deployed to a cloud. I found existing SOAP-based web services, even Spring-based ones, were tedious and time-consuming to deliver. The SOAP protocols were complex and difficult to work with. Furthermore, as we began deploying more and more cloud-based services, the operational infrastructure needed to keep a services-based application running was immature. I spent many an evening as part of our critical situation team trying to bring back up an application that had crashed because of a failure in one or more of the services it depended on. The concept of a microservice architecture is appealing because it shifts development away from building heavy services based on the SOAP protocols to a much simpler REST/JSONbased service model where an individual service is very constrained in the work is does. However, any architecture is only as good as the tools and languages that can implement it. When I discovered the Spring Boot and Spring Cloud frameworks, I realized that these tools provided the capabilities I needed to build microservice architectures, while still leveraging my years of experience with Java and Spring. I was so impressed with the power these frameworks brought, that it one of the reasons why I chose to write this book. Books are a labor of love and one the deepest expressions of an authors experiences and knowledge. I hope you enjoy this book. While it has been a lot hard work to get to this point in the MEAP, I look forward to hearing your comments and feedback as you explore this existing technologies with me. —John Carnell ©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders. https://forums.manning.com/forums/spring-microservices-in-action brief contents 1 Welcome to the cloud, Spring 2 Building microservices with Spring Boot 3 Controlling your configuration in the cloud with Spring Cloud Config 4 Service discovery with Spring Cloud, Netflix Eureka, and Ribbon 5 When bad things happen: client-side resiliency patterns with Spring and Netflix Hystrix 6 Service-level routing with Spring Cloud and Zuul 7 Event processing in the cloud with Spring Cloud Stream 8 Getting ready to launch: getting your Spring Cloud application ready for deployment 9 Pushing to the cloud: how to leverage AWS and CloudFoundry to deploy your Spring Cloud applications APPENDIXES: A Setting up a desktop cloud: using Docker Machine and Docker Compose ©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders. https://forums.manning.com/forums/spring-microservices-in-action 1 1 Welcome to the cloud, Spring This chapter covers • What are microservices • The drivers for changing to microservices • Different patterns of microservice development • • The cloud and how microservices are a great natural fit for cloud applications How Spring Boot/Cloud supports microservice developments The one constant in the field of software development is that we as software developers sit in the middle of a sea of chaos and change. We all feel the churn as new technologies and approaches appear suddenly on the scene that cause us to re-evaluate how we build and deliver solutions forour customers. One example of this churn is the rapid adoption by many organizations of adopting and building applications using microservices. This book is going to introduce you to the microservice pattern and why you should consider building your applications with them. We are also going to look at how we can build microservices using Java and two Spring framework projects: Spring Boot and Spring Cloud. If you are a Java developer, Spring Boot and Spring Cloud are going to provide an easy migration path from building traditional monolithic Spring applications to microservice applications that can be deployed to the cloud. The concept of a microservice originally crept into the software development community’s consciousness around 2014. A microservice is ansoftware design approachbased around the concept of building applications out of very small, loosely coupled and distributed services. • Application logic is broken down into very small grained components with well defined • Each component has a very small domain of responsibility and is deployed completely boundaries of responsibility that coordinate together to deliver a solution. ©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders. https://forums.manning.com/forums/spring-microservices-in-action 2 independently of one another. Microservices should have responsibility for a single part of a business domain. Also a microservice should be reusable across multiple • applications. Microservices communicate based on a few basic principles (notice I said principles, not standards) and employ a very lightweight communication protocols (e.g. HTTP and • JSON) for exchanging data between the service consumer and service provider. The underlying technical implementation of the service are irrelevant because the applications always communicate with a technology neutral protocol (JSON is the common). • This means an application built using a microservice application could be built with multiple languages and technologies. Microservices by their small, independent and distributed nature allow organizations to have small development teams with well-defined areas of responsibility. These teams might work to towards a single goal of delivering an application, but each team is responsible for only the services they ae working. I often joke with my colleagues that microservices are the gateway drug for building cloud applications. You start building microservices because they give you a high degree of flexibility and autonomy with your development teams, but you and your team quickly find that the small, independent nature of microservices makes them easily deployed to the cloud. Once the services are in the cloud, their small size makes its easy to start up large instances of the same service and suddenly your applications become more scalable and with some forethought more resilient. 1.1 What is Spring and why it’s relevant to microservices Spring has become the de-facto development framework for building Java-based applications. At its core Spring is based on the concept of dependency injection. In a dependency injection framework that allows you to more easily manage large Java projects by externalizing the relationship between objects within your application through convention (and annotations) rather then have those objects have hard-coded to know about it each other. Spring’s rapid inclusion of features drove its utility and the framework quickly became a lighter weight alternative for enterprise application Java developers looking for an alternative to building applications using the J2EE stack. The J2EE stack, while powerful was considered by many bloat with many features that were never used by the application development teams. Further, a J2EE application forced you to use a full-blown (and heavy) Java application server to deploy your applications. What is amazing about the Spring framework and a testament to its development community is is ability to stay relevant and re-invent itself. The Spring development team quickly saw that many development teams were moving away from monolithic applications where the applications presentation, business and data access logic were packaged together and deployed as a single artifact. Instead teams were moving to highly distributed model where services were being built as small, distributed services that could be easily deployed to ©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders. https://forums.manning.com/forums/spring-microservices-in-action 3 the cloud. In response to this shift, the Spring development team launched two projects Spring Boot and Spring Cloud. Spring Boot is a re-envisioning of the Spring framework. While it embraces core features of Spring, Spring Boot strips away many of “enterprise” features found in Spring and instead delivers a framework built geared towards Java-based, REST (Representational State Transfer) 1 orientated microservices quickly. With a few simple annotations, a Java developer can build a REST microservice that can be package and deployed without the need for an external application container. NOTE While we will cover REST in more detail in chapter 2, the core concept behind REST is that your services are invoked via the HTTP protocol, embrace the use of the HTTP verbs (GET, POST, PUT and DELETE) to represent the core actions of the service and use a very lightweight web orientated data serialization protocol, like JSON for requesting and receiving data from the service. Since microservices have become one of the more common architectural patterns for building cloud-based applications, the Spring development community has given us Spring Cloud. The Spring Cloud framework makes operationalizing and deploying microservices to a private or public cloud simple. components. Spring Microservice applications are highly distributed with many moving Cloud wrappers several popular cloud management microservice frameworks under a common framework and makes the use and deployment of these technologies as easy to use as just annotating your code. We will cover the different components within Spring Cloud later on in the chapter. 1.2 What you will learn in this book This book is about building microservice based applications using Spring Boot and Spring Cloud that can be deployed to a private cloud run by your company or a public cloud like Amazon, Google or Pivotal.With this book, we will cover with hands-on examples: • What is a microservice and what are the design considerations that go into building a • microservice-based application • How to build microservices using the Spring Boot • application, particularly a cloud-based application • • When shouldn’t you build a microservice-based application. What are the core operational patterns that need to be in place to support microservice How we can use Spring Cloud to implement these operational patterns How to take take what we have learned and build a deployment pipeline that can be used to deploy to multiple cloud providers 1 While we cover REST later on in Chapter 2, it always worthwhile to read Roy Fielding’s PHD dissertation on building REST-based applications (http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm) is still one of the explanations of REST available. ©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders. https://forums.manning.com/forums/spring-microservices-in-action 4 1.3 Why is this book relevant to you If you have gotten this far into reading chapter 1, I suspect that: • You are a Java developer. • You have some kind of background in Spring. • You are interested in how you leverage microservices for building cloud-based • You want to know if Java and Spring are relevant technologies for building • • You are interested in learning how to build microservice-based applications. applications. microservice-based applications. You are interested to see what goes into deploying a microservice-based application to the cloud. I chose to write this book, because while I have seen many good books on the conceptual aspects of microservices, I could not a find a good Java-based book on implementing microservices. While, I have always considered myself a programming language polyglot (knows and speaks several languages), Java is my core development language and Spring has been the development framework I “reach” for whenever I build a new application. When I first came across Spring Boot and Spring Cloud, I was blown away. Spring Boot and Spring Cloud greatly simplified my development life when it came to building microservice based applications running in the cloud. Enough talk. I have talked a lot this point with very little code examples. Let’s shift gears for a moment and walkthrough building a simple microservice using Spring Boot. 1.4 Building a microservice with Spring Boot I have always been of the opinion that a software development framework is well thought out and easy to use if it passes what I affectionately call the “Carnell Monkey Test.” If a monkey like me (the author) can figure out a framework in 10 minutes or less it has promise. That is how I felt the first time I wrote a sample Spring Boot service. I want you to have to the same experience and joy. So let’s take a minute to write a simple “Hello World” REST-service using Spring Boot. Figure 1.1 shows what our service is going to do and the general flow of how Spring Boot microservice will process a user’s request. ©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders. https://forums.manning.com/forums/spring-microservices-in-action 5 Figure 1.1 A user calling our Hello World microservice This example is by no means exhaustive or even illustrative of how you should build a production-level microservice service, but it should cause you to take a pause. We are not going to go through how to setup the project build files or the details of the code until Chapter2. If you would like to see the maven pom.xml file and the actual code, you can find in the Chapter 1 section of the downloadable code. So for our example we are going to have a single src/com/thoughtmechanix/application/simple/Application.java Java class call that will be used to expose a REST endpoint called /hello. Listing 1.1 shows the code for our Application.java. Listing 1.1 Hello World with Spring Boot: A (very) simple Spring Microservice package com.thoughtmechanix.simpleservice; import import import import import import org.springframework.boot.SpringApplication; org.springframework.boot.autoconfigure.SpringBootApplication; org.springframework.web.bind.annotation.RequestMapping; org.springframework.web.bind.annotation.RequestMethod; org.springframework.web.bind.annotation.RestController; org.springframework.web.bind.annotation.PathVariable; @SpringBootApplication @RestController @RequestMapping(value="hello") public class Application { ❶ ❷ ❸ public static void main(String[] args) { SpringApplication.run(Application.class, args); ©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders. https://forums.manning.com/forums/spring-microservices-in-action 6 } @RequestMapping(value="/{firstName}/{lastName}", ❹ method = RequestMethod.GET) public String hello( @PathVariable("firstName") String firstName, @PathVariable("lastName") String lastName) { return String.format("{\"message\":\"Hello %s %s\"}", ❻ firstName, lastName); } ❺ } ❶ ❷ ❸ ❹ Tells the Spring Boot framework that this class is the entrypoint for the Spring Boot framework. Tells Spring Boot we are going to expose the code in this class as a Spring RestController class. All URLs exposed in this application will be prefaced with /hello prefix. Spring Boot will expose an endpoint a GET-based REST endpoint that will take two parameters in it firstName and lastName. ❺ Maps the firstName and lastName parameters passed in on the URL to two variables passed into the hello function. ❻ Returns a simple JSON string. In listing 1.1 we are basically exposing a single GET http endpoint that will take two parameters (firstName and lastName) on the URL and then return a simple a JSON string that has a JSON payload containing the message “Hello firstName lastName”. So if we were to call the endpoint /hello/john/carnell on our service(which will be shown shortly) the return of the call would be: {“message”:”Hello john carnell”} So lets actually fire up our service. To do this we are going to go to the command prompt and issue the following command from the command-line: mvn spring-boot:run This command, mvn, will use a Spring Boot plug-in to start the application using an embedded tomcat server. Java vs. Groovy and Maven vs. Gradle The Spring Boot framework has strong support for both Java and the Groovy programming language. You can build microservices with Groovy and and no project setup. Spring Boot also supports both maven and the gradle build tools. I have chosen to limit the examples in this book to Java and Maven. As a long-time Groovy and Gradle aficionado, the author has a healthy respect for the language and the build tool, but in an effort to keep the book manageable and the material focus, I have chosen to go with Java and Maven to reach the largest audience. If everything starts correctly, you should see the following from your command-line window: ©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders. https://forums.manning.com/forums/spring-microservices-in-action 7 Figure 1.2 Our Spring Boot Service will communicate the endpoints exposed and the port of the service If you look closes at the screen shot above in Figure 1.1 you will notice two things. First, a tomcat server was started on port 8080. Second, a GET endpoint of /hello/{firstName}/{lastName} is exposed on the server. So let’s call our service using a command-line tool called curl and see what is returned. The curl command to issue is: curl http://localhost:8080/hello/john/carnell When the command above is issued, we should see the following response. Figure 1.3 Response from the /hello endpoint Obviously this simple example does not demonstrate the full power of Spring Boot. But what it should show is that you can write a full HTTP JSON REST-based service with route mapping of URL and parameters in Java with as little as 25 lines of code. As any experienced Java developer will tell you, writing anything meaningful in 25 lines of code in Java is extremely difficult. Java, while being a very powerful language, has acquired a reputation of being wordy compared to other language. 2 We are done with our brief tour of Spring Boot and will cover it in more detail in Chapter 2. However, just because we can write our applications using a microservice approach, does this mean we should? In the next section we are going to walkthrough why and when a microservice approach is justified for building your applications. 2 Shhh don’t tell anyone, but this Java programmer has a habit of also writing Clojure code. That’s a book for another day ©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders. https://forums.manning.com/forums/spring-microservices-in-action 8 1.5 Why change the way we build applications? We are at an inflection point in history. Almost all aspects of modern society are now wired together via the Internet. Companies that used to serve local markets are suddenly finding that they can reach out to a global customer base. However, with a larger global customer base has also come global competition. These competitive pressures mean the following forces are impacting the way developers have to think about building applications: • Complexity has gone way up. Customers expect that all parts of an organization know who they are. “Siloed” applications that talk to a single database are no longer the norm. Today’s applications need to talk to multiple services and database residing not only inside a company’s data center, but also to external service providers over the • Internet. Customers want faster delivery. Customers no longer want to wait annually for the next release or version of a software package. Instead, they expectthe features in a software product to be unbundled so that new functionality can be released without • having to wait for an entire product release. Performance and scalability. Global applications make it extremely difficult to predict how much transaction volume is going to be handled by an application and when that transaction volume is going to hit. Applications need to be able to scale up across multiple servers quickly and then when the volume needs have passed, scale • back down. Customers expect their applications to be available. Since, customers are one click away from a competitor, a company’s applications must be highly resilient. Failures or problems in one part of the application should not bring down the entire application. To meet the expectations listed above, we as application developers have to embrace the paradox that to build high-scalable and highly redundant applications we need to break our applications into very small services that can be built and deployed independently of one another. If we “unbundle” our applications and move them away from a single monolithic artifact we can build systems that are: • Flexible. Decoupled services can be composed and rearranged to quickly deliver new functionality. The smaller the unit of code that one is working with the less complicated • it is to change the code and the less time it takes to test deploy the code. Resilient. Decoupled servicesmeans an application is no longer a single “ball of mud” where a degradation in one part of the application causes the whole application to fail. Failures can be localized to a small part of the application and contained before the entire application experiences an outage. This also enables the applications to degrade • gracefully in case of un-recoverable error. Scalable. Decoupled servicescan easily be distributed horizontally across multiple servers enabling the ability to scale the features / services appropriately. With a ©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders. https://forums.manning.com/forums/spring-microservices-in-action 9 monolithic application where all of the logic for the application is intertwined the entire application needs to scale even if only a small part of the application is the bottleneck. Scaling on small services are localized and much more cost-effective. To this end as we begin our discussion of microservices keep the following in mind: SMALL, SIMPLE AND DECOUPLED SERVICES = SCALABLE, RESILIENT AND FLEXIBLE APPLICATIONS 1.6 What exactly is the cloud The term “cloud” has become overused. Every software vendor has a cloud and everyone’s platform is cloud-enabled, but if you cut through the hype there are really three basic models of cloud-based computing. These are: • • • Infrastructure as a Service Platform as a Service Software as a Service To better understand these concepts let map the everyday task of making a meal to how a different models of cloud computing. When we want to eat a meal we have four choices: 1. We can make the meal at home. 2. We can go to the grocery store and buy a meal pre-made that we have to heat up and server. 3. We can a meal delivered to our houses 4. We can get in the car and eat at restaurant. Figure 1.4 shows each model: ©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders. https://forums.manning.com/forums/spring-microservices-in-action 10 Figure 1.4 The three core models of cloud computing The difference between these options is really about whose responsible for cooking these meals and where the meal is going to be cooked. In the on-premise model, eating a meal at home requires you to do all of the work using your own oven and ingredients already in the home. A store-bought meal is like using the Infrastructure as a Service (IaaS) model of computing. We are using the store’s chef and oven to pre-bake the meal, but we still are still responsible for heating the meal and eating it at house (and cleaning up the dishes afterwards). In a Platform as a Service (PaaS) model we still have some responsibilities for the meal (e.g. we have to supply the plates and furniture), but we further rely on a vendor to take care of the core tasks associated with making a meal. In the Software as a Service (SaaS) model, we go to a restaurant where all the food is prepared for us. We eat at the restaurant and then we pay for the meal when we are done. We also have no dishes to prepare. The key items at play in each of these models is one of control: who is responsible for maintaining the infrastructure and what are the technology choices available for building an application. 1.7 Why the cloud and microservices One of the core concepts of a microservice-based architecture is that each service is packaged and deployed as is its own discrete and independent artifact. Services instance should be ©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders. https://forums.manning.com/forums/spring-microservices-in-action 11 able to brought up quickly and each instance of the service should be indistinguishable from each other. As a developer writing a microservice sooner or later you are going to have to decide whether your service is going to be deployed to a: • Physical Server. While you can build and deploy your microservices to a physical machines few organizations do this because physical servers are constrained. You can not quickly ramp up the capacity of a physical server and scaling horizontally your • microservice across multiple physical servers can become extremely costly. Virtual Machine Images. One of the key benefits of microservices is being able to quickly startup and shutdown microservice instances in response to scalability and service failure events. providers. Virtual machines are the heart and soul of the major cloud A microservice can be packaged up in a virtual machine image. Multiple instances of the service can then be quickly deployed and started in either a IaaS • private or public cloud. Virtual Container. Virtual container are a natural extension to deploying your microservices on a virtual machine image. Rather then deploying your service to a full virtual machine, many developers will deploy their services as Docker (or equivalent container technology) containers to the cloud. Virtual containers run inside of a virtual machine and allow you to segregate a single virtual machine into a series of selfcontained processes sharing the same virtual machine image. For this book, all the microservices and corresponding service infrastructure will be deployed to an IaaS-based cloud provider. This is the most common deployment topology used for microservices: • Simplified Infrastructure Management. IaaS cloud-providers give you the ability to have the most control over your services. New services can be started and stopped with simple API calls. With an IaaS cloud solution, you only pay for the infrastructure • that you use. Massive horizontal scalability. IaaS cloud providers allow you to quickly and succinctly start service (and their corresponding services). This capability means you can scale services quickly and also allows you to quickly route around misbehaving or • failing servers. High redundancy through geographic distribution. By necessity IaaS providers will have multiple data centers. By deploying your microservices using an IaaS cloud provider you can gain a higher level of redundancy beyond just using cluster in a data center. ©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders. https://forums.manning.com/forums/spring-microservices-in-action 12 Whynot PaaS-based Microservices? Earlier in the chapter we identified there are three types of cloud platforms (Infrastructure as a Service, Platform as a Service and Software as a Services). For this book we have chosen to focus specifically on building microservices using an IaaS-based approach. While some cloud providers will let you abstract away the deployment infrastructure for your microservice. For instance, Amazon, CloudFoundry and Heroku give you the ability to deploy your services without having to know about the underlying application container. They provide a web interface and APIs to allow you to deploy your application as a WAR or JAR file. The setup and tuning of the application server and the corresponding Java container are abstracted away from you. While this is very convenient, each cloud provider’s platform have different idiosyncracies related to their individual PaaS solution. An IaaS approach, while more work, is portable across multiple cloud providers and also allows us to reach a wider audience with our material. Personally, I have found that PaaS based cloud solutions can allow you to quickly jump start your development effort, but once your application reaches enough microservices, you starting needing the flexibility the IaaS style of cloud development provides. The services built in this book will be packaged as Docker containers. One of the reasons why I chose Docker is that as a container technology, Docker is deployable to all of the major cloud providers. Later in Chapters 8 and 9, I will be demonstrating how to package our microservices using Docker and then deploy these containers to Pivotal’s and Amazon’s cloud platforms. (CloudFoundry and Amazon Web Services respectively) 1.8 Microservices are more then just writing the code While the concepts around building individual microservices are easy to understand, actually running and supporting a robust microservice application (especially when running in the cloud) involves a lot more then writing the services code. It involves having to think about how your services are going to be: • Right-sized. How do we ensure that our microservices are properly sized so that we do not have a microservice take on too much responsibility? Remember, properly size a service allows us to quickly make changes to an application and reduces the overall • risk of an outage to the entire application? Manageable.How do we manage the physical details of service invocation when in a microservice application you might have multiple service instances can quickly start • and shutdown? • application by routing around failing services and ensuring that we take a “fail-fast.” Resilient. How do protect our microservice consumers and the overall integrity of our Repeatable. How do we ensure that every new instance of our service brought up is guaranteed to have the same configuration and code base as all the other service • instances in production? Scalable. How do we leverage asynchronous processing and events to minimize the direct dependencies between our services and ensure that we can gracefully scale our ©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders. https://forums.manning.com/forums/spring-microservices-in-action 13 microservices? This book is going to take a patterns based approach as we answer the questions above. Specifically, we are going to cover the following four categories of patterns: • • • • Core Microservice Development Patterns Microservice Routing Patterns Microservice Client Resiliency Patterns Microservice Build/Deployment Patterns Let’s walk through these patterns in more detail. 1.8.1 Core Microservice Development Pattern The core development patterns really deals with the basics of building a microservice. Figure 1.5 highlights the topics we will cover around basic service design. Figure 1.5 – In building a simple service we have to consider these topics Let’s walk through these topics in a little more detail. • Service Granularity. How do you approach decomposing a business domain down into microservices so that the microservice has the right level of responsibility? Making a service too coarse-grained with responsibilities that overlap into different business problems domains makes service difficult to maintain and change over time. Making the service too fine-grained increases the overall complexity of the application and really just turns the service into a data later. Service granularity will be covered in chapter 2. ©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders. https://forums.manning.com/forums/spring-microservices-in-action 14 • Communication Protocols. How will developers communicate with your service? We will go into why JSON is the ideal chose for microservices and has become the most common choice for sending and receiving data to microservice. • The topic of communication protocols will be covered in Chapter 2 of this book. Interface Design. What is the best way to design the actual service interfaces that developers are going to use to call your service? How do you structure your service URLs to communicate service intent? What about versioning your services? A well design microservice interface makes using your service intuitive. Interface design will • be covered in Chapter 2. Configuration Management of Service. How do you manage the configuration of your microservice so that as it moves between different environments in the cloud you never have to change the core application code or configuration? • Managing service configuration will be covered in Chapter 3. Event processing between services. How do you decouple your microservice using events so that you minimize hardcoded dependencies between your services and increase the resiliency of your application? The topic of event processing between services will be covered in chapter 7. 1.8.2 Microservice Routing Patterns The microservice routing patterns cover microservice discovery and routing. In a cloud-based application you might have hundreds of microservices instances running. This means you will need to abstract away the physical IP address of these services and have a single point of entry for service calls so that you can consistently enforce security and content policies for all service calls. ©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders. https://forums.manning.com/forums/spring-microservices-in-action 15 Figure 1.6 – Service discovery and routing are key parts of any large-scale microservice application. Service discovery and routing really answer the question of how do I get my clients request for a service to a specific instance of a service. • Service Discovery. How do you make your microservice discoverable so client applications can find them without having the location of the service hardcoded into the application? How do you ensure that misbehaving microservice instances are removed • from pool of available service instances? Service discovery is covered in Chapter 4. Service Routing – How do provide a single entry point for all of your services so that security policies and routing rules are applied uniformly to multiple services and service instances in your microservice applications? How do you ensure that each developer in you team do not have to come up with their own solutions for providing routing to their services. Service routing is covered in chapter 6. While in Figure 1.3 appear to have a hard-coded sequence between them (first comes service routing and the service discovery) to implement one pattern does not require the other. For instance, we can implement service discovery without service routing. Service routing can be implemented without service discovery (even though its implementation is more difficult) ©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders. https://forums.manning.com/forums/spring-microservices-in-action 16 1.8.3 Microservice Client Resiliency Patterns Since microservices architectures are highly distributed we have to be extremely sensitive in how we prevent a problem in single service (or service instance) from cascading up and out to the consumers of the service. To this end, we are going to cover four topics with client resiliency patterns. Figure 1.7 – With microservices care must be taken to protect the call from a poorly behaving services • Client-side load balancing. How do we cache the location of our service instances on the service client so that calls to multiple instances of a microservice are load balanced • to all of the health instances of that microservice? Circuit Breakers Pattern. How do you prevent a client from continuing to call a service that is failing or suffering performance problems? When a service is running slow it consuming resources on the client calling it. We want failing microservice calls • to fail fast. Fallback Pattern. When a service call fails how do we provide a “plug-in” mechanism that will allow the service client to try and carry out its work through some alternatives • means other then the microservice being called. Bulkhead Pattern.Microservice applications use multiple distributed resources to carry out their work. How do we compartmentalize these calls so that the misbehavior of one service call does not negatively impact the rest of the application? These four topics are covered in Chapter 5. ©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders. https://forums.manning.com/forums/spring-microservices-in-action 17 1.8.4 Microservice Build/Deployment Patterns One of the core parts of a microservice architecture is that each instance of a microservice should be identical to all of its other instances. We can not allow “configuration drift” (something changes on a server after it has been deployed) to occur as this can introduceinstability in your applications. A phrase too often said “I made only one small change on the stage server, but I forgot to make the change in production.” The resolution of many down systems when I have worked on critical situations teams over the years has often started with those words from a developer or system administrator. Engineers (and most people in general) operate under the notation of good intent. They don’t go to work to make mistakes or bring down systems. Instead they are doing the best they can, but they get busy or distracted. So they tweak something on a server fully intending to go back and do it in all of the environments. At some later point, an outage occurred and everyone is left scratching their head going what is different between the lower environments in production. I have found that the small size and limited scope of microservice make it the perfect opportunity to introduce the concept of “immutable infrastructure” into an organization: Once a service is deployed, the infrastructure it is running on is never touched again by human hands In my mind having an immutable infrastructure is critical piece of successfully using a microservice architecture, because you have to be able to guarantee in production that every microservice instance you start for a particular microservice is identical to its brethren. To this end our goal is to integrate the configuration of our infrastructure right into our build deployment process so that we no longer deploy software artifacts like a Java WAR our EAR to an already running piece of infrastructure. Instead we want to “bake” our microservice and the virtual server image it is running on as part of the build process. Then when our microservice gets deployed, the entire machine image with the server running on it gets deployed. Figure 1.8 illustrates this process. ©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders. https://forums.manning.com/forums/spring-microservices-in-action 18 Figure 1.8 We want to deployment of the microservice and the server its running on to be one atomic artifact that is deployed as a whole between environments. At the end of the book we are going to look at how we change our build and deployment pipeline so that our microservices and the servers they run on are deployed as a single unit of work. In chapter 8 we are going to cover the following patterns and topics: • Build and Deployment Pipeline. How do you create a repeatable build and deployment process that emphasis one button builds and deployment to any environment in your organization? • Infrastructure as Code. How do you treat the provisioning of your services as code • Immutable Servers. • Phoenix Servers. that can be executed and managed under source control? Once a microservice image is created how do you ensure that it is never changed after it has been deployed? The longer a server is running the more opportunity for configuration drift. How do we ensure that our servers that run our microservices get torn down on a regular basis and recreated off an immutable image? Our goal with these patterns and topics is to ruthlessly expose as quickly as possible and stamp out configuration drift before it is allowed to hit our environment upper environments like stage or production. ©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders. https://forums.manning.com/forums/spring-microservices-in-action 19 1.9 Leveraging Spring Cloud in building your microservices In this section, I briefly introduce the Spring Cloud technologies that we are going to use as we build out our microservices. This is just a high-level overview; when we use each technology in this book, I’ll teach you the details on each as needed. Implementing all of the patterns above from scratch would be a tremendous amount of work. Fortunately, for us the Spring team has integrated a wide number of battle-tested open-source projects into a Spring sub-project collectively known as Spring Cloud. (http://projects.spring.io/spring-cloud/). Spring Cloud wrappers the work of open-source companies like Pivotal, HashiCorp and NetFlix in delivering the above patterns. Spring Cloud simplifies setting up and configuring of these projects into your Spring application so that you can focus on writing code and not getting buried in the details of configuring all of the infrastructure that can go with building and deploying a microservice application. Figure 1.8 below maps the patterns listed in the previous section to the Spring Cloud projects that implement them. Figure 1.9 Mapping the technologies we are going to use to implement the microservice patterns Let’s walkthrough these technologies in greater detail. 1.9.1 Spring Boot Spring Boot is the core technology used in our microservice implementation. Spring Boot greatly simplifies microservice development by simplifying the core tasks of building RESTbased microservices. Spring Boot greatly simplifies mapping HTTP-style verbs actions to URLs and the serialization of the JSON (JavaScript Object Notation) protocol to and from Java objects. It also simplifies the mapping of Java exceptions back to standard HTTP error codes. ©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders. https://forums.manning.com/forums/spring-microservices-in-action 20 1.9.2 Spring Cloud Config Spring Cloud Config handles the management of application configuration data through a centralized service so your application configuration data (particularly your environment specific configuration data) is cleanly separated from your deployed microservice. This ensures that no matter how many microservice instances you bring up they will always have the same configuration. Spring Cloud Config has it owns property management repository, but also integrates with open source projects like Git (https://git-scm.com/) , Consul (https://www.consul.io/) and Eureka project (https://github.com/Netflix/eureka). 1.9.3 Spring Cloud Service Discovery Spring Cloud service discovery allows you to abstract away the physical location (IP and/or server name) of where your servers are deployed from the clients consuming the service. Service consumers invokes business logic for the servers through a logical name rather then a physical location. Spring Cloud Service Discovery also handles the registration and deregistration of services instances as they are started up and shutdown. Spring Cloud Service Discovery can be implemented using Consul (https://www.consul.io/) and Eureka project (https://github.com/Netflix/eureka)as it service discovery engine. 1.9.4 Spring Cloud/Netflix Hystrix and Ribbon Spring Cloud heavily integrates with Netflix open source projects. resiliency patterns, Spring (https://github.com/Netflix/Hystrix)and Cloud Ribbon wrappers the For microservice client Netflix Hystrix (https://github.com/Netflix/Ribbon)projects and makes leveraging them from within your own microservices trivial to implement. The Netflix Hystrix libraries allow you quickly implement service client resiliency patterns like the circuit breaker and bulkhead patterns. While the Netflix Ribbon project simplifies integrating with service discovery agents like Eureka, it also provides client-side load-balancing of service calls from a service consumer. This allows a client to continue making service calls even if the service discovery agent is temporarily unavailable. 1.9.5 Spring Cloud/Netflix Zuul Spring Cloud leverages the Netflix Zuul project (https://github.com/Netflix/zuul)to provide service routing capabilities for your microservice application. Zuul proxies service request and makes sure that all calls to your microservices go through a single “front door” before the actual requests hits your service instance. This centralization of service calls with Zuul allows you to enforce standard service policies like a security authorization authentication, content filtering and routing rules. ©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders. https://forums.manning.com/forums/spring-microservices-in-action 21 1.9.6 Spring Cloud Stream Spring Cloud Stream (https://cloud.spring.io/spring-cloud-stream/) is an enabling technology that allows you easily integrate lightweight message processing into your microservice. By using Spring Cloud Stream you can build intelligent microservices that can leverage asynchronous events as they occur in your application. Spring Cloud Stream allows to quickly integrate your microservices with AMQP-compliant (https://www.amqp.org/)message brokers like RabbitMQ (https://www.rabbitmq.com/)and Kafka.(http://kafka.apache.org/) 1.9.7 What about Provisioning? For the provisioning implementations we are going to make a technology shift. The Spring framework(s) are geared towards application development. The Spring frameworks (including Spring Cloud) do not have tools for creating a “build and deployment” pipeline. To this end we are going to leverage the following tools: Travis CI (https://travis-ci.org) for our build tool and Docker (https://www.docker.com/) to build the final server image containing our microservice. 1.10 Spring Cloud by example In the last section we walked through all the different Spring Cloud technologies that we are going to use as we build out our microservices. Since each of these technologies are independent services it is obviously going to take more than one chapter to explain all of them in detail. However, as I wrap up this chapter, I want to leave you with a small code example that again demonstrates how easy it is to integrate these technologies in your own microservice development effort. Unlike the first code example in listing 1.1, you will not be able to simply run this code example, as there are a number of supporting services that need to be setup and configured to be leveraged. Don’t worry though, the setup costs for these Spring Cloud services (configuration service, service discovery) are a one-time cost in terms of setting up the service. Once they are setup, your individual microservices can leverage these capabilities over and over again. We just get fit all that goodness into a single code example at the beginning of the book. In the code showing in listing 2.2, I am going to quickly demonstrate how we integrated the service discovery, the circuit breaker, bulkhead and client-side load balancing of remote services into our “Hello World” example. Listing 1.2 Our Hello World Service using with Spring Cloud package com.thoughtmechanix.simpleservice; //Removed other imports for conciseness import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; ©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders. https://forums.manning.com/forums/spring-microservices-in-action 22 import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; @SpringBootApplication @RestController @RequestMapping(value="hello") @EnableCircuitBreaker @EnableEurekaClient public class Application { ❶ ❷ public static void main(String[] args) { SpringApplication.run(Application.class, args); } @HystrixCommand(threadPoolKey = "helloThreadPool") ❸ public String helloRemoteServiceCall(String firstName, String lastName){ ResponseEntity<String> restExchange = restTemplate.exchange( "http://nameservice/name/{firstName}/{lastName}", ❹ HttpMethod.GET, null, String.class, firstName, lastName); return restExchange.getBody(); } @RequestMapping(value="/{firstName}/{lastName}", method = RequestMethod.GET) public String hello( @PathVariable("firstName") String firstName, @PathVariable("lastName") String lastName) { return helloRemoteServiceCall(firstName, lastName) } } Listing 1.2 Our simple service leveraging Spring Cloud Capabilities ❶ Enables the service to use the Hystrix and Ribbon Libraries ❷ Tells the service that it should register itself with a Eureka service discovery agent and that service calls are to use Service discovery to “lookup” the location of remote services ❸ Wrappers calls to the helloRemoteServiceCall method with a Hystrix Circuit Breaker. ❹ Uses a decorated RestTemplate class to take a “logical” service id and use Eureka under the covers to look up the physical location of the service. There is a lot packed into the code example above. Let’s quick walkthrough it. Keep in mind that listing 1.2 is for examples purposes only. We will structure and break apart our Spring Boot microservices into a more structured fashion as we progress through the book. The first thing you should notice as you look at listing 1.2, is the @EnableCircuitBreaker and @EnableEurekaClient annotations. The @EnableCircuitBreaker annotation tells our Spring microservice that we are going to use the Netflix Hystrix libraries in our application. The @EnableEurekaClient annotation tells our microservice to register itself with a Eureka Service Discovery agent and that we are going to use service discovery to look up remote ©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders. https://forums.manning.com/forums/spring-microservices-in-action 23 REST services endpoints in our code. Note, there is some configuration going on in a property file that will tell our simple service the location and port number of a Eureka server to contact.We first see Hystrix being used when are declaring our hello method. @HystrixCommand(threadPoolKey = "helloThreadPool") public String helloRemoteServiceCall(String firstName, String lastName) The @HystrixCommand annotation is doing two things. First, any time the helloRemoteServiceCall method, the method will be invoked on a thread pool managed by Hystrix. If the calls takes too long (default is 1 second), Hystrix will step in and interrupt the call. This is the implementation of the circuit breaker pattern. The second thing this annotation does is create a thread pool called “helloThreadPool” that is managed by Hystrix. All calls to helloRemoteServiceCall method will only occur on this thread pool and will be isolated from any other remote service calls being made. The last thing to note is what is occurring inside the the helloRemoteServiceCall method. The presence of the @EnableEurekaClient has told Spring Boot that we are going to use to a modified RestTemplate class (this is not how the Standard Spring RestTemplate would work out of the box) whenever we make a REST service call. This RestTemplateclass will allow us to pass in a logical service id for the service we are trying to invoke. ResponseEntity<String> restExchange = restTemplate.exchange(http://logical-serviceid/name/{firstName}/{lastName} Under the covers, the RestTemplate class will contact the Eureka service and lookup the physical location of one or more the “name” service instances. As a consumer of the service, our code never has to nowhere that service is located. Also RestTemplate class above is leveraging Netflix’s Ribbon library. Ribbon will retrieve a list of all of the physical endpoints associated with a service and the everytime the service is called by the client, will round robin to the different service instances on the client without having to go through a centralized load balancer. By eliminating a centralized load-balancer and moving it to the client you eliminate another failure point (load balancer going down) in your application infrastructure. I hope at this point you are impressed because we have added a significant amount of capabilities to our microservice with only a few annotations. That is the real beauty behind Spring Cloud. You as a developer get to take advantage of battle-hardened microservice capabilities from premier cloud companies like Netflix and Consul. These capabilities, if be being used outside of Spring Cloud can be complex and obtuse to setup. Spring Cloud simplifies their use down to literally nothing more then a few simple Spring Cloud annotations and configuration entries. 1.11 Making sure our examples are relevant I want to make sure this book provides examples that you can relate to as you go about your day-to-day job. To this end, I am going to structure the chapters in this book and the ©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders. https://forums.manning.com/forums/spring-microservices-in-action 24 corresponding code examples around the adventures (misadventures) of a fictitious company called ThoughtMechanix. The examples in this book will not build the entire ThoughtMechanix application. Instead we build some specific microservices from the problem domain at hand and then build the infrastructure that will support these services ThoughtMechanix is a software development company, whose core product, EagleEye provides an enterprise grade Software Asset Management application. It provides coverage for all of the critical elements: Inventory, Software Delivery, License management, Compliance, Cost and Resource management. Its primary goal is to enable organizations to gain an accurate point in time picture of its software assets. The company is approximately 10 years old and while they have been experiencing solid revenue growth internally they have been debating about whether or not they should be replatforming their core product from a monolithic,“on premise” based application or move their application to the cloud. The re-platforming involved with EagleEye can be a “make or break” moment for a company. The company is looking at rebuilding their core product EagleEye on a new architecture. While much of the business logic for the application will remain in place, the application itself will be broken down from a monolithic design to a much smaller microservice design whose pieces can be deployed independently to the cloud. The ability to successfully adopt cloud-based, microservice architecture is going to impact all parts of a technical organization. This includes the architecture, engineering, testing and operations teams. Input is going to be needed from each group and in the end they are probably going to see the need for some reorganization as the team re-evaluates their responsibility in this new environment. Let’s begin our journey with Thoughtmechanix as we begin the fundamental work of identifying and building out some of the microservices used in “Eagle Eye” and then building these services using Spring Boot. 1.12 Summary • • Microservices are extremely small pieces of functionality that are responsible for one specific area of scope. There are no industry standards around microservices. Unlike other early web service protocols, microservices take a principle based approach and align with the concepts of • REST and JSON. Writing microservices are easy, but fully operationalizing them for production requires additional forethought. We introduced several categories of microservice development patterns including: core development, routing patterns, client resiliency and build/deployment patterns. • While microservices are language agnostic, we introduced two Spring frameworks that • Spring Boot is used to simplify the building of REST-based/JSON microservices. significantly help in building microservices: Spring Boot and Spring Cloud. Its goal is to allow you to build microservices quickly with nothing more then a few annotations. ©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders. https://forums.manning.com/forums/spring-microservices-in-action 25 • Spring Cloud is a collection of open-source technologies from companies like NetFlix and HashiCorp that have been “wrappered” with Spring annotations to significantly simplify the setup and configuration of these services. ©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders. https://forums.manning.com/forums/spring-microservices-in-action