40,81 €
Explore the reactive system and create efficient microservices with Spring Boot 2.1 and Spring Cloud
Key Features
Book Description
These days, businesses need a new type of system that can remain responsive at all times. This is achievable with reactive programming; however, the development of these kinds of systems is a complex task, requiring a deep understanding of the domain. In order to develop highly responsive systems, the developers of the Spring Framework came up with Project Reactor.
Hands-On Reactive Programming in Spring 5 begins with the fundamentals of Spring Reactive programming. You'll explore the endless possibilities of building efficient reactive systems with the Spring 5 Framework along with other tools such as WebFlux and Spring Boot. Further on, you'll study reactive programming techniques and apply them to databases and cross-server communication. You will advance your skills in scaling up Spring Cloud Streams and run independent, high-performant reactive microservices.
By the end of the book, you will be able to put your skills to use and get on board with the reactive revolution in Spring 5.1!
What you will learn
Who this book is for
This book is for Java developers who use Spring to develop their applications and want to build robust and reactive applications that can scale in the cloud. Basic knowledge of distributed systems and asynchronous programming will help you understand the concepts covered in this book.
Das E-Book können Sie in Legimi-Apps oder einer beliebigen App lesen, die das folgende Format unterstützen:
Seitenzahl: 730
Veröffentlichungsjahr: 2018
Copyright © 2018 Packt Publishing
All rights reserved. No part of this book may be reproduced, stored in a retrieval system, or transmitted in any form or by any means, without the prior written permission of the publisher, except in the case of brief quotations embedded in critical articles or reviews.
Every effort has been made in the preparation of this book to ensure the accuracy of the information presented. However, the information contained in this book is sold without warranty, either express or implied. Neither the authors, nor Packt Publishing or its dealers and distributors, will be held liable for any damages caused or alleged to have been caused directly or indirectly by this book.
Packt Publishing has endeavored to provide trademark information about all of the companies and products mentioned in this book by the appropriate use of capitals. However, Packt Publishing cannot guarantee the accuracy of this information.
Commissioning Editor: Aaron LazarAcquisition Editor: Alok DhuriContent Development Editor: Tiksha SarangTechnical Editor: Abhishek SharmaCopy Editor:Safis EditingProject Coordinator: Prajakta NaikProofreader: Safis EditingIndexer: Rekha NairGraphics: Jisha ChirayilProduction Coordinator: Arvindkumar Gupta
First published: October 2018
Production reference: 2041018
Published by Packt Publishing Ltd. Livery Place 35 Livery Street Birmingham B3 2PB, UK.
ISBN 978-1-78728-495-1
www.packtpub.com
Mapt is an online digital library that gives you full access to over 5,000 books and videos, as well as industry leading tools to help you plan your personal development and advance your career. For more information, please visit our website.
Spend less time learning and more time coding with practical eBooks and videos from over 4,000 industry professionals
Improve your learning with Skill Plans built especially for you
Get a free eBook or video every month
Mapt is fully searchable
Copy and paste, print, and bookmark content
Did you know that Packt offers eBook versions of every book published, with PDF and ePub files available? You can upgrade to the eBook version at www.Packt.com and as a print book customer, you are entitled to a discount on the eBook copy. Get in touch with us at [email protected] for more details.
At www.Packt.com, you can also read a collection of free technical articles, sign up for a range of free newsletters, and receive exclusive discounts and offers on Packt books and eBooks.
Reactive programming is finally getting the attention it deserves with the help of famous Java names such as Spring Boot and Spring Framework. Which qualifier would you use to describe Spring solutions? The usual answer I hear and read from various users—pragmatic. The reactive support offered is no exception, and the team has chosen to keep supporting both reactive and non-reactive stacks. With choice comes responsibility, it is, therefore, critical to understand when to design your application "the reactive way" and what best practices you can apply to your next production-ready systems.
Spring positions itself as a provider of the best tooling available to write all kinds of microservices. With its reactive stack, Spring helps developers to create incredibly efficient, available, and resilient endpoints. As a byproduct, reactive Spring microservices tolerate network latency and cope with failure in a much less impacting way. Think about it—it's the right solution if you are writing an Edge API, a mobile backend, or a heavily mutualized microservice! The secret? Reactive microservices isolate slow transactions and reward the fastest.
Once you have qualified your needs, Project Reactor will be a reactive foundation of choice that will naturally pair with your reactive Spring project. In its latest 3.x iterations, it implements most of the Reactive extensions described first by Microsoft in 2011. Along with a standard vocabulary, Reactor introduces first-class support for Reactive Streams flow control at every functional stage and unique features such as Context passing.
In a synthetic but not simplistic set of example-driven chapters, Oleh and Igor describe a fantastic journey into reactive programming and reactive systems. After a quick context setting, reminding the history and challenges of Project Reactor, we quickly dive into ready-to-use examples running on Spring Boot 2. The book never does miss an occasion to seriously cover testing, giving a clear idea on how to produce quality reactive code.
Oleh and Igor perfectly introduce their readers to those reactive design patterns for the scalability needs of today and tomorrow. The authors cover more than reactive programming with plenty of guidance on Spring Boot or Spring Framework. In a forward-looking chapter, authors stimulate the readers' curiosity with some details about reactive communications using RSocket—a promising technology poised to deliver reactive benefits to the transport layer.
I hope you will take as much pleasure from reading this book as I did and keep learning new ways of writing applications.
Stéphane Maldini
Lead developer, Project Reactor
Oleh Dokuka is an experienced software engineer, Pivotal Champion, and one of the top contributors to Project Reactor and Spring Framework. He knows the internals of both frameworks very well and advocates reactive programming with Project Reactor on a daily basis. Along with that, the author applies Spring Framework and Project Reactor in software development, so he knows how to build reactive systems using these technologies.
Igor Lozynskyi is a senior Java developer who primarily focuses on developing reliable, scalable, and blazingly fast systems. He has over seven years of experience with the Java platform. He is passionate about interesting and dynamic projects both in life and in software development.
Mikalai Alimenkou is a senior delivery manager, Java tech lead, and experienced coach. An expert in Java development, scalable architecture, agile engineering practices, QA processes, and project management, he has more than 14 years of development experience, specializes in complex, distributed, scalable systems, and global company transformations. He's an active participant and speaker at many international conferences and is the founder and an independent consultant at XP Injection—a training and consulting provider. He's an organizer and founder of Selenium Camp, JEEConf, and XP Days Ukraine international conferences, as well as the Active Anonymous Developers Club (UADEVCLUB).
Nazarii Cherkas works as a solutions architect at Hazelcast—a company that develops open source projects such as Hazelcast IMDG and Hazelcast Jet. Nazarii has many years of experience of working in different positions, from Java engineer to team lead. He has been involved in various projects for different industries, from telecoms and healthcare to critical systems serving the infrastructure of one of world's biggest airlines. He holds a master's degree in computer science of the Yuriy Fedkovych Chernivtsi National University.
Tomasz Nurkiewicz is a Java champion. He had spent half of his life programming. On a daily basis, he works in the e-commerce sector. He's involved in open source, is DZone's most valuable blogger, and used to be very active on Stack Overflow. He's an author, trainer, conference speaker, technical reviewer, and runner. He claims that code that's not tested automatically is not a feature but just a rumor. He also wrote a book on RxJava.
If you're interested in becoming an author for Packt, please visit authors.packtpub.com and apply today. We have worked with thousands of developers and tech professionals, just like you, to help them share their insight with the global tech community. You can make a general application, apply for a specific hot topic that we are recruiting an author for, or submit your own idea.
Title Page
Copyright and Credits
Hands-On Reactive Programming in Spring 5
Dedication
Packt Upsell
Why subscribe?
Packt.com
Foreword
Contributors
About the authors
About the reviewers
Packt is searching for authors like you
Preface
Who this book is for
What this book covers
To get the most out of this book
Download the example code files
Download the color images
Conventions used
Get in touch
Reviews
Why Reactive Spring?
Why reactive?
Message-driven communication
Reactivity use cases
Why Reactive Spring? 
Reactivity on the service level
Summary
Reactive Programming in Spring - Basic Concepts
Early reactive solutions in Spring
Observer pattern
Observer pattern usage example
Publish-Subscribe pattern with @EventListener
Building applications with @EventListener
Bootstrapping a Spring application
Implementing business logic
Asynchronous HTTP with Spring Web MVC
Exposing the SSE endpoint
Configuring asynchronous support  
Building a UI with SSE support
Verifying application functionality
Criticism of the solution
RxJava as a reactive framework
Observer plus iterator equals Reactive Stream
Producing and consuming streams
Generating an asynchronous sequence
Stream transformation and marble diagrams
Map operator
Filter operator
Count operator
Zip operator
Prerequisites and benefits of RxJava
Rebuilding our application with RxJava
Implementing business logic
Custom SseEmitter
Exposing the SSE endpoint
Application configuration
Brief history of reactive libraries
Reactive landscape
Summary
Reactive Streams - the New Streams' Standard
Reactivity for everyone
The API's inconsistency problem
Pull versus push
The flow control problem
Slow producer and fast consumer
Fast producer and slow consumer
Unbounded queue
Bounded drop queue
Bounded blocking queue
The solution
The basics of the Reactive Streams spec
Reactive Streams spec in action
The introduction of the Processor notion 
Reactive Streams technology compatibility kit
The Publisher verification
The Subscriber verification
JDK 9
Advanced - async and parallel in Reactive Streams
Transfiguration of the Reactive Landscape
RxJava transfiguration
Vert.x adjustments
Ratpack improvements
MongoDB Reactive Streams driver 
A composition of reactive technologies in action
Summary
Project Reactor - the Foundation for Reactive Apps
A brief history of Project Reactor
Project Reactor version 1.x
Project Reactor version 2.x
Project Reactor essentials
Adding Reactor to the project
Reactive types – Flux and Mono
Flux
Mono
Reactive types of RxJava 2
Observable
Flowable
Single
Maybe
Completable
Creating Flux and Mono sequences
Subscribing to Reactive Streams
Implementing custom subscribers
Transforming reactive sequences with operators
Mapping elements of reactive sequences 
Filtering reactive sequences
Collecting reactive sequences
Reducing stream elements
Combining Reactive Streams
Batching stream elements
The flatMap, concatMap, and flatMapSequential operators
Sampling elements 
Transforming reactive sequences into blocking structures
Peeking elements while sequence processing
Materializing and dematerializing signals
Finding an appropriate operator
Creating streams programmatically
Factory methods – push and create
Factory method – generate
Wrapping disposable resources into Reactive Streams
Wrapping reactive transactions with the usingWhen factory
Handling errors
Backpressure handling
Hot and cold streams
Multicasting elements of a stream
Caching elements of a stream
Sharing elements of a stream
Dealing with time
Composing and transforming Reactive Streams
Processors
Testing and debugging Project Reactor
Reactor Addons
Advanced Project Reactor 
Reactive Streams life cycle
Assembly-time
Subscription-time
Runtime
The thread scheduling model in Reactor
The publishOn operator
Parallelization with the publishOn operator
The subscribeOn operator
The parallel operator
Scheduler
Rector Context
Internals of Project Reactor
Macro-fusion
Micro-fusion
Summary
Going Reactive with Spring Boot 2
A fast start as the key to success
Using Spring Roo to try to develop applications faster
Spring Boot as a key to fast-growing applications
Reactive in Spring Boot 2.0
Reactive in Spring Core
Support for reactive types conversion
Reactive I/O
Reactive in web
Reactive in Spring Data
Reactive in Spring Session
Reactive in Spring Security
Reactive in Spring Cloud
Reactive in Spring Test
Reactive in monitoring
Summary
WebFlux Async Non-Blocking Communication
WebFlux as a central reactive server foundation
The reactive web core
The reactive web and MVC frameworks
Purely functional web with WebFlux
Non-blocking cross-service communication with WebClient
Reactive WebSocket API
Server-side WebSocket API 
Client-side WebSocket API
WebFlux WebSocket versus the Spring WebSocket module 
Reactive SSE as a lightweight replacement for WebSockets
Reactive template engines
Reactive web security
Reactive access to SecurityContext
Enabling reactive security
Interaction with other reactive libraries
WebFlux versus Web MVC
Laws matter when comparing frameworks 
Little's Law
Amdahl's Law
The Universal Scalability Law
Thorough analysis and comparison
Understanding the processing models in WebFlux and Web MVC
Impact of processing models on throughput and latency
Challenges with the WebFlux processing model
Impact of different processing models on memory consumption
Impact of processing models on usability
Application of WebFlux
Microservice-based systems
Systems that handle clients with slow connections
Streaming or real-time systems
WebFlux in action
Summary
Reactive Database Access
Data handling patterns in the modern world
Domain-driven design
Data stores in the era of microservices
Polyglot persistence
Database as a Service
Sharing data across microservices
Distributed transactions
Event-driven architecture
Eventual consistency
The SAGA pattern
Event sourcing
Command Query Responsibility Segregation
Conflict-free replicated data types
Messaging system as a data store
Synchronous model for data retrieval
Wire protocol for database access
Database driver
JDBC
Connection management
Making relational database access reactive
Spring JDBC
Spring Data JDBC
Making Spring Data JDBC reactive
JPA
Making JPA reactive
Spring Data JPA
Making Spring Data JPA reactive
Spring Data NoSQL
Limitations of the synchronous model
Advantages of the synchronous model
Reactive data access with Spring Data
Using MongoDB reactive repository
Combining repository operations
How reactive repositories work
Pagination support
ReactiveMongoRepository implementation details
Using ReactiveMongoTemplate
Using reactive drivers (MongoDB)
Using asynchronous drivers (Cassandra)
Reactive transactions
Reactive transactions with MongoDB 4
Distributed transactions with the SAGA pattern
Spring Data reactive connectors
Reactive MongoDB connector
Reactive Cassandra connector
Reactive Couchbase connector
Reactive Redis connector
Limitations and anticipated improvements
Asynchronous Database Access
Reactive Relational Database Connectivity
Using R2DBC with Spring Data R2DBC
Transforming a synchronous repository into reactive
Using the rxjava2-jdbc library
Wrapping a synchronous CrudRepository
Reactive Spring Data in action
Summary
Scaling Up with Cloud Streams
Message brokers as the key to message-driven systems
Server-side load balancing
Client-side load balancing with Spring Cloud and Ribbon
Message brokers as an elastic, reliable layer for message transferring
The market of message brokers
Spring Cloud Streams as a bridge to Spring Ecosystem
Reactive programming in the cloud
Spring Cloud Data Flow
The finest-grained application with Spring Cloud Function
Spring Cloud – function as a part of a data flow
RSocket for low-latency, reactive message passing
RSocket versus Reactor-Netty
RSocket in Java
RSocket versus gRPC
RSocket in Spring Framework
RSocket in other frameworks 
The ScaleCube Project
The Proteus Project
Summarizing RSocket
Summary
Testing the Reactive Application
Why are reactive streams hard to test?
Testing reactive streams with StepVerifier
Essentials of StepVerifier
Advanced testing with StepVerifier
Dealing with virtual time
Verifying reactive context
Testing WebFlux
Testing Controllers with WebTestClient 
Testing WebSocket
Summary
And, Finally, Release It!
The importance of DevOps-friendly apps
Monitoring the Reactive Spring application
Spring Boot Actuator
Adding an actuator to the project
Service info endpoint
Health information endpoint
Metrics endpoint
Loggers management endpoint
Other valuable endpoints
Writing custom actuator endpoints
Securing actuator endpoints
Micrometer
Default Spring Boot metrics
Monitoring Reactive Streams
Monitoring reactor flows
Monitoring reactor schedulers
Adding custom Micrometer meters
Distributed tracing with Spring Boot Sleuth
Pretty UI with Spring Boot Admin 2.x
Deploying to the cloud
Deploying to Amazon Web Services
Deploying to the Google Kubernetes Engine
Deploying to Pivotal Cloud Foundry
Discovering RabbitMQ in PCF
Discovering MongoDB in PCF
Configurationless deployment with Spring Cloud Data Flow for PCF
Knative for FaaS over Kubernetes and Istio
Bits of advice for successful application deployment
Summary
Other Books You May Enjoy
Leave a review - let other readers know what you think
Reactive systems are responsive at all times, which is what most businesses demand. The development of such systems is a complex task and requires a deep understanding of the domain. Fortunately, developers of the Spring Framework have created a new, reactive version of the project.
With Reactive Programming in Spring 5, you'll explore the fascinating process of developing a Reactive system using Spring Framework 5.
This book begins with the foundation of Spring Reactive programming. You will gain an understanding of the possibilities of the framework and learn about the fundamentals of reactivity. Further on, you will study the techniques of reactive programming, learn how to apply them to databases, and use them for cross-server communication. All of these tasks will be applied to a real project example, which will enable you to practice the skills learned.
Get on board with the reactive revolution in Spring 5!
This book is for Java developers who use Spring to develop their applications and want to be able to build robust and reactive applications that can scale in the cloud. Basic knowledge of distributed systems and asynchronous programming is assumed.
Chapter 1, Why Reactive Spring?, covers the business cases in which reactivity fits very well. You will see why a reactive solution is better than a proactive one. Also, you will get an overview of a few code examples that show different ways of cross-server communication, as well as an understanding of today's business needs and their requirements of the modern Spring Framework.
Chapter 2, Reactive Programming in Spring - Basic Concepts, expands on the potential of reactive programming and its central concepts by means of code examples. The chapter then shows the power of reactive, asynchronous, non-blocking programming in the Spring Framework with code examples, and applies this technique in business cases. You'll garner an overview of the publisher-subscriber model in examples of code, understand the power of reactive Flow events, and learn about the application of these techniques in real-world scenarios.
Chapter 3, Reactive Streams - the New Streams' Standard, concentrates on the problems that are introduced by Reactive Extensions. Code examples are used to explore the different approaches and expand upon the nature of the problems. The chapter also delves into problem-solving and the introduction of the Reactive Streams specification, which introduces new components to the well-known publisher-subscriber model.
Chapter 4, Project Reactor - the Foundation for Reactive Apps, looks at the realization of the reactive library; that is, fully implementing the Reactive Streams specification. Firstly, this chapter emphasizes the advantages of implementing Reactor, and then it takes a survey of the reasons that motivated Spring developers to develop their own new solution. Also, this chapter embraces the fundamentals of this impressive library—here you'll get an understanding of Mono and Flux, as well as the applications for reactive types.
Chapter 5, Going Reactive with Spring Boot 2, introduces the Spring 5 reactive modules required for reactive application development. Here you'll learn how to get started with modules, and how Spring Boot 2 helps developers configure applications fast.
Chapter 6, WebFlux Async Non-Blocking Communication, covers the primary module, Spring WebFlux, which is the essential tool for the organization of asynchronous, non-blocking communication with both the user and external services. This chapter gives an overview of the advantages of this module and the comparison with Spring MVC.
Chapter 7, Reactive Database Access, goes into the Spring 5-based reactive programming model for data access. This chapter's emphasis is upon reactive reinforcement in Spring Data modules and explores the features that come out of the box with Spring 5, Reactive Streams, and Project Reactor. In this chapter, you will encounter code that shows a reactive approach for communication with different databases, such as SQL and NoSQL databases.
Chapter 8, Scaling Up with Cloud Streams, will introduce you to the reactive features of Spring Cloud Streams. Before starting to learn about the new brilliant capabilities of the module, you'll be given an overview of business case gaps and the problems that you can be faced with when scaling on different servers. This chapter reveals to you the power of the Spring Cloud solution, covering its implementation via code examples of the relevant Spring Boot 2 configuration.
Chapter 9, Testing the Reactive Application, covers the basics required for reactive pipeline testing. This chapter introduces the Spring 5 Test and Project Reactor Test modules for writing tests. Here you will see how to manipulate the frequency of events, move timelines, enhance thread pools, mock results, and assert passed messages.
Chapter 10, And, Finally, Release It!, is a step-by-step guide to current solution deployment and monitoring. Here you will see how to monitoring reactive microservices, for which Spring 5 modules are required. Also, the chapter covers the tools that will be useful for monitoring the aggregation and display of results.
The development of reactive systems is a complex task, requiring a deep understanding of the domain. A knowledge of distributed systems and asynchronous programming is required.
You can download the example code files for this book from your account at www.packt.com. If you purchased this book elsewhere, you can visit www.packt.com/support and register to have the files emailed directly to you.
You can download the code files by following these steps:
Log in or register at
www.packt.com
.
Select the
SUPPORT
tab.
Click on
Code Downloads & Errata
.
Enter the name of the book in the
Search
box and follow the onscreen instructions.
Once the file is downloaded, please make sure that you unzip or extract the folder using the latest version of:
WinRAR/7-Zip for Windows
Zipeg/iZip/UnRarX for Mac
7-Zip/PeaZip for Linux
The code bundle for the book is also hosted on GitHub at https://github.com/PacktPublishing/Hands-On-Reactive-Programming-in-Spring-5. In case there's an update to the code, it will be updated on the existing GitHub repository.
We also have other code bundles from our rich catalog of books and videos available at https://github.com/PacktPublishing/. Check them out!
We also provide a PDF file that has color images of the screenshots/diagrams used in this book. You can download it here: https://www.packtpub.com/sites/default/files/downloads/9781787284951_ColorImages.pdf.
There are a number of text conventions used throughout this book.
CodeInText: Indicates code words in text, database table names, folder names, filenames, file extensions, pathnames, dummy URLs, user input, and Twitter handles. Here is an example: "The first call invokesonSubscribe(), which storesSubscriptionlocally and then notifiesPublisher about their readiness to receive newsletters via the request()method."
A block of code is set as follows:
@Overridepublic long maxElementsFromPublisher() { return 1;}
Any command-line input or output is written as follows:
./gradlew clean build
Bold: Indicates a new term, an important word, or words that you see onscreen.
Feedback from our readers is always welcome.
General feedback: If you have questions about any aspect of this book, mention the book title in the subject of your message and email us at [email protected].
Errata: Although we have taken every care to ensure the accuracy of our content, mistakes do happen. If you have found a mistake in this book, we would be grateful if you would report this to us. Please visit www.packt.com/submit-errata, selecting your book, clicking on the Errata Submission Form link, and entering the details.
Piracy: If you come across any illegal copies of our works in any form on the Internet, we would be grateful if you would provide us with the location address or website name. Please contact us at [email protected] with a link to the material.
If you are interested in becoming an author: If there is a topic that you have expertise in and you are interested in either writing or contributing to a book, please visit authors.packtpub.com.
Please leave a review. Once you have read and used this book, why not leave a review on the site that you purchased it from? Potential readers can then see and use your unbiased opinion to make purchase decisions, we at Packt can understand what you think about our products, and our authors can see your feedback on their book. Thank you!
For more information about Packt, please visit packt.com.
In this chapter, we are going to explain the concept of reactivity, looking at why reactive approaches are better than traditional approaches. To do this, we will look at examples in which traditional approaches failed. In addition to this, we will explore the fundamental principles of building a robust system, which is mostly referred to as reactive systems. We will also take an overview of the conceptual reasons for building message-driven communication between distributed servers, covering business cases in which reactivity fits well. Then, we will expand the meaning of reactive programming to build a fine-grained reactive system. We will also discuss why the Spring Framework team decided to include a reactive approach as the core part of Spring Framework 5. Based on the content of this chapter, we will understand the importance of reactivity and why it is a good idea to move our projects to the reactive world.
In this chapter, we will cover the following topics:
The fundamental principles of the reactive system
Business cases in which a reactive system design matches perfectly
Programming techniques that are more suitable for a reactive system
Reasons for moving Spring Framework to reactivity
Nowadays,reactiveis a buzzword—so exciting but so confusing. However, should we still care about reactivity even if it takes an honorable place in conferences around the world? If we google the word reactive, we will see that the most popular association is programming, in which it defines the meaning of a programming model. However, that is not the only meaning for reactivity. Behind that word, there are hidden fundamental design principles aimed at building a robust system. To understand the value of reactivity as an essential design principle, let's imagine that we are developing a small business.
Suppose our small business is a web store with a few cutting-edge products at an attractive price. As is the case with the majority of projects in this sector, we will hire software engineers to solve any problems that we encounter. We opted for the traditional approaches to development, and, during a few development interactions, we created our store.
Usually, our service is visited by about one thousand users per hour. To serve the usual demand, we bought a modern computer and ran the Tomcat web server as well as configuring Tomcat's thread pool with 500 allocated threads. The average response time for the majority of user requests is about 250 milliseconds. By doing a naive calculation of the capacity for that configuration, we can be sure that the system can handle about 2,000 user requests per second. According to statistics, the number of users previously mentionedproduced around 1,000 requests per second on average. Consequently,thecurrent system's capacity will be enough for the average load.
To summarize, we configured our application with the margin regarding capacity. Moreover, our web store had been working stablyuntilthelast Friday in November, which is Black Friday.
Black Friday is a valuable day for both customers and retailers. For the customer, it is a chance to buy goods at discounted prices. And for retailers, it is a way to earn money and popularize products. However, this day is characterized by an unusual influx of clients, and that may be a significant cause of failure in production.
And, of course, we failed! At some point in time, the load exceeded all expectations. There were no vacant threads in the thread pool to process user requests. In turn, the backup server was not able to handle such an unpredictable invasion, and, in the end, this caused a rise in the response time and periodic service outage. At this point, we started losing some user requests, and, finally, our clients became dissatisfied and preferred dealing with competitors.
In the end, a lot of potential customers and money were lost, and the store's ratingdecreased. This was all a result of the fact thatwe couldn't stay responsive under the increased workload.
But, don't worry, this is nothing new. At one point in time, giants such as Amazon and Walmart also faced this problem and have since found a solution. Nevertheless, we will follow the same roads as our predecessors, gaining an understanding of the central principles of designing robust systems and then providing a general definition for them.
Now, the central question that should remain in our minds is—How should we be responsive? As we might now understand from the example given previously, an application should react to changes. This should include changes in demand (load) and changes in the availability of external services. In other words, it should be reactive to any changes that may affect the system's ability to respond to user requests.
One of the first ways to achieve the primary goal is through elasticity. This describes the ability to stay responsive under a varying workload, meaning that the throughput of the system should increase automatically when more users start using it and it should decrease automatically when the demand goes down. From the application perspective, this feature enables system responsiveness because at any point in time the system can be expanded without affecting the average latency.
For example, by providing additional computation resources or additional instances, the throughput of our system might be increased. The responsiveness will then increase as a consequence. On the other hand, if demand is low, the system should shrink in terms of resource consumption, thereby reducing business expenses. We may achieve elasticity by employing scalability, which might either be horizontal or vertical. However, achieving scalability of the distributed system is a challenge that is typically limited by the introduction of bottlenecks or synchronization points within the system. From the theoretical and practical perspectives, such problems are explained by Amdahl's Law and Gunther's Universal Scalability Model. We will discuss these inChapter 6, WebFlux Async Non-Blocking Communication.
However, building a scalable distributed system without the ability to stay responsive regardless of failures is a challenge. Let's think about a situation in which one part of our system is unavailable. Here, an external payment service goes down, and all user attempts to pay for the goods will fail. This is something that breaks the responsiveness of the system, which may be unacceptable in some cases. For example, if users cannot proceed with their purchases easily, they will probably go to a competitor's web store. To deliver a high-quality user experience, we must care about the system's responsiveness. The acceptance criteria for the system are the ability to stay responsive under failures, or, in other words, to be resilient.This may be achieved by applying isolation between functional components of the system, thereby isolating all internal failures and enabling independence. Let's switch back to the Amazon web store. Amazon has many different functional components such as the order list, payment service, advertising service, comment service, and many others. For example, in the case of a payment service outage, we may accept user orders and then schedule a request auto-retry, thereby protecting the user from undesired failures. Another example might be isolation from the comments service. If the comments service goes down, the purchasing and orders list services should not be affected and should work without any problems.
Another point to emphasize is that elasticity and resilience are tightly coupled, and we achieve a truly responsive system only by enabling both. With scalability, we can have multiple replicas of the component so that, if one fails, we can detect this, minimize its impact on the rest of the system, and switch to another replica.
In the previous section, we learned the importance of reactivity and the fundamental principles of the reactive system, and we have seen why message-driven communication is an essential constituent of the reactive ecosystem. Nonetheless, to reinforce what we have learned, it is necessary to touch on real-world examples of its application. First of all, the reactive system is about architecture, and it may be applied anywhere. It may be used in simple websites, in large enterprise solutions, or even in fast-streaming or big-data systems. But let's start with the simplest—consider the example of a web store that we have already seen in the previous section. In this section, we will cover possible improvement and changes in the design that may help in achieving a reactive system. The following diagram helps us get acquainted with the overall architecture of the proposed solution:
The preceding diagram expands a list of useful practices that allow the reactive system to be achieved. Here, we improved our small web store by applying modern microservice patterns. In that case, we use an API Gateway pattern for achieving location transparency. It provides the identification of a specific resource with no knowledge about particular services that are responsible for handling requests.
In turn, the responsibility for keeping information about available services up to date is implemented using the service registry pattern and achieved with the support of the client-side discovery pattern. It should be noticed, that in the previous example, the service gateway and service registry are installed on the same machine, which may be useful in the case of a small distributed system. Additionally, the high responsiveness of the system is achieved by applying replication to the service. On the other hand, failure tolerance is attained by properly employed message-driven communication using Apache Kafka and the independent Payment Proxy Service (the point with Retry N times description in Diagram 1.4), which is responsible for redelivering payment in the case of unavailability of the external system. Also, we use database replication to stay resilient in the case of the outage of one of the replicas. To stay responsive, we return a response about an accepted order immediately and asynchronously process and send the user payment to the payments service. A final notification will be delivered later by one of the supported channels, for example, via email. Finally, that example depicts only one part of the system and in real deployments, the overall diagram may be broader and introduce much more specific techniques for achieving a reactive system.
To familiarize ourselves with API Gateway, Service Registry, and other patterns for constructing a distributed system, please click on the following link: http://microservices.io/patterns.
Along with the plain, small web store example that may seem really complex, let's consider another sophisticated area where a reactive system approach is appropriate. A more complex but exciting example is analytics. The term analytics means that the system that is able to handle a huge amount of data, process it in run-time, keep the user up to date with live statistics, and so on. Suppose we are designing a system for monitoring a telecommunication network based on cell site data. Due to the latest statistic report of the number of cell towers, in 2016 there were 308,334 active sites in the USA.
Unfortunately, we can just imagine the real load produced by that number of cell sites. However, we can agree that processing such a huge amount of data and providing real-time monitoring of the telecommunication network state, quality, and traffic is a challenge.
To design this system, we may follow one of the efficient architectural techniques called streaming. The following diagram depicts the abstract design of such a streaming system:
As may be noticed from this diagram, streaming architecture is about the construction of the flow of data processing and transformation. In general, such a system is characterized by low latency and high throughput. In turn, the ability to respond or simply deliver analyzed updates of the telecommunication network state is therefore crucial. Thus, to build such a highly-available system, we have to rely on fundamental principles, as mentioned in the Reactive Manifesto. For example, achieving resilience might be done by enabling backpressure support. Backpressure refers to a sophisticated mechanism of workload management between processing stages in such a way that ensures we do not overwhelm another. Efficient workload management may be achieved by using message-driven communication over a reliable message broker, which may persist messages internally and send messages on demand.
Moreover, by properly scaling each component of the system, we will be able to elastically expand or reduce system throughput.
In a real-world scenario, the stream of the data may be persisted databases processed in a batch, or partially processed in real-time by applying windowing or machine-learning techniques. Nonetheless, all fundamental principles offered by the Reactive Manifesto are valid here, regardless of the overall domain or business idea.
To summarize, there are a ton of different areas in which to apply the foundational principles of building a reactive system. The area of application of the reactive system is not limited to the previous examples and areas, since all of these principles may be applied to building almost any kind of distributed system oriented to giving users effective, interactive feedback.
Nonetheless, in the next section, we will cover the reasons for moving Spring Framework to reactivity.
In the previous section, we looked at a few interesting examples in which reactive system approaches shine.We have also expanded on the usage of fundamentals such as elasticity and resilience, and seen examples of microservice-based systems commonly used to attain a reactive system.
That gave us an understanding of the architectural perspective but nothing about the implementation. However, it is important to emphasize the complexity of the reactive system and the construction of such a system is a challenge. To create a reactive system with ease, we have to analyze frameworks capable of building such things first and then choose one of them. One of the most popular ways to choose a framework is by analyzing its available features, relevance, and community.
In the JVM world, the most commonly known frameworks for building a reactive system has been Akka and Vert.x ecosystems.
On the one hand, Akka is a popular framework with a huge list of features and a big community. However, at the very beginning, Akka was built as part of the Scala ecosystem and for a long time, it showed its power only within solutions written in Scala. Despite the fact that Scala is a JVM-based language, it is noticeably different from Java. A few years ago, Akka provided direct support for Java, but for some reason, it was not as popular in the Java world as it was in Scala.
On the other hand, there is the Vert.x framework which is also a powerful solution for building an efficient reactive system. Vert.x was designed as a non-blocking, event-driven alternative to Node.js that runs on the Java Virtual Machine. However, Vert.x started being competitive only a few years ago and during the last 15 years, the market for frameworks for flexible robust application development has been held by the Spring Framework.
The Spring Framework provides wide possibilities for building a web application using a developer-friendly programming model. However, for a long time, it had some limitations in building a robust reactive system.
