📄 Page
1
M A N N I N G John Carnell
📄 Page
2
Spring Microservices in ActionLicensed to <null>
📄 Page
3
Licensed to <null>
📄 Page
4
Spring Microservices in Action JOHN CARNELL M A N N I N G SHELTER ISLANDLicensed to <null>
📄 Page
5
For online information and ordering of this and other Manning books, please visit www.manning.com. The publisher offers discounts on this book when ordered in quantity. For more information, please contact Special Sales Department Manning Publications Co. 20 Baldwin Road PO Box 761 Shelter Island, NY 11964 Email: orders@manning.com ©2017 by Manning Publications Co. All rights reserved. No part of this publication may be reproduced, stored in a retrieval system, or transmitted, in any form or by means electronic, mechanical, photocopying, or otherwise, without prior written permission of the publisher. Many of the designations used by manufacturers and sellers to distinguish their products are claimed as trademarks. Where those designations appear in the book, and Manning Publications was aware of a trademark claim, the designations have been printed in initial caps or all caps. Recognizing the importance of preserving what has been written, it is Manning’s policy to have the books we publish printed on acid-free paper, and we exert our best efforts to that end. Recognizing also our responsibility to conserve the resources of our planet, Manning books are printed on paper that is at least 15 percent recycled and processed without the use of elemental chlorine. Manning Publications Co. Acquisition editor: Greg Wild 20 Baldwin Road Development editor: Marina Michaels PO Box 761 Technical development editor: Raphael Villela Shelter Island, NY 11964 Copyeditor: Katie Petito Proofreader: Melody Dolab Technical proofreader: Joshua White Review editor: Aleksandar Dragosavljevic Typesetter: Marija Tudor Cover designer: Marija Tudor ISBN 9781617293986 Printed in the United States of America 1 2 3 4 5 6 7 8 9 10 – EBM – 22 21 20 19 18 17Licensed to <null>
📄 Page
6
To my brother Jason, who even in his darkest moments showed me the true meaning of strength and dignity. You are a role model as a brother, husband, and father.Licensed to <null>
📄 Page
7
vi Licensed to <null>
📄 Page
8
brief contents 1 ■ Welcome to the cloud, Spring 1 2 ■ Building microservices with Spring Boot 35 3 ■ Controlling your configuration with Spring Cloud configuration server 64 4 ■ On service discovery 96 5 ■ When bad things happen: client resiliency patterns with Spring Cloud and Netflix Hystrix 119 6 ■ Service routing with Spring Cloud and Zuul 153 7 ■ Securing your microservices 192 8 ■ Event-driven architecture with Spring Cloud Stream 228 9 ■ Distributed tracing with Spring Cloud Sleuth and Zipkin 259 10 ■ Deploying your microservices 288 vii Licensed to <null>
📄 Page
9
BRIEF CONTENTSviii Licensed to <null>
📄 Page
10
contents preface xv acknowledgments xvii about this book xix about the author xxii about the cover illustration xxiii 1 Welcome to the cloud, Spring 1 1.1 What’s a microservice? 2 1.2 What is Spring and why is it relevant to microservices? 5 1.3 What you’ll learn in this book 6 1.4 Why is this book relevant to you? 7 1.5 Building a microservice with Spring Boot 8 1.6 Why change the way we build applications? 12 1.7 What exactly is the cloud? 13 1.8 Why the cloud and microservices? 15 1.9 Microservices are more than writing the code 17 Core microservice development pattern 19 ■ Microservice routing patterns 20 ■ Microservice client resiliency patterns 21 Microservice security patterns 23 ■ Microservice logging and tracing patterns 24 ■ Microservice build/deployment patterns 25 1.10 Using Spring Cloud in building your microservices 26 Spring Boot 28 ■ Spring Cloud Config 28 ■ Spring Cloud service discovery 28 ■ Spring Cloud/Netflix Hystrix and ix Licensed to <null>
📄 Page
11
CONTENTSxRibbon 29 ■ Spring Cloud/Netflix Zuul 29 ■ Spring Cloud Stream 29 ■ Spring Cloud Sleuth 29 ■ Spring Cloud Security 30 ■ What about provisioning? 30 1.11 Spring Cloud by example 30 1.12 Making sure our examples are relevant 33 1.13 Summary 33 2 Building microservices with Spring Boot 35 2.1 The architect’s story: designing the microservice architecture 38 Decomposing the business problem 38 ■ Establishing service granularity 41 ■ Talking to one another: service interfaces 43 2.2 When not to use microservices 44 Complexity of building distributed systems 44 ■ Server sprawl 44 ■ Type of application 44 ■ Data transformations and consistency 45 2.3 The developer’s tale: building a microservice with Spring Boot and Java 45 Getting started with the skeleton project 46 ■ Booting your Spring Boot application: writing the Bootstrap class 47 ■ Building the doorway into the microservice: the Spring Boot controller 48 2.4 The DevOps story: building for the rigors of runtime 53 Service assembly: packaging and deploying your microservices 56 Service bootstrapping: managing configuration of your microservices 58 ■ Service registration and discovery: how clients communicate with your microservices 59 ■ Communicating a microservice’s health 60 2.5 Pulling the perspectives together 62 2.6 Summary 63 3 Controlling your configuration with Spring Cloud configuration server 64 3.1 On managing configuration (and complexity) 65 Your configuration management architecture 67 ■ Implementation choices 69 3.2 Building our Spring Cloud configuration server 70 Setting up the Spring Cloud Config Bootstrap class 74 Using Spring Cloud configuration server with the filesystem 75Licensed to <null>
📄 Page
12
CONTENTS xi3.3 Integrating Spring Cloud Config with a Spring Boot client 77 Setting up the licensing service Spring Cloud Config server dependencies 79 ■ Configuring the licensing service to use Spring Cloud Config 79 ■ Wiring in a data source using Spring Cloud configuration server 83 ■ Directly Reading Properties using the @Value Annotation 86 ■ Using Spring Cloud configuration server with Git 87 ■ Refreshing your properties using Spring Cloud configuration server 88 3.4 Protecting sensitive configuration information 89 Download and install Oracle JCE jars needed for encryption 90 Setting up an encryption key 91 ■ Encrypting and decrypting a property 91 ■ Configure microservices to use encryption on the client side 93 3.5 Closing thoughts 95 3.6 Summary 95 4 On service discovery 96 4.1 Where’s my service? 97 4.2 On service discovery in the cloud 100 The architecture of service discovery 100 ■ Service discovery in action using Spring and Netflix Eureka 103 4.3 Building your Spring Eureka Service 105 4.4 Registering services with Spring Eureka 107 4.5 Using service discovery to look up a service 111 Looking up service instances with Spring DiscoveryClient 112 Invoking services with Ribbon-aware Spring RestTemplate 114 Invoking services with Netflix Feign client 116 4.6 Summary 118 5 When bad things happen: client resiliency patterns with Spring Cloud and Netflix Hystrix 119 5.1 What are client-side resiliency patterns? 120 Client-side load balancing 121 ■ Circuit breaker 122 Fallback processing 122 ■ Bulkheads 122 5.2 Why client resiliency matters 123 5.3 Enter Hystrix 126 5.4 Setting up the licensing server to use Spring Cloud and Hystrix 127Licensed to <null>
📄 Page
13
CONTENTSxii5.5 Implementing a circuit breaker using Hystrix 128 Timing out a call to the organization microservice 131 Customizing the timeout on a circuit breaker 132 5.6 Fallback processing 133 5.7 Implementing the bulkhead pattern 136 5.8 Getting beyond the basics; fine-tuning Hystrix 138 Hystrix configuration revisited 142 5.9 Thread context and Hystrix 144 ThreadLocal and Hystrix 144 ■ The HystrixConcurrencyStrategy in action 147 5.10 Summary 151 6 Service routing with Spring Cloud and Zuul 153 6.1 What is a services gateway? 154 6.2 Introducing Spring Cloud and Netflix Zuul 157 Setting up the Zuul Spring Boot project 157 ■ Using Spring Cloud annotation for the Zuul service 157 ■ Configuring Zuul to communicate with Eureka 158 6.3 Configuring routes in Zuul 159 Automated mapping routes via service discovery 159 Mapping routes manually using service discovery 161 Manual mapping of routes using static URLs 165 Dynamically reload route configuration 168 ■ Zuul and service timeouts 169 6.4 The real power of Zuul: filters 169 6.5 Building your first Zuul pre-filter generating correlation IDs 173 Using the correlation ID in your service calls 176 6.6 Building a post filter receiving correlation IDs 182 6.7 Building a dynamic route filter 184 Building the skeleton of the routing filter 186 ■ Implementing the run() method 187 ■ Forwarding the route 188 ■ Pulling it all together 190 6.8 Summary 191 7 Securing your microservices 192 7.1 Introduction to OAuth2 193Licensed to <null>
📄 Page
14
CONTENTS xiii7.2 Starting small: using Spring and OAuth2 to protect a single endpoint 195 Setting up the EagleEye OAuth2 authentication service 196 Registering client applications with the OAuth2 service 197 Configuring EagleEye users 200 ■ Authenticating the user 202 7.3 Protecting the organization service using OAuth2 205 Adding the Spring Security and OAuth2 jars to the individual services 205 ■ Configuring the service to point to your OAuth2 authentication service 206 ■ Defining who and what can access the service 207 ■ Propagating the OAuth2 access token 210 7.4 JavaScript Web Tokens and OAuth2 213 Modifying the authentication service to issue JavaScript Web Tokens 214 ■ Consuming JavaScript Web Tokens in your microservices 218 ■ Extending the JWT Token 220 Parsing a custom field out of a JavaScript token 222 7.5 Some closing thoughts on microservice security 224 7.6 Summary 227 8 Event-driven architecture with Spring Cloud Stream 228 8.1 The case for messaging, EDA, and microservices 229 Using synchronous request-response approach to communicate state change 230 ■ Using messaging to communicate state changes between services 233 ■ Downsides of a messaging architecture 235 8.2 Introducing Spring Cloud Stream 236 The Spring Cloud Stream architecture 237 8.3 Writing a simple message producer and consumer 238 Writing the message producer in the organization service 239 Writing the message consumer in the licensing service 244 Seeing the message service in action 247 8.4 A Spring Cloud Stream use case: distributed caching 249 Using Redis to cache lookups 250 ■ Defining custom channels 256 Bringing it all together: clearing the cache when a message is received 257 8.5 Summary 258 9 Distributed tracing with Spring Cloud Sleuth and Zipkin 259 9.1 Spring Cloud Sleuth and the correlation ID 260 Adding Spring Cloud sleuth to licensing and organization 261 Anatomy of a Spring Cloud Sleuth trace 262Licensed to <null>
📄 Page
15
CONTENTSxiv9.2 Log aggregation and Spring Cloud Sleuth 263 A Spring Cloud Sleuth/Papertrail implementation in action 265 Create a Papertrail account and configure a syslog connector 267 Redirecting Docker output to Papertrail 268 ■ Searching for Spring Cloud Sleuth trace IDs in Papertrail 270 ■ Adding the correlation ID to the HTTP response with Zuul 272 9.3 Distributed tracing with Open Zipkin 274 Setting up the Spring Cloud Sleuth and Zipkin dependencies 275 Configuring the services to point to Zipkin 275 ■ Installing and configuring a Zipkin server 276 ■ Setting tracing levels 278 Using Zipkin to trace transactions 278 ■ Visualizing a more complex transaction 281 ■ Capturing messaging traces 282 Adding custom spans 284 9.4 Summary 287 10 Deploying your microservices 288 10.1 EagleEye: setting up your core infrastructure in the cloud 290 Creating the PostgreSQL database using Amazon RDS 293 Creating the Redis cluster in Amazon 296 ■ Creating an ECS cluster 298 10.2 Beyond the infrastructure: deploying EagleEye 302 Deploying the EagleEye services to ECS manually 303 10.3 The architecture of a build/deployment pipeline 305 10.4 Your build and deployment pipeline in action 309 10.5 Beginning your build deploy/pipeline: GitHub and Travis CI 311 10.6 Enabling your service to build in Travis CI 312 Core build run-time configuration 315 ■ Pre-build tool installations 318 ■ Executing the build 320 ■ Tagging the source control code 320 ■ Building the microservices and creating the Docker images 321 ■ Pushing the images to Docker Hub 322 Starting the services in Amazon ECS 323 ■ Kicking off the platform tests 323 10.7 Closing thoughts on the build/deployment pipeline 325 10.8 Summary 325 appendix A Running a cloud on your desktop 327 appendix B OAuth2 grant types 336 index 345Licensed to <null>
📄 Page
16
preface It’s ironic that in writing a book, the last part of the book you write is often the begin- ning of the book. It’s also often the most difficult part to put down on paper. Why? Because you have to explain to everyone why you’re so passionate about a subject that you spent the last one and a half years of your life writing a book about it. It’s hard to articulate why anyone would spend such a large amount of time on a technical book. One rarely writes software books for the money or the fame. Here’s the reason why I wrote this book: I love writing code. It’s a calling for me and it’s also a creative activity—akin to drawing, painting, or playing an instrument. Those outside the field of software development have a hard time understanding this. I especially like building distributed applications. For me, it’s an amazing thing to see an application work across dozens (even hundreds) of servers. It’s like watching an orchestra playing a piece of music. While the final product of an orchestra is beauti- ful, the making of it is often a lot of hard work and requires a significant amount of practice. The same goes for writing a massively distributed application. Since I entered the software development field 25 years ago, I’ve watched the industry struggle with the “right” way to build distributed applications. I’ve seen dis- tributed service standards such as CORBA rise and fall. Monstrously big companies have tried to push big and, often, proprietary protocols. Anyone remember Micro- soft’s Distributed Component Object Model (DCOM) or Oracle’s J2EE’s Enterprise Java Beans 2 (EJB)? I watched as technology companies and their followers rushed to build service-oriented architectures (SOA) using heavy XML-based schemas. In each case, these approaches for building distributed systems often collapsed under their own weight. I’m not saying that these technologies weren’t used to build some very powerful applications. The reality is that they couldn’t keep up with thexv Licensed to <null>
📄 Page
17
PREFACExvidemand of the users. Ten years ago, smartphones were just being introduced to the market and cloud computing was in the earliest stage of infancy. Also, the standards and technology for distributed application development were too complicated for the average developer to understand and easily use in practice. Nothing speaks truth in the software development industry like written code. When the standards get in the way of this, the standards quickly get discarded. When I first heard of the microservices approach to building applications I was more than a little skeptical. “Great, another silver-bullet approach to building distrib- uted applications,” I thought. However, as I started diving into the concepts, I realized the simplicity of microservices could be a game changer. A microservice architecture focuses on building small services that use simple protocols (HTTP and JSON) to com- municate. That’s it. You can write a microservice with nearly any programming lan- guage. There’s beauty in this simplicity. However, while building an individual microservice is easy, operationalizing and scaling it is difficult. Getting hundreds of small distributed components to work together and then building a resilient application from them can be incredibly diffi- cult to do. In distributed computing, failure is a fact of life and how your application deals with it is incredibly difficult to get right. To paraphrase my colleagues Chris Miller and Shawn Hagwood: “If it’s not breaking once in a while, you’re not building.” It’s these failures that inspired me to write this book. I hate to build things from scratch when I don’t have to. The reality is that Java is the lingua franca for most appli- cation development efforts, especially in the enterprise. The Spring framework has for many organizations become the de facto framework for most application develop- ment. I’d already been doing application development in Java for almost 20 years (I remember the Dancing Duke applet) and Spring for almost 10 years. As I began my microservices journey, I was delighted and excited to watch the emergence of Spring Cloud. The Spring Cloud framework provides out-of-the-box solutions for many of the common development and operational problems you’ll run into as a microservice developer. Spring Cloud lets you use only the pieces you need and minimizes the amount of work you need to do to build and deploy production-ready Java micro- services. It does this by using other battle-hardened technologies from companies and groups such as Netflix, HashiCorp, and the Apache foundation. I’ve always considered myself an average developer who, at the end of the day, has deadlines to meet. That’s why I undertook the project of writing this book. I wanted a book that I could use in my day-to-day work. I wanted something with direct (and hopefully) straightforward code examples. I always want to make sure that the mate- rial in this book can be consumed as individual chapters or in its entirety. I hope you find this book useful and I hope you enjoy reading it as much as I enjoyed writing it.Licensed to <null>
📄 Page
18
acknowledgments As I sit down to write these acknowledgments, I can’t help but think back to 2014 when I ran my first marathon. Writing a book is a lot like running a marathon. Writing the proposal and the outline for the book is much like the training process. It gets your thoughts in shape, it focuses you for what’s ahead and, yes, near the end of the process, it can be more than a little tedious and brutal. When you start writing the book, it’s a lot like race day. You start the marathon excited and full of energy. You know you’re trying to do something bigger than any- thing you might have done before and it’s both exciting and nerve-wracking. This is what you’ve trained for, but at the same time, there’s always that small voice of doubt in the back of your mind that says you won’t finish what you started. What I’ve learned from running is that races aren’t completed one mile at a time. Instead, they’re run one foot in front of the other. The miles run are the sum of the individual footsteps. When my children are struggling with something, I laugh and ask them, “How do you write a book? One word, one single step at a time.” They usually roll their eyes, but in the end there’s no other way around this indisputable and iron- clad law. However, when you run a marathon, you might be the one running the race, but you’re never running it alone. There’s a whole team of people there to give you sup- port, time, and advice along the way. It has been the same experience writing this book. I’d like to start by thanking Manning for the support they gave me in writing this book. It started with Greg Wild, my acquisitions editor, who patiently worked with me as I refined the core concepts in this book and guided me through the proposal pro- cess. Along the way, Marina Michaels, my development editor, kept me honest andxvii Licensed to <null>
📄 Page
19
ACKNOWLEDGMENTSxviiichallenged me to become a better author. I’d also like to thank Raphael Villela and Joshua White, my technical editors, who constantly checked my work and ensured the overall quality of the examples and the code I produced. I’m extremely grateful for the time, talent, and commitment each of these individuals put into into the overall project. I’d also like to thank the reviewers who provided feedback on the manuscript throughout the writing and development process: Aditya Kumar, Adrian M. Rossi, Ashwin Raj, Christian Bach, Edgar Knapp, Jared Duncan, Jiri Pik, John Guthrie, Mirko Bernardoni, Paul Balogh, Pierluigi Riti, Raju Myadam, Rambabu Posa, Sergey Evsikov, and Vipul Gupta. I want to close these acknowledgments with a deep sense of thanks for the love and time my family has given me in working on this project. To my wife Janet, you have been my best friend and the love of my life. When I’m tired and want to give up, I only have to listen for the sound of your footsteps next to me to know that you’re always running beside me, never telling me no, and always pushing me forward. To my son Christopher, you’re growing up to be an incredible young man. I can- not wait for the day when you truly discover your passion, because there will be noth- ing in this world that can stop you from reaching your goals. To my daughter Agatha, I’d give all the money I have to see the world through your eyes for just 10 minutes. The experience would make me a better author and more importantly a better person. Your intellect, your power of observation, and cre- ativity humble me. To my four-year-old son, Jack: Buddy, thank you being patient with me whenever I said, “I can’t play right now because Daddy has to work on the book.” You always make me laugh and you make this whole family complete. Nothing makes me happier than when I see you being the jokester and playing with everyone in the family. My race with this book is done. Like my marathon, I’ve left nothing on the table in writing this book. I have nothing but gratitude for the Manning team and the MEAP readers who bought this book early and gave me so much valuable feedback. I hope in the end that you enjoy this book as much as I enjoyed writing it. Thank you. Licensed to <null>
📄 Page
20
about this book Spring Microservices in Action was written for the practicing Java/Spring developer who needs hands-on advice and examples of how to build and operationalize microservice- based applications. When I wrote this book, I wanted it to be based around core microservice patterns that aligned with Spring Boot and Spring Cloud examples that demonstrated the patterns in action. As such, you’ll find specific microservice design patterns discussed in almost every chapter, along with examples of the patterns imple- mented using Spring Boot and Spring Cloud. You should read this book if You’re a Java developer who has experience building distributed applications (1-3 years). You have a background in Spring (1+ years). You’re interested in learning how to build microservice-based applications. You’re interested in how you can use microservices for building cloud-based applications. You want to know if Java and Spring are relevant technologies for building microservice-based applications. You’re interested in seeing what goes into deploying a microservice-based appli- cation to the cloud. How this book is organized Spring Microservices in Action consists of 10 chapters and two appendixes: Chapter 1 introduces you to why the microservices architecture is an important and relevant approach to building applications, especially cloud-based applications.xix Licensed to <null>