- Foreword
- Preface
- Target Audience
- Goals
- Conventions Used in This Book
- Using Code Examples
- O’Reilly Online Learning
- How to Contact Us
- Acknowledgments
- 1. Why Distributed?
- The Single-Threaded Nature of JavaScript
- Quick Node.js Overview
- The Node.js Event Loop
- Event Loop Phases
- Code Example
- Event Loop Tips
- Sample Applications
- Service Relationship
- Producer Service
- Consumer Service
- 2. Protocols
- Request and Response with HTTP
- HTTP Payloads
- HTTP Semantics
- HTTP Compression
- HTTPS / TLS
- JSON over HTTP
- The Dangers of Serializing POJOs
- API Facade with GraphQL
- GraphQL Schema
- Queries and Responses
- GraphQL Producer
- GraphQL Consumer
- RPC with gRPC
- Protocol Buffers
- gRPC Producer
- gRPC Consumer
- 3. Scaling
- The Cluster Module
- A Simple Example
- Request Dispatching
- Cluster Shortcomings
- Reverse Proxies with HAProxy
- Introduction to HAProxy
- Load Balancing and Health Checks
- Compression
- TLS Termination
- Rate Limiting and Back Pressure
- SLA and Load Testing
- Introduction to Autocannon
- Running a Baseline Load Test
- Reverse Proxy Concerns
- Protocol Concerns
- Coming Up with SLOs
- 4. Observability
- Environments
- Logging with ELK
- Running ELK via Docker
- Transmitting Logs from Node.js
- Creating a Kibana Dashboard
- Running Ad-Hoc Queries
- Metrics with Graphite, StatsD, and Grafana
- Running via Docker
- Transmitting Metrics from Node.js
- Creating a Grafana Dashboard
- Node.js Health Indicators
- Distributed Request Tracing with Zipkin
- How Does Zipkin Work?
- Running Zipkin via Docker
- Transmitting Traces from Node.js
- Visualizing a Request Tree
- Visualizing Microservice Dependencies
- Health Checks
- Building a Health Check
- Testing the Health Check
- Alerting with Cabot
- Create a Twilio Trial Account
- Running Cabot via Docker
- Creating a Health Check
- 5. Containers
- Introduction to Docker
- Containerizing a Node.js Service
- Dependency Stage
- Release Stage
- From Image to Container
- Rebuilding and Versioning an Image
- Basic Orchestration with Docker Compose
- Composing Node.js Services
- Internal Docker Registry
- Running the Docker Registry
- Pushing and Pulling to the Registry
- Running a Docker Registry UI
- 6. Deployments
- Build Pipeline with Travis CI
- Creating a Basic Project
- Configuring Travis CI
- Testing a Pull Request
- Automated Testing
- Unit Tests
- Integration Tests
- Code Coverage Enforcement
- Deploying to Heroku
- Create a Heroku App
- Configure Travis CI
- Deploy Your Application
- Modules, Packages, and SemVer
- Node.js Modules
- SemVer (Semantic Versioning)
- npm Packages and the npm CLI
- Internal npm Registry
- Running Verdaccio
- Configuring npm to Use Verdaccio
- Publishing to Verdaccio
- 7. Container Orchestration
- Introduction to Kubernetes
- Kubernetes Overview
- Kubernetes Concepts
- Starting Kubernetes
- Getting Started
- Deploying an Application
- Kubectl Subcommands
- Kubectl Configuration Files
- Service Discovery
- Modifying Deployments
- Scaling Application Instances
- Deploying New Application Versions
- Rolling Back Application Deployments
- 8. Resilience
- The Death of a Node.js Process
- Process Exit
- Exceptions, Rejections, and Emitted Errors
- Signals
- Building Stateless Services
- Avoiding Memory Leaks
- Bounded In-Process Caches
- External Caching with Memcached
- Introducing Memcached
- Running Memcached
- Caching Data with Memcached
- Data Structure Mutations
- Database Connection Resilience
- Running PostgreSQL
- Automatic Reconnection
- Connection Pooling
- Schema Migrations with Knex
- Configuring Knex
- Creating a Schema Migration
- Applying a Migration
- Rolling Back a Migration
- Live Migrations
- Idempotency and Messaging Resilience
- HTTP Retry Logic
- Circuit Breaker Pattern
- Exponential Backoff
- Resilience Testing
- Random Crashes
- Event Loop Pauses
- Random Failed Async Operations
- 9. Distributed Primitives
- The ID Generation Problem
- Introduction to Redis
- Redis Operations
- Strings
- Lists
- Sets
- Hash
- Sorted Sets
- Generic Commands
- Other Types
- Seeking Atomicity
- Transactions
- Lua Scripting
- Writing a Lua Script File
- Loading the Lua Script
- Tying It All Together
- 10. Security
- Wrangling Repositories
- Recognizing Attack Surface
- Parameter Checking and Deserialization
- Malicious npm Packages
- Application Configuration
- Environment Variables
- Configuration Files
- Secrets Management
- Upgrading Dependencies
- Automatic Upgrades with GitHub Dependabot
- Manual Upgrades with npm CLI
- Unpatched Vulnerabilities
- Upgrading Node.js
- Node.js LTS Schedule
- Upgrade Approach
- A. Installing HAProxy
- Linux: Build from Source
- Linux: Install Precompiled Binary
- macOS: Install via Homebrew
- B. Installing Docker
- macOS: Install Docker Desktop for Mac
- Linux: Convenient Install Script
- C. Installing Minikube & Kubectl
- Linux: Debian Package and Precompiled Binary
- macOS: Install via Homebrew
- Index