Mastering Akka
()
About this ebook
Related to Mastering Akka
Related ebooks
Spring MVC: Designing Real-World Web Applications Rating: 0 out of 5 stars0 ratingsJavaScript at Scale Rating: 0 out of 5 stars0 ratingsFast Data Processing Systems with SMACK Stack Rating: 0 out of 5 stars0 ratingsAkka Cookbook Rating: 2 out of 5 stars2/5Real-World Next.js: Build scalable, high-performance, and modern web applications using Next.js, the React framework for production Rating: 0 out of 5 stars0 ratingsScala for Data Science Rating: 0 out of 5 stars0 ratingsJava Testing with Spock Rating: 0 out of 5 stars0 ratingsSchematron: A language for validating XML Rating: 0 out of 5 stars0 ratingsJava 8 to 21: Explore and work with the cutting-edge features of Java 21 (English Edition) Rating: 0 out of 5 stars0 ratingsVert.x in Action: Asynchronous and Reactive Java Rating: 0 out of 5 stars0 ratingsHow To Build Microservices: Top 10 Hacks To Modeling, Integrating & Deploying Microservices Rating: 0 out of 5 stars0 ratingsSpring 2.5 Aspect Oriented Programming Rating: 0 out of 5 stars0 ratingsSoftware Design Patterns for Java Developers: Expert-led Approaches to Build Re-usable Software and Enterprise Applications Rating: 0 out of 5 stars0 ratingsScala Design Patterns Rating: 0 out of 5 stars0 ratingsDocker: Up and Running: Build and deploy containerized web apps with Docker and Kubernetes (English Edition) Rating: 0 out of 5 stars0 ratingsDependency Injection: Design patterns using Spring and Guice Rating: 0 out of 5 stars0 ratingsAspectJ in Action: Enterprise AOP with Spring Applications Rating: 0 out of 5 stars0 ratingsLearning Concurrent Programming in Scala - Second Edition Rating: 0 out of 5 stars0 ratingsJava Concurrency Complete Self-Assessment Guide Rating: 0 out of 5 stars0 ratingsQuick Start Kubernetes Rating: 0 out of 5 stars0 ratingsNative Docker Clustering with Swarm Rating: 0 out of 5 stars0 ratingsMastering Elasticsearch - Second Edition Rating: 0 out of 5 stars0 ratingsUltimate Laravel for Modern Web Development Rating: 0 out of 5 stars0 ratingsScala Functional Programming Patterns Rating: 0 out of 5 stars0 ratingsConcurrency in .NET: Modern patterns of concurrent and parallel programming Rating: 0 out of 5 stars0 ratings
Software Development & Engineering For You
ASP.NET Core in Action, Third Edition Rating: 0 out of 5 stars0 ratingsWordpress 2023 A Beginners Guide : Design Your Own Website With WordPress 2023 Rating: 0 out of 5 stars0 ratingsGrokking Algorithms: An illustrated guide for programmers and other curious people Rating: 4 out of 5 stars4/5Python For Dummies Rating: 4 out of 5 stars4/5How to Start a Business Analyst Career Rating: 5 out of 5 stars5/5Grokking Simplicity: Taming complex software with functional thinking Rating: 4 out of 5 stars4/5Case Studies in Design Patterns Rating: 5 out of 5 stars5/5Git Essentials Rating: 4 out of 5 stars4/5Hands-On Python for DevOps: Leverage Python's native libraries to streamline your workflow and save time with automation Rating: 0 out of 5 stars0 ratingsPYTHON: Practical Python Programming For Beginners & Experts With Hands-on Project Rating: 5 out of 5 stars5/5The Creative Programmer Rating: 0 out of 5 stars0 ratingsAce the Trading Systems Developer Interview (C++ Edition) : Insider's Guide to Top Tech Jobs in Finance Rating: 5 out of 5 stars5/5Visio 2016: Up To Speed Rating: 0 out of 5 stars0 ratingsLearn to Code. Get a Job. The Ultimate Guide to Learning and Getting Hired as a Developer. Rating: 5 out of 5 stars5/5ReactJS for Jobseekers: The Only Guide You Need to Learn React and Crack Interviews (English Edition) Rating: 0 out of 5 stars0 ratingsExtending Jenkins Rating: 0 out of 5 stars0 ratingsLevel Up! The Guide to Great Video Game Design Rating: 4 out of 5 stars4/5DevOps For Dummies Rating: 4 out of 5 stars4/5Learning Elixir Rating: 0 out of 5 stars0 ratingsGood Code, Bad Code: Think like a software engineer Rating: 5 out of 5 stars5/5The Practice of Enterprise Architecture: A Modern Approach to Business and IT Alignment Rating: 4 out of 5 stars4/5Adobe Illustrator CC For Dummies Rating: 5 out of 5 stars5/5What is Software Testing?: ISTQB Foundation Companion and Study Guide Rating: 5 out of 5 stars5/5The Kubernetes Book 2024 Edition Rating: 0 out of 5 stars0 ratingsTiny Python Projects: Learn coding and testing with puzzles and games Rating: 4 out of 5 stars4/5How to Build and Design a Website using WordPress : A Step-by-Step Guide with Screenshots Rating: 0 out of 5 stars0 ratingsBuilding RESTful Python Web Services Rating: 5 out of 5 stars5/5Agile Project Management: Scrum for Beginners Rating: 4 out of 5 stars4/5
Reviews for Mastering Akka
0 ratings0 reviews
Book preview
Mastering Akka - Christian Baxter
Table of Contents
Mastering Akka
Credits
About the Author
Acknowledgments
About the Reviewer
www.PacktPub.com
Why subscribe?
Preface
What this book covers
What you need for this book
Who this book is for
Conventions
Reader feedback
Customer support
Downloading the example code
Downloading the color images of this book
Errata
Piracy
Questions
1. Building a Better Reactive App
Understanding the initial example app
Working with the example application
Setting up Docker
Adding the boot2docker hosts entry
Understanding the bookstore Postgres schema
Running bash scripts on Windows
Starting up the example application
Interacting with the example application endpoints
Installing httpie on Mac OS X
Installing httpie on Windows
Interacting with the user endpoint
Interacting with the Book endpoint
Interacting with the Order endpoint
So what's wrong with this application?
Understanding the meanings of scalability
The scalability cube
X axis scaling
Microservices and Y axis scaling
Z axis scaling
Monolith versus microservices
Scale issues with our monolith
Issues with the size of deployments
Supporting different runtime characteristics of services
The pain of a shared domain model
Issues with our relational database usage
Sharing the same schema across all services
Fixing a single point of failure
Avoiding cross-domain transactions
Understanding the CAP theorem
Cassandra to the rescue
Assessing the application's domain model
Recognizing poorly written actors
Replacing our HTTP libraries
Summary
2. Simplifying Concurrent Programming with Actors
Understanding the actor model's origin
Differentiating concurrency and parallelism
Defining concurrency in computing
Defining parallelism
The dangers of concurrent programming
Using Akka actors for safe concurrency
Concurrent programming with actors
Achieving parallelism with Akka actors and routers
A word on dispatchers in Akka
Dispatchers and executors
Dispatcher types in Akka
Dispatcher
PinnedDispatcher
BalancingDispatcher
CallingThreadDispatcher
Configuring a dispatcher for your actors
Mailbox types in Akka
Unbounded mailboxes
Bounded mailboxes
Configuring mailboxes for your actors
Refactoring a bad actor to FSM
Modeling the new process flow
Coding the new order process flow
Defining state and data representations
Implementing the idle state handling
Implementing the ResolvingDependencies state handling
Implementing the LookingUpEntities state handling
Implementing the ChargingCard state handling
Implementing the WritingEntity state handling
Handling unhandled events
Summing up the refactor
Testing your Akka actors
Understanding the testing pyramid
Unit testing
Integration testing
Acceptance testing
Unit testing Akka actors
The CallingThreadDispatcher
Using TestActorRefs
Using ImplicitSender
Using TestProbes
Testing the SalesOrderProcessor actor
Testing homework
Summary
3. Curing Anemic Models with Domain-Driven Design
What is DDD?
Knowing where the domain layer fits
Understanding strategic DDD
Ubiquitous language
Bounded context
Continuous integration
Context map
Patterns of intercommunication in strategic DDD
Published language
Open host service
Shared kernel
Customer/supplier
Conformist
Anticorruption layer
Visualizing the spectrum of cooperation
Visualizing the relationships in strategic DDD
Building blocks of DDD
Entity
Value object
Aggregate
Domain event
Service
Repository
Factory
Identifying anemic vs rich models
Designing our DDD refactor
The bookstore context map
Modelling DDD with actors
Understanding the vocabulary of a component
Difficulties of DDD and actors
Remodeling the user management context
Remodeling the inventory management context
Remodeling the credit processing context
Remodeling the sales order processing context
Understanding the refactored bookstore code
The EntityActor abstract class
The EntityAggregate abstract class
The Book and InventoryClerk actors
Looking up a single Book
Looking up multiple books
Making a persistence action on a book
Fixing the transaction in the order creation process
Improvements needed for the refactor
Refactoring homework
Summary
4. Making History with Event Sourcing
Event sourcing primer
The pros of event sourcing
High performance
Avoidance of Object-relational mapping
Full audit trail
Enabler for system/context separation
No atomic concerns
A natural fit with DDD
The cons of event sourcing
Querying
Performance with long lived entities
Versioning concerns
It's just different
Bookstore-specific example of event sourcing
Akka Persistence for event sourcing
The PersistentActor trait
Persistent actor state handling
The persistenceId method
Taking snapshots for faster recovery
Serialization of events and snapshots
The AsyncWriteJournal
The SnapshotStore
Using Cassandra for our persistent store
Installing Cassandra
Configuring Akka Persistence to use Cassandra
Refactoring the inventory management module
The PersistentEntity abstract class
The Aggregate abstract class
The JsonSerializer class
The event sourced Book entity
The refactored InventoryClerk actor
Trying out the new Book entity
Viewing the events in Cassandra
Adding snapshotting to book
Dealing with an evolving schema
Using event adapters
Detaching the domain model from the data model
The refactored sales order processing module
Refactoring homework
Summary
5. Separating Concerns with CQRS
A brief history of CQRS
CQRS in the event sourced world
Designing our read model implementation
Selecting our read model data store
Projecting events into the read model
Using Persistence Query to build our views
Understanding your journal provider's query capabilities
Setting up a ReadJournal in your code
Obtaining all of the persistenceIds in the system
Getting events by persistenceId
Getting events by tag
Implementing the Book read model
Supporting tagging in ProtobufDatamodelAdapter
Elasticsearch support traits
The ViewBuilder trait
Acknowledging the flaws with the current code
Discussing the code
Building the BookViewBuilder
Building the BookView
Building a resumable projection
Defining the resumable projection framework
Applying ResumableProjection into our code
Refactoring sales order processing
Denormalization in the SalesOrder read model
Using Persistence Query for inventory allocation
Playing around with the new application
Refactoring homework
Closing comments
Summary
6. Going with the Flow with Akka Streams
Understanding the Reactive Streams API
Back-pressure in action
The Akka Streams API
The building blocks of Akka Streams
Learning the basics of Stream building
Understanding Stream Materialization
Operator fusion within streams
Using buffers to control rate
Internal buffers on async stages
Adding explicit buffers to data flows
Transforming rate within flows
Reducing data flow rates with conflate
Increasing data flow rates with expand
Building processing graphs with the graph builder DSL
Graph building basics
Building a real-world graph example
Working with partial graphs
Handling streaming I/O
Streams and TCP
Framing your streaming I/O handling
Refactoring the view building code
Refactoring homework
Summary
7. REST Easy with Akka HTTP
Creating RESTful HTTP interfaces
Comparing Akka HTTP to Spray
Akka Streams and back-pressure
Other differences
Creating RESTful interfaces with Akka HTTP
Using the low-level server-side API
Akka Streams in the low-level API
Handling requests with the low-level API
Controlling parallelism within your server
Low-level server example
Using the high-level server-side API
Completing, rejecting, or failing routes
The RequestContext class
Building out a routing tree
Using directives to build your routing tree
Composing directives together
Marshalling and unmarshalling JSON with spray-json
Handling rejections within your routes
Building a custom RejectionHandler
Testing your routes with route TestKit
Invoking RESTful APIs with Akka HTTP
Client-side Akka HTTP and streams
Consuming the response entity
Parsing the response entity as JSON
Understanding the outbound connection models
The connection-level API
The host-level API
The request-level API
Refactoring homework
Inbound HTTP changes
Outbound HTTP changes
Summary
8. Scaling Out with Akka Remoting/Clustering
Using Akka Remoting
Enabling Akka Remoting in your projects
Interacting with remote actors
Akka Remoting and serialization
Looking up remote actors
Deploying actors to remote systems
Using remote routers
Using Akka Clustering
Core architectural principles of clustering
Dealing with unreachable nodes
Understanding the membership life cycle
Enabling clustering in your projects
Refactoring the remote worker example for clustering
Using clustering in the bookstore application
Using Cluster Sharding in the bookstore application
Basic concepts of Akka Cluster Sharding
Refactoring the code for Cluster Sharding
Proper passivation of sharded entities
Cluster Sharding related homework
Using Cluster Singleton in the bookstore application
Using the Cluster Singleton pattern
Implementing Cluster Singleton for ViewBuilders
Cluster Singleton homework
Playing with the clustered bookstore application
Summary
9. Managing Deployments with ConductR
An overview of ConductR
Installing and setting up ConductR locally
Installing the ConductR CLI sandbox
Setting up the ConductR sandbox
Setting up sbt-conductr plugin
A quick note about the use of Docker in the sandbox
Using the ConductR CLI
Viewing the ConductR version information
Viewing the deployed bundle information
Viewing service information from your bundles
Viewing access-control lists for bundle services
Loading a bundle into ConductR
Starting a bundle within ConductR
Stopping a bundle within ConductR
Removing a bundle from ConductR
Viewing bundle-related events in ConductR
Viewing your bundle's logs
Preparing your services for ConductR
Bundling your components for deployment
Creating and deploying your bundle
Code requirements for deployment into ConductR
Signalling the application state
Setting up your ActorSystem and HTTP server
Locating other services within the cluster
Refactoring the bookstore for ConductR
Splitting apart the bookstore projects
Common changes to support ConductR
The new Server class
The ServiceConsumer classes
Turning the service modules into ConductR bundles
Setting up an application.conf for each module
Adding bundle keys to our sbt build files
Creating a main class to startup each bundle
Refactoring the sales-order-processing module
Refactoring the SalesOrderCreateValidator
Refactoring SalesOrderViewBuilder
Refactoring the inventory-allocation process
Refactoring the inventory-management module
Building and deploying the bookstore bundles
Testing the bookstore modules in ConductR
Summary
10. Troubleshooting and Best Practices
Refactoring retrospective
Coding better actors
Using Domain-driven design
Akka Persistence and event sourcing
Akka Persistence Query and CQRS
Akka Streams
Akka HTTP
Akka Remoting and Akka Clustering
Separating the modules via ConductR
Troubleshooting and best practices for actors
Avoid closing over mutable state with Futures
Avoiding closing over the sender
Minimize your use of ActorSelection
Use tell instead of ask
Avoid creating a lot of top-level actors
Troubleshooting and best practices for Akka HTTP
Trouble with the tilde
Building an inbound HTTP request log
Building an outbound HTTP request log
Troubleshooting and best practices for Akka Clustering/Akka Remoting
Prefer using IP addresses over host names in config
Configuring more than one seed node
Disassociated exceptions in the logs can be normal
Further reading
Lagom
Akka Streams cookbook
How to and common patterns
Akka Persistence schema evolution
Other Akka books to consider reading
Domain-driven design by Eric Evans
Martin Fowler on event sourcing
Summary
Mastering Akka
Mastering Akka
Copyright © 2016 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 author, nor Packt Publishing, and its dealers and distributors will be held liable for any damages caused or alleged to be 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.
First published: October 2016
Production reference: 1141016
Published by Packt Publishing Ltd.
Livery Place
35 Livery Street
Birmingham
B3 2PB, UK.
ISBN 978-1-78646-502-3
www.packtpub.com
Credits
About the Author
Christian Baxter, from an early age, has always had an interest in understanding how things worked. Growing up, he loved challenges and liked to tinker with and fix things. This inquisitive nature was the driving force that eventually led him into computer programming. While his primary focus in college was life sciences, he always set aside time to study computers and to explore all aspects of computer programming. When he graduated from college during the height of the Internet boom, he taught himself the necessary skills to get a job as a programmer. He’s been happily programming ever since, working across diverse industries such as insurance, travel, recruiting, and advertising. He loves building out high-performance distributed systems using Scala on the Akka platform.
Christian was a long time Java programmer before making the switch over to Scala in 2010. He was looking for new technologies to build out high throughput and asynchronous systems and loved what he saw from Scala and Akka. Since then, he's been a major advocate for Akka, getting multiple ad tech companies he’s worked for to adopt it as a means of building out reactive applications. He's also been an occasional contributor to the Akka codebase, identifying and helping to fix issues. When he’s not hacking away on Scala and Akka, you can usually find him answering questions on Stackoverflow as cmbaxter.
Acknowledgments
A lot went into the writing of this book, and not just from me. As such, I’d like to thank a few people, starting with the two special women in my life.
To my beautiful wife, Laurie. Thank you for being so patient throughout the writing of this book, and with me, in general. All this time, you’ve somehow been able to put up with all my quirks, which is a feat in and of itself. You’ve always believed in me, even if, at times, I didn’t believe in myself. Thank you for always challenging me and never letting me be complacent. Without you, this book would have never been possible.
To my amazing mother, you taught me how to be a good person by instilling in me the values one needs to be successful in life. Your strength of character and resilience to life’s challenges have served as inspirations to me. You’ve always been there for me, no matter how hard the times got. For this, I am eternally grateful.
Lastly, I’d like to thank my very first mentor, Dan Gallagher. I learned so much from you during our time together. Who knows how my career would have ended up if you weren’t there in the beginning to screw my head on straight. I appreciate the enormous amount of patience that must have gone into dealing with me way back then. Thank you so much for starting my career down the right path to where I am today.
About the Reviewer
Dennis Vriend is a professional with more than 10 years of experience in programming for the Java Virtual Machine. Over the last 4 years, Dennis has been developing and designing fault tolerant, scalable, distributed, and highly performant systems using Scala, Akka, and Spark, and maintaining them across multiple servers. Dennis is active in the open source community and maintains two very successful Akka plugins—the akka-persistence-jdbc plugin and the akka-persistence-inmemory plugin—both useful to design and test state of the art business components leveraging domain-driven design and event sourcing in a distributed environment. Dennis is currently working as a software development engineer for Trivento in the Netherlands.
www.PacktPub.com
For support files and downloads related to your book, please visit www.PacktPub.com.
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.PacktPub.com and as a print book customer, you are entitled to a discount on the eBook copy. Get in touch with us at service@packtpub.com for more details.
At www.PacktPub.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.
https://www.packtpub.com/mapt
Get the most in-demand software skills with Mapt. Mapt gives you full access to all Packt books and video courses, as well as industry-leading tools to help you plan your personal development and advance your career.
Why subscribe?
Fully searchable across every book published by Packt
Copy and paste, print, and bookmark content
On demand and accessible via a web browser
Preface
The Akka library is well known in the Scala world for providing a means to build reactive applications. Akka’s core building block is the Actor, which is a simple concurrency unit that allows you to build asynchronous, event driven, fault tolerant, and potentially distributed components on top of. Actors are an excellent starting point to build your reactive applications and services on top of, but there’s a lot more within the entire Akka platform that you should be considering as well.
This book will provide the reader with a purpose-built tour through some of the additional modules within the Akka platform. The tour will be conducted by progressively refactoring an initial Akka application from an inflexible monolith all the way to a set of loosely coupled microservices. Along the way, you will learn how to apply new features, such as event sourcing via Akka Persistence, to the application in an effort to help it scale better. When the journey is complete, you will have a much better understanding of these additional offerings within the Akka platform and how they can help you build your applications and services.
Throughout the refactoring process, new concepts and libraries within Akka will be introduced to the reader on a chapter by chapter basis. Within those chapters, I will detail what each new feature is, and how that feature fits into breaking down a monolith into a set of loosely coupled services. Each chapter will also involve coding homework for the reader, giving them an active role in the progressive refactoring process. This hands-on experience will give the reader an immersive understanding of how to use these newer Akka features in the real-world code, which is the main goal of this book.
What this book covers
Chapter 1, Building a Better Reactive App, introduces you to the initial sample application and how it will be improved over the course of this book.
Chapter 2, Simplifying Concurrent Programming with Actors, is a refresher on Actors with some refactoring work using Akka’s FSM.
Chapter 3, Curing Anemic Models with Domain-Driven Design, introduces you to domain-driven design (DDD) and how it helps in modeling and building software.
Chapter 4, Making History with Event Sourcing, presents Akka Persistence as a means to build event-sourced entities.
Chapter 5, Separating Concerns with CQRS, teaches you how to separate read and write models using the CQRS pattern.
Chapter 6, Going with the Flow with Akka Streams, explains how Akka Streams can be used to build back-pressure aware, stream-based processing components.
Chapter 7, REST Easy with Akka HTTP, shows you how to leverage Akka HTTP to build and consume RESTful interfaces.
Chapter 8, Scaling Out with Akka Remoting/Clustering, demonstrates how to use remoting and clustering to gain horizontal scalability and high availability.
Chapter 9, Managing Deployments with ConductR, illustrates building, deploying, and locating your microservices with ConductR.
Chapter 10, Troubleshooting and Best Practices, presents a few final tips and best practices for using Akka.
What you need for this book
You will need a computer (Windows or Mac OS X) with Java 8 installed on it. You will need to have Simple Build Tool (sbt) installed on that computer as well. This book also leverages Docker, with the installation of Docker being covered in more detail in Chapter 1, Building a Better Reactive App.
Who this book is for
If you want to use the Lightbend platform to create highly-performant reactive applications, then this book is for you. If you are a Scala developer looking for techniques to use all features of the new Akka release and want to incorporate these solutions in your current or new projects, then this book is for you. Expert Java developers who want to build scalable, concurrent, and reactive application will find this book helpful.
Conventions
In this book, you will find a number of text styles that distinguish between different kinds of information. Here are some examples of these styles and an explanation of their meaning.
Code words in text, database table names, folder names, filenames, file extensions, pathnames, dummy URLs, user input, and Twitter handles are shown as follows: If you want to stop a Docker container, use the docker stop command, supplying the name of the container you want to stop.
A block of code is set as follows:
{
firstName
: Chris
,
lastName
: Baxter
,
email
: chris@masteringakka.com
}
Any command-line input or output is written as follows:
docker-build.sh
New terms and important words are shown in bold. Words that you see on the screen, for example, in menus or dialog boxes, appear in the text like this: Click the Docker whale icon in your system tray and select Preferences in the context menu that pops up.
Note
Warnings or important notes appear in a box like this.
Tip
Tips and tricks appear like this.
Reader feedback
Feedback from our readers is always welcome. Let us know what you think about this book-what you liked or disliked. Reader feedback is important for us as it helps us develop titles that you will really get the most out of. To send us general feedback, simply e-mail feedback@packtpub.com, and mention the book's title in the subject of your message. If there is a topic that you have expertise in and you are interested in either writing or contributing to a book, see our author guide at www.packtpub.com/authors.
Customer support
Now that you are the proud owner of a Packt book, we have a number of things to help you to get the most from your purchase.
Downloading the example code
You can download the example code files for this book from your account at http://www.packtpub.com. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.
You can download the code files by following these steps:
Log in or register to our website using your e-mail address and password.
Hover the mouse pointer on the SUPPORT tab at the top.
Click on Code Downloads & Errata.
Enter the name of the book in the Search box.
Select the book for which you're looking to download the code files.
Choose from the drop-down menu where you purchased this book from.
Click on Code Download.
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/Mastering-Akka. We also have other code bundles from our rich catalog of books and videos available at https://github.com/PacktPublishing/. Check them out!
Downloading the color images of this book
We also provide you with a PDF file that has color images of the screenshots/diagrams used in this book. The color images will help you better understand the changes in the output. You can download this file from https://www.packtpub.com/sites/default/files/downloads/MasteringAkka_ColorImages.pdf.
Errata
Although we have taken every care to ensure the accuracy of our content, mistakes do happen. If you find a mistake in one of our books-maybe a mistake in the text or the code-we would be grateful if you could report this to us. By doing so, you can save other readers from frustration and help us improve subsequent versions of this book. If you find any errata, please report them by visiting http://www.packtpub.com/submit-errata, selecting your book, clicking on the Errata Submission Form link, and entering the details of your errata. Once your errata are verified, your submission will be accepted and the errata will be uploaded to our website or added to any list of existing errata under the Errata section of that title.
To view the previously submitted errata, go to https://www.packtpub.com/books/content/support and enter the name of the book in the search field. The required information will appear under the Errata section.
Piracy
Piracy of copyrighted material on the Internet is an ongoing problem across all media. At Packt, we take the protection of our copyright and licenses very seriously. If you come across any illegal copies of our works in any form on the Internet, please provide us with the location address or website name immediately so that we can pursue a remedy.
Please contact us at copyright@packtpub.com with a link to the suspected pirated material.
We appreciate your help in protecting our authors and our ability to bring you valuable content.
Questions
If you have a problem with any aspect of this book, you can contact us at questions@packtpub.com, and we will do our best to address the problem.
Chapter 1. Building a Better Reactive App
This book is meant to be geared towards the more experienced Scala and Akka developers looking to build reactive applications on top of the Akka platform.
This book is written for an engineer who has already leveraged Akka in the 2.3.x series and below to build reactive applications. You have a firm understanding of the actor model and how the Akka framework leverages actors to build highly scalable, concurrent, asynchronous, event-driven, and fault-tolerant applications. You've seen the new changes rolled out in Akka 2.4.2 and are curious about how some of these new features such as Akka Streams and Akka HTTP can be leveraged within your reactive applications.
This book will serve as a guide for an engineer who wants to take a functional but flawed reactive application and, through a series of refactors, make improvements to it. It will help you understand what some of the common pitfalls are when building Akka applications. Throughout the various chapters in the book, you will learn how to use Akka and some of the newer features to address the following shortcomings:
Building a more domain-centric model using domain-driven design
Using event sourcing and Akka Persistence for high throughput persistence
Understanding reactive streams and how Akka makes use of them in Akka Streams and Akka HTTP
Decomposing a monolith into a set of fully decoupled and independent services
Understanding the initial example app
Imagine you woke up one morning and decided that you were going to take down the mighty Amazon.com. They've spread themselves too thin in trying to sell anything and everything the world has to offer. You see an opportunity back in their original space of online book selling and have started a company to challenge them in that area.
Over the past few months, you and your team of engineers have built out a simple Minimum Viable Product (MVP) reactive bookstore application build on top of the Akka 2.3.x series. As this is an MVP, it's pretty basic, but it has served its purpose of getting something to the market quickly to establish a user base and get good feedback to iterate on. The current application covers the following subdomains within the overall domain of a bookstore application:
User management
Book (inventory) management
Credit card processing
Sales order processing
The code that represents the initial application can be found in the initial-example-app folder within the code distribution for this book. The application is an sbt multi-project build with the following individual projects:
common: Common utilities and a shared domain model
user-services: User management related services
book-services: Book management related services
credit-services: Credit card processing services
sales-services: Sales order processing services
server: A single project that aggregates the individual service projects and contains a main method to launch the server
If you were to look at the different projects from a dependency view, they would look like this:
The individual services subprojects were set up to avoid any direct code dependencies to each other. If services in different modules need to communicate with each other, then they use the shared domain model (entities and messages) from the common project as the protocol. The initial intention was to allow each module to eventually be built and deployed independent of each other, even though currently it's built together and deployed as a monolith.
Each service module is made up of HTTP endpoint classes, services, and, in some cases, Data Access Objects (DAOs). The endpoint classes are built on top of the Unfiltered library and allow inbound, REST-oriented HTTP requests to be serviced asynchronously, using Netty under the hood. The service business logic is modeled using the actor model and implemented with Akka actors that are called from the endpoints. Service actors that need to talk to the relational Postgres db do so via DAOs that reside within the same .scala files as the services that use them. The DAOs use Lightbend's Slick library with the Plain SQL approach to talk to Postgres.
The way the application is currently structured, an inbound request that talks to the db would be handled as follows:
The HTTP request comes in and is handled by Netty's NIO channel handling code on top of its own thread pool.
Netty passes the code off to the Unfiltered framework for handling, still using Netty's thread pool.
Unfiltered looks up a service actor via actor selection and uses the ask pattern to send it a message, returning a Future that will hold the result of the service call.
The service actor that receives the message is running on the actor system's main Fork/Join thread pool.
The actor talks to the Postgres db via the Slick DAO. The SQL itself runs within Slick's AsycExecutor system, on top of another separate thread pool.
The actor sends a response back to the sender (the Future from the endpoint) using the pipe pattern.
The Future in the endpoint, which runs on the actor system's dispatcher, is completed, which results in a response being communicated through Unfiltered and Netty and then back into the wire.
As you can see from the preceding steps, there are a few different thread pools involved in the servicing of the request, but it's done completely asynchronously. The only real blocking done in this flow is the JDBC calls done via Slick (sadly, JDBC has yet to incorporate async calls into the API). Thankfully though, those blocking calls are isolated behind Slick's own thread pool.
If you've played with Akka long enough, you know it's taboo to block in the actor system's main Fork/Join pool. Akka is built around the concept of using very few threads to do a lot of work. If you start blocking the dispatcher threads themselves, then your actors can suffer from thread starvation and fall behind in the processing of their mailboxes. This will lead to higher latency in call times, upsetting end users, and nobody wins when that happens. We avoided such problems with this app, so we can pat ourselves on the back for that.
You should take a little time in going through the example code to understand how everything is wired together. Understanding this example app is critical as this serves as the foundation for our progressive refactoring. Spending a little time upfront getting familiar with things will help as different sections are discussed in the upcoming chapters.
The app itself is not perfect. It has intentional shortcomings to give us something to refactor. It was certainly beyond the scope of this book to have me build out a fully functioning, coherent, and production-ready storefront application. The code is just a medium in which to communicate some of the flawed ways in which an Akka reactive application could be put together. It was purposely built as a lead-in to discover some of the newer features in the Akka toolkit as a way to solve some common shortcomings. View it as such, with an open mind, and you will have already taken the first step in our refactoring journey.
Tip
Detailed steps to download the code bundle are mentioned in the Preface of this book. Please have a look. The code bundle for the book is also hosted on GitHub at https://github.com/PacktPublishing/Mastering-Akka. We also have other code bundles from our rich catalog of books and videos available at https://github.com/PacktPublishing/. Check them out!
Working with the example application
Now that you have an understanding of the initial code, we can build it and then get it up and running. It's assumed that you already have Scala and sbt installed. Assuming you have those two initial requirements installed, we can get started on getting the example app functional.
Setting up Docker
Throughout this book, we will be using Docker to handle setting up any additional applications (such as Postgres) and for running the bookstore application itself (within a container). For those unfamiliar with Docker, it is a containerization platform that will let you package and run your applications, ensuring that they run and behave the same no matter what the environment is that they are running on. This means that when you are testing things locally, on your Mac or Windows computer, the components will run and behave the same as when they eventually get deployed to whatever production environment you run (say some Linux distribution on Amazon's Elastic Compute Cloud). You package up all of the application components and their dependencies into a neat little container that can then be run anywhere Docker itself is running.
The decision to use Docker here should make set up simpler (as Docker will handle the majority of it). Also, you won't clutter up your computer with these applications as they will only run as Docker containers instead of being directly installed. When it comes to your Docker installation, you have two possible options:
Install Docker Toolbox, which will install the docker engine, docker-machine and docker-compose, which are necessary for running the bookstore application.
Install one of the native Docker apps (Docker for Windows or Docker for Mac), both of which will also work for running the bookstore application.
The biggest difference between these two options will be what local host address Docker uses when binding applications to ports. When using Docker Toolbox, docker-machine is used, which will by default bind applications to the local address of 192.168.99.100. When using one of the native Docker apps, the loopback address of 127.0.0.1 (localhost) will be used instead.
If you already have Docker installed, then you can use that pre-existing installation. If you don't have Docker installed, and you are on a Mac, then please read through the link from below to help you decide between Docker for Mac and Docker Toolbox: https://docs.docker.com/docker-for-mac/docker-toolbox/.
For Windows users, you should check out the following link, reading through the section titled What to know before you install, to see if your computer can support the requirements of Docker for Windows. If so, then go ahead and install that flavor. If not, then callback to using Docker Toolbox: https://docs.docker.com/docker-for-windows/.
Adding the boot2docker hosts entry
Because we gave you a choice in which Docker flavor to run, and because each different flavor will bind to different local addresses, we need a consistent way to refer to the host address that is being used by Docker. The easiest way to do this is to add an entry to your hosts file, setting up an alias for a host called boot2docker. We can then use that alias going forward to when referring to the local Docker bind address, both in the scripts provided in the code content for this book and in any examples in the book content.
The entry we need to add to this file will be the same regardless of if you are on Windows or a Mac. This is the format of the entry that you will need to add to that file:
You will need to replace the
127.0.0.1 boot2docker
And if you installed Docker Toolkit and are thus using docker-machine, then the line would look like this:
192.168.99.100 boot2docker
The location of that file will be different depending on if you are running Windows or are on a Mac. If you are on Windows, then the file an be found at the following location: C:\Windows\System32\Drivers\etc\hosts.
If you are running in a Mac, then the file can be found here: /etc/hosts.
Understanding the bookstore Postgres schema
The initial example app uses Postgres for its persistence needs. It's a good choice for a relational database as it's lightweight and fast (for a relational database at least). It also has fantastic support for JSON fields, so much so that people have been using it for a document store too.
We will use Docker to handle setting up Postgres locally for us, so no need to go out and install it yourself. There are also setup scripts provided as part of the code for this chapter that will handle setting up the schema and database tables that the bookstore application needs. I've included an ERD diagram of that schema below for reference as I feel it's important in understanding the table relationships between the entities for the initial version of the bookstore app.
If you are interested in the script that was used to create the tables from this diagram, then you can find it in the sql directory under the intial-example-app root folder from the code distribution, in a file called example-app.sql.
Running bash scripts on Windows
If you are using a Mac, you can skip reading this section. It only pertains to running the .sh scripts used to start up the app on Windows.
As part of the code content for each chapter, there are some bash scripts that handle building and running the bookstore application. As bash is not native to the Windows operating system, you will have to decide how you want to build and start the bookstore application, choosing from one of the the following possibilities:
If you are using Git for Windows, then you have Git BASH installed locally and you should be able to use that tool to run these fairly simple scripts.
If you are on Windows 10, then you can use the new Windows Subsystem for Linux and install a bash shell. Check out this link for instructions: http://www.howtogeek.com/249966/how-to-install-and-use-the-linux-bash-shell-on-windows-10.
You can install cygwin.
As a last resort, if none of the above options work then you can look at the .sh files referenced and just run the commands (which are a mix of sbt and Docker commands) individually yourself. There's not a lot of them per file, so this is not a bad last resort.
Starting up the example application
Now that the database is up and running, we can get the Scala code built and then packaged into a Docker container (along with Java8 and Postgres, via docker-compose) so we can run and play with it locally. First, make sure that you have Docker up and running locally. If you are running one of the native Docker apps, then look for the whale in your system tray. If it's not there, then go and start it up and make sure it shows there before continuing. If you are running Docker Toolbox, then fire up the Docker Quickstart Terminal, which will start up a local docker-machine session within a terminal window with a whale as ASCII art at the top of it. Stay in that window for the remainder of the rest of the following commands as that's the only window where you can run Docker-related commands.
From a terminal window within the root of the initial-example-app folder run the following command to get the app all packaged up into a Docker container:
docker-build.sh
This script will instruct sbt to build and package the application. The script will then build a docker image, tag it and store it in the local docker repository. This script could take a while to run initially, as it will need to download a bunch of Docker-related dependencies, so be patient. Once that completes, you can then run the following command in that same terminal window:
launch.sh
This command will also take a while initially as it pulls down all of the components of our container, including Postgres. Once this command completes, you will have the bookstore initial example application container up and running locally, which you can verify by running the following command:
docker ps
That will print out a process list for the containers running under Docker. You should see two rows in that list, one for the bookstore and one for Postgres. If you want to log into Postgres via the psql client, to maybe look at the db before and after interacting with the app, then you can do so by executing the following command:
docker run -it --rm --network initialexampleapp_default postgres psql -h postgres -U docker
When prompted for the password, enter docker. Once in the database, you can switch to the schema used by the example app by running the following command from within psql:
\c akkaexampleapp
From there, you can interact with any of the tables described in the ERD diagram shown earlier.
Tip
If you want to stop a Docker container, use the docker stop command, supplying the name of the container you want to stop. Then, use the docker rm command to remove the stopped container or docker restart if you want to start it up again.
Interacting with the example application endpoints
Once the app is up and running, we can start interacting with its REST-like API in an effort to see what it can do. The interactions will be broken down by subdomain within the app (represented by the -services projects), detailing the capabilities of the endpoint(s) within that subdomain. We will use the httpie utility to execute our HTTP requests. Here are the installation instructions for each platform.
Installing httpie on Mac OS X
You can install httpie on your Mac via homebrew. The command to install is as follows:
$ brew install httpie
Installing httpie on Windows
The installation on Windows is going to be a bit more complicated as you will need Python, curl, and pip. The full instructions are too long to include directly in this book and can be found at: http://jaspreetchahal.org/setting-up-httpie-and-curl-on-windows-environment/.
Interacting with the user endpoint
The first thing we can do when playing with the app's endpoints is to create a new BookstoreUser entity that will be stored in the StoreUser Postgres table. If you cd into the json folder under the initial-example-app root, there will be a user.json file that contains the following json object:
{
firstName
: Chris
,
lastName
: Baxter
,
email
: chris@masteringakka.com
}
In order to create a user with these fields, you can execute the following httpie command when in the json folder:
http -v POST boot2docker:8080/api/user < user.json
Here, you can see that we are making use of the hosts file alias we created in section Adding the boot2docker hosts entry. This let us make HTTP calls to the bookstore app container that is running in Docker regardless of what local address it is bound to.
The -v option supplied in that command will allow you to see the entire request that was sent (headers, body, path, and params), which can be helpful if it becomes necessary