Cloud Native Go. 2nd Edition - Helion
ISBN: 9781098156381
stron: 542, Format: ebook
Data wydania: 2024-10-14
Księgarnia: Helion
Cena książki: 203,15 zł (poprzednio: 247,74 zł)
Oszczędzasz: 18% (-44,59 zł)
Learn how to use Go's strengths to develop services that are scalable and resilient even in an unpredictable environment. With this book's expanded second edition, Go developers will explore the composition and construction of cloud native applications, from lower-level Go features and mid-level patterns to high-level architectural considerations.
Each chapter in this new edition builds on the lessons of the previous chapter, taking intermediate to advanced developers through Go to construct a simple but fully featured distributed key-value store. You'll learn about Go generics, dependability and reliability, memory leaks, and message-oriented middleware. New chapters on security and distributed state delve into critical aspects of developing secure distributed cloud native applications.
With this book you will:
- Learn the features that make Go an ideal language for building cloud native software
- Understand how Go solves the challenges of designing scalable distributed services
- Design and implement a reliable cloud native service by leveraging Go's lower-level features such as channels and goroutines
- Apply patterns, abstractions, and tooling to effectively build and manage complex distributed systems
- Overcome stumbling blocks when using Go to build and manage a cloud native service
Osoby które kupowały "Cloud Native Go. 2nd Edition", wybierały także:
- Windows Media Center. Domowe centrum rozrywki 66,67 zł, (8,00 zł -88%)
- Ruby on Rails. Ćwiczenia 18,75 zł, (3,00 zł -84%)
- Przywództwo w świecie VUCA. Jak być skutecznym liderem w niepewnym środowisku 58,64 zł, (12,90 zł -78%)
- Scrum. O zwinnym zarządzaniu projektami. Wydanie II rozszerzone 58,64 zł, (12,90 zł -78%)
- Od hierarchii do turkusu, czyli jak zarządzać w XXI wieku 58,64 zł, (12,90 zł -78%)
Spis treści
Cloud Native Go. Building Reliable Services in Unreliable Environments. 2nd Edition eBook -- spis treści
- Preface
- Whats New in the Second Edition
- Who Should Read This Book
- Why I Wrote This Book
- Conventions Used in This Book
- Using Code Examples
- OReilly Online Learning
- How to Contact Us
- Acknowledgments
- Acknowledgments for the Second Edition
- I. Going Cloud Native
- 1. What Is a Cloud Native Application?
- The Story So Far
- What Is Cloud Native?
- Scalability
- Loose Coupling
- Resilience
- Manageability
- Observability
- Why Is Cloud Native a Thing?
- Summary
- 2. Why Go Rules the Cloud Native World
- The Motivation Behind Go
- Features for a Cloud Native World
- Composition and Structural Typing
- Comprehensibility
- CSP-Style Concurrency
- Fast Builds
- Linguistic Stability
- Memory Safety
- Performance
- Static Linking
- Static Typing
- Summary
- II. Cloud Native Go Constructs
- 3. Go Language Foundations
- Basic Data Types
- Booleans
- Simple Numbers
- Complex Numbers
- Strings
- Variables
- Short Variable Declarations
- Zero Values
- The Blank Identifier
- Constants
- Container Types: Arrays, Slices, and Maps
- Arrays
- Slices
- Working with slices
- The slice operator
- Strings as slices
- Maps
- Map membership testing
- Pointers
- Control Structures
- Fun with for
- The general for statement
- Looping over arrays and slices
- Looping over maps
- The if Statement
- The switch Statement
- Fun with for
- Error Handling
- Creating an Error
- Putting the Fun in Functions: Variadics and Closures
- Functions
- Multiple return values
- Recursion
- Defer
- Pointers as parameters
- Variadic Functions
- Passing slices as variadic values
- Anonymous Functions and Closures
- Functions
- Structs, Methods, and Interfaces
- Structs
- Methods
- Interfaces
- Type assertions
- The any type
- Composition with Type Embedding
- Interface embedding
- Struct embedding
- Promotion
- Directly accessing embedded fields
- Generics
- The Before Times
- Generic Functions
- Generic Types
- Type Constraints
- Type Inference
- The Good Stuff: Concurrency
- Goroutines
- Channels
- Channel blocking
- Channel buffering
- Closing channels
- Looping over channels
- Select
- Implementing channel timeouts
- Summary
- Basic Data Types
- 4. Cloud Native Patterns
- The Context Package
- What Context Can Do for You
- Creating Context
- Defining Context Deadlines and Timeouts
- Defining Request-Scoped Values
- Using a Context
- Layout of This Chapter
- Stability Patterns
- Circuit Breaker
- Applicability
- Participants
- Implementation
- Sample code
- Debounce
- Applicability
- Participants
- Implementation
- Sample code
- Retry
- Applicability
- Participants
- Implementation
- Sample code
- Throttle
- Applicability
- Participants
- Implementation
- Sample code
- Timeout
- Applicability
- Participants
- Implementation
- Sample code
- Circuit Breaker
- Concurrency Patterns
- Fan-In
- Applicability
- Participants
- Implementation
- Sample code
- Fan-Out
- Applicability
- Participants
- Implementation
- Sample code
- Future
- Applicability
- Participants
- Implementation
- Sample code
- Sharding
- Applicability
- Participants
- Implementation
- Sample code
- Worker Pool
- Applicability
- Participants
- Implementation
- Sample code
- Chord
- Applicability
- Participants
- Implementation
- Sample code
- Fan-In
- Summary
- The Context Package
- 5. Building a Cloud Native Service
- Lets Build a Service!
- Whats a Key-Value Store?
- Requirements
- What Is Idempotence and Why Does It Matter?
- The Eventual Goal
- Generation 0: The Core Functionality
- Your Super Simple API
- Generation 1: The Monolith
- Building an HTTP Server with net/http
- Building an HTTP Server with gorilla/mux
- Creating a minimal service
- Initializing your project with Go modules
- Variables in URI paths
- So many matchers
- Building a RESTful Service
- Your RESTful methods
- Implementing the create function
- Implementing the read function
- Making Your Data Structure Concurrency-Safe
- Integrating a read-write mutex into your application
- Generation 2: Persisting Resource State
- Whats a Transaction Log?
- Your transaction log format
- Your transaction logger interface
- Storing State in a Transaction Log File
- Prototyping your transaction logger
- Defining the event type
- Implementing your FileTransactionLogger
- Creating a new FileTransactionLogger
- Appending entries to the transaction log
- Using a bufio.Scanner to play back file transaction logs
- Your transaction logger interface (redux)
- Initializing the FileTransactionLogger in your web service
- Integrating FileTransactionLogger with your web service
- Future improvements
- Storing State in an External Database
- Working with databases in Go
- Importing a database driver
- Implementing your PostgresTransactionLogger
- Creating a new PostgresTransactionLogger
- Using db.Exec to execute a SQL INSERT
- Using db.Query to play back postgres transaction logs
- Initializing the PostgresTransactionLogger in your web service
- Future improvements
- Whats a Transaction Log?
- Generation 3: Implementing Transport Layer Security
- Transport Layer Security
- Certificates, certificate authorities, and trust
- Private Key and Certificate Files
- Privacy enhanced mail (PEM) file format
- Securing Your Web Service with HTTPS
- Transport Layer Summary
- Transport Layer Security
- Containerizing Your Key-Value Store
- Docker (Absolute) Basics
- The Dockerfile
- Building your container image
- Running your container image
- Running your container image
- Issuing a request to a published container port
- Running multiple containers
- Stopping and deleting your containers
- Building Your Key-Value Store Container
- Iteration 1: adding your binary to a FROM scratch image
- Iteration 2: using a multistage build
- Externalizing Container Data
- Docker (Absolute) Basics
- Summary
- Lets Build a Service!
- III. The Cloud Native Attributes
- 6. Cloud Native Design Principles
- Whats the Point of Cloud Native?
- Its All About Dependability
- What Is Dependability and Why Is It So Important?
- Dependability: Its Not Just for Ops Anymore
- Achieving Dependability
- Fault Prevention
- Good programming practices
- Language features
- Scalability
- Loose coupling
- Fault Tolerance
- Fault Removal
- Verification and testing
- Manageability
- Fault Forecasting
- Fault Prevention
- The Continuing Relevance of The Twelve-Factor App
- I. Codebase
- II. Dependencies
- III. Configuration
- IV. Backing Services
- V. Build, Release, Run
- VI. Processes
- VII. Data Isolation
- VIII. Scalability
- IX. Disposability
- X. Development/Production Parity
- XI. Logs
- XII. Administrative Processes
- Summary
- 7. Scalability
- What Is Scalability?
- Different Forms of Scaling
- The Four Common Bottlenecks
- State and Statelessness
- Application State Versus Resource State
- Advantages of Statelessness
- Scaling Postponed: Efficiency
- Efficient Caching Using an LRU Cache
- Efficient Synchronization
- Share memory by communicating
- Reduce blocking with buffered channels
- Minimizing locking with sharding
- Memory Leaks Canfatal error: runtime: out of memory
- Leaking goroutines
- Forever ticking tickers
- On Efficiency
- Service Architectures
- The Monolith System Architecture
- The Microservices System Architecture
- Serverless Architectures
- The pros and cons of serverlessness
- Serverless services
- Summary
- What Is Scalability?
- 8. Loose Coupling
- Coupling
- Coupling Takes Many Forms
- Shared dependencies
- Fragile messaging protocols
- Shared point-in-time
- Fixed addresses
- Coupling Takes Many Forms
- Service Discovery
- Messaging Protocols
- Messaging Patterns
- Request-Response Messaging
- Common request-response implementations
- Issuing HTTP requests with net/http
- Remote procedure calls with gRPC
- Interface definition with protocol buffers
- Installing the protocol compiler
- The message definition structure
- The key-value message structure
- Defining our service methods
- Compiling your protocol buffers
- Implementing the gRPC service
- Implementing the gRPC client
- Publish-Subscribe Messaging
- Messages versus events
- Asynchronous communication
- Middleware and message brokers
- Consumer processing
- Request-Response Messaging
- Loose Coupling Local Resources with Plug-ins
- In-Process Plug-ins with the plugin Package
- Plug-in vocabulary
- A toy plug-in example
- The Sayer interface
- The Go plugin code
- Building the plug-ins
- Using our Go plug-ins
- Import the plugin package
- Find our plug-in
- Open our plug-in
- Look up your symbol
- Assert and use your symbol
- Executing our example
- HashiCorps Go Plug-in System Over RPC
- Another toy plug-in example
- Common code
- The Sayer interface
- The SayerPlugin struct
- The SayerRPC client implementation
- The handshake configuration
- The SayerRPCServer server implementation
- Our plug-in implementation
- Our host process
- Import the hashicorp/go-plugin and commons packages
- Find our plug-in
- Create our plug-in client
- Connect to our plug-in and dispense our Sayer
- In-Process Plug-ins with the plugin Package
- Hexagonal Architecture
- The Architecture
- Implementing a Hexagonal Service
- Our refactored components
- Our first plug
- Our core application
- Our TransactionLogger adapters
- Our frontend port
- Putting it all together
- Summary
- Coupling
- 9. Resilience
- Keep on Ticking: Why Resilience Matters
- What Does It Mean for a System to Fail?
- Building for Resilience
- Cascading Failures
- Preventing Overload
- Throttling
- Load shedding
- Graceful service degradation
- Preventing Overload
- Play It Again: Retrying Requests
- Backoff Algorithms
- Circuit Breaking
- Timeouts
- Using Context for service-side timeouts
- Timing out HTTP/REST client calls
- Timing out gRPC client calls
- Idempotence
- How do I make my service idempotent?
- What about scalar operations?
- Service Redundancy
- Designing for Redundancy
- Autoscaling
- Healthy Health Checks
- What Does It Mean for a Service to Be Healthy?
- Liveness and Readiness Probes
- The Three Types of Health Checks
- Reachability checks
- Shallow health checks
- Deep health checks
- Failing Open
- Graceful Shutdowns
- Signals and Traps
- Common POSIX signals
- Catching signals
- Stop Incoming Requests
- Clean Up Your Resources
- Putting It Into Action
- Signals and Traps
- Summary
- 10. Manageability
- What Is Manageability and Why Should I Care?
- Configuring Your Application
- Configuration Good Practice
- Configuring with Environment Variables
- Configuring with Command-Line Arguments
- The standard flag package
- The Cobra command-line parser
- Configuring with Files
- Our configuration data structure
- Working with JSON
- Encoding JSON
- Decoding JSON
- Field formatting with struct field tags
- Working with YAML
- Encoding YAML
- Decoding YAML
- Struct field tags for YAML
- Watching for configuration file changes
- Making your configuration reloadable
- Polling for configuration changes
- Watching OS filesystem notifications
- Viper: The Swiss Army Knife of Configuration Packages
- Explicitly setting values in Viper
- Working with command-line flags in Viper
- Working with environment variables in Viper
- Working with configuration files in Viper
- Reading configuration files
- Watching and rereading configuration files in Viper
- Using remote key-value stores with Viper
- Setting defaults in Viper
- Feature Management with Feature Flags
- The Evolution of a Feature Flag
- Generation 0: The Initial Implementation
- Generation 1: The Hardcoded Feature Flag
- Generation 2: The Configurable Flag
- Generation 3: Dynamic Feature Flags
- Dynamic flags as functions
- Implementing a dynamic flag function
- The flag function lookup
- The router function
- Summary
- 11. Observability
- What Is Observability?
- Why Do We Need Observability?
- How Is Observability Different from Traditional Monitoring?
- The Three Pillars of Observability
- OpenTelemetry
- The OpenTelemetry Components
- Distributed Tracing
- Distributed Tracing Concepts
- Distributed Tracing with OpenTelemetry
- Creating the tracing exporters
- The Console Exporter
- The OTLP Exporter
- Creating a tracer provider
- Setting the global tracer provider
- Obtaining a tracer
- Starting and ending spans
- Setting span metadata
- Attributes
- Resource attributes
- Events
- Autoinstrumentation
- Autoinstrumenting net/http and gorilla/mux
- Autoinstrumenting gRPC
- Getting the current span from context
- Creating the tracing exporters
- Putting It All Together: Distributed Tracing
- The Fibonacci service API
- The Fibonacci service handler
- Building the tracer provider
- The services main function
- Starting your services
- Console exporter output
- Viewing your results in Jaeger
- Metrics
- Push Versus Pull Metric Collection
- Push-based metric collection
- Pull-based metric collection
- But which is better?
- Metrics with OpenTelemetry
- Creating your metric exporters
- Setting the global meter provider
- Exposing the metrics endpoint
- Obtaining a meter
- Metric instruments
- Synchronous instruments
- Asynchronous instruments
- Putting It All Together: Metrics
- Starting your services
- Metric endpoint output
- Viewing your results in Prometheus
- Push Versus Pull Metric Collection
- Logging
- Better Logging Practices
- Treat logs as streams of events
- Structure events for parsing
- Less is (way) more
- Dynamic sampling
- Logging with Gos Standard log Package
- The special logging functions
- Log flags
- Structured Logging with the log/slog Package
- Using the slog package
- Logging levels
- The slog.Logger type
- Attributes
- Alternating keys and values
- slog.Attr values
- Common attributes
- Output formatting with handlers
- OpenTelemetry Logging
- Better Logging Practices
- Summary
- What Is Observability?
- 12. Security
- Go: Secure by Design
- Common Vulnerabilities
- Injection
- SQL injection
- Cross-site scripting (XSS)
- Broken Access Control
- Cryptographic Failures
- Injection
- Handling Untrusted Input
- Input Validation
- Input Validation Rules of Thumb
- String encoding
- Double encoding and canonicalization
- Hazardous characters
- Numeric validation
- Leveraging regular expressions
- Input Sanitization
- Converting special characters to HTML entities
- Stripping tags
- Input Validation
- Output Encoding
- Authentication
- Password-Based Authentication
- Common password attacks
- Hashing passwords
- Token-Based Authentication
- The lifecycle of a token
- JSON Web Tokens
- Header
- Payload
- Signature
- All together now
- JSON Web Tokens in Go
- Building and signing a token
- Parsing and validating a token
- Password-Based Authentication
- Communication Security
- Transport Layer Security
- HTTP Over TLS
- gRPC Over TLS
- Cryptographic Practices
- Hashing
- Hashing Algorithms
- Encryption
- Symmetric encryption
- The encryption process
- The decryption process
- Putting these together
- Asymmetric encryption
- Generating a key pair
- The encryption process
- The decryption process
- Putting it all together
- When to use each
- Symmetric encryption
- Cryptographic Randomness
- Database Security
- Connections
- Parameterized Queries
- Regular Expressions
- How Go Regex Is Different
- Syntax
- Summary
- 13. Distributed State
- Distributed State Is Hard
- Theoretical Foundations
- The CAP Theorem
- Consistency Models
- Strong consistency
- Benefits
- Trade-offs
- Weak consistency
- Benefits
- Trade-offs
- Eventual consistency
- Comparing weak and strong consistency
- Strong consistency
- Data Replication
- Synchronous replication
- Asynchronous replication
- Replication and the CAP theorem
- Hybrid approaches
- Common Distributed Algorithms
- Consensus Algorithms
- Paxos
- Raft
- Other consensus algorithms
- Status Dissemination Techniques
- Heartbeating
- Polling
- Gossip
- Hierarchical
- Consensus Algorithms
- Distributing Our Key-Value Store
- Adding Some Raft
- Defining the State Machine
- The Apply Method
- Setting Up the Raft Node
- Defining the API
- Putting It All Together
- Future Directions
- Summary
- Index