Skip to content

Instantly share code, notes, and snippets.

@talum
Created November 27, 2018 04:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save talum/4b9c9e41b828890a05ea4ab24633a5f3 to your computer and use it in GitHub Desktop.
Save talum/4b9c9e41b828890a05ea4ab24633a5f3 to your computer and use it in GitHub Desktop.
microservices_patterns

Microservices Patterns

Chapter 3 Interprocess Communication in a microservice architecture

Intro

IPC (Interprocess Communication)

  • REST w/ JSON - the fashionable choice
  • Messaging

Considerations

  • transaction management
  • author favors lolsely coupled services that communicate over asynchronous messaging

Interprocess communication

  • synchronous request/response: HTTP REST or gRPC
  • asynchonous, message-based AMQP or STOMP
  • text-based JSON or XML or binary format Avro / Protocol Buffers

Styles

  • one-to-one
  • one-to-many
    • publish/subscribe
    • publish / async responses
  • synchronous (request-response tends to be tightly coupled, often blocking)
  • asynchronous
  • one-way notifications - no reply expected or sent

Defining APIs

  • A service's API is a contract between the service and its clients
  • Regardless of IPC mechanism, preciely define API using some kind of interface definition language (IDL)
  • API-first approach? Q: What would that look like for us? Could there be a software design phase? Does that work with Agile?
  • Robustness principle: “Be conservative in what you do, be liberal in what you accept from others.”
  • APIs evolve. In monoliths, it's somewhat easy to change if typed, rolling upgrades, no downtime.
  • Semantic versioning

3.2 Communicating using the synchronous remote procedure invocation pattern RPI: Remote procedure invocation

  • business logic in client invokes proxy interface, which makes a request to the service
  • proxy interface encapsulates the underlying communication protocol

Using REST

  • different levels of maturity for REST
  • Level 0 -- HTTP POST to sole URL endpoint with action to perform, target, and params
  • Level 1 -- resources, POST request with action to perform and params
  • Level 2 -- HTTP verbs to perform actions ono resources
  • Level 3 - HATEOAS - representation of resource returned by GET request contains links for performing actions, no hardcoded URLs in client code
  • familiar, but synchronous.
  • hard to query multiple resources
  • hard to map operations to HTTP verbs

Using gRPC

  • cross language clients and servers
  • binary message-based protocol
  • uses protocol buffers as message format
  • bidirectional streaming enables both RPI and messaging styles of communication
  • harder for JS clients to consume API
  • synchronous communication mechanism, partial failure problem

Circut breaker pattern

  • RPI proxy that immediately rejects invocations for a timeout period after the number of consecutive failures exceeds a specified threshold

Using service discovery

  • Your code needs to know the network location (IP address and port) of server instance

3.3 Communicating using the Asynchronous messaging pattern

  • messaging-based application typically uses a message broker, which acts as an intermediary between the services
  • alternative is brokerless architecture
  • sharding related messages so that they go to the same consumer instance (Kafka, Kinesis)
  • Idempotent message handlers OR discarding duplicates
  • transactional messaging
    • transational outbox pattern: using the database table as a message queue
    • polling publisher: publish messages by polling the outbox in the database
    • publishing events by tailing the transaction log
  • eliminating synchronous interaction
    • ex) define services that only have asynchronous APIs
    • exchange messages with other services and eventually send a reply message to client

Chapter 4 Managing Transactions with sagas

Intro

  • ACID (Atomicity, Consistency, Isolation, Durability)
  • saga - message-driven sequence of local transactions to maintain data consistency
  • sagas are ACD, they lack isolation
  • "Many applications use a lower transaction isolation level in order to improve performance" -- many apps only give the illustion of isolation

1 Transaction management in a microservice architecture

  • traditional approach is to use distributed transactions, they are not widely supported and they are a form of synchronous IPC
  • each additional service involved in a distributed transaction further reduces availability

using the saga pattern to maintain data consistency

  • pattern: saga. maintain data consistency across services using a series of local transactions that are coordinated using asynchronous messaging
  • completion of local transaction triggers execution of the next one
  • a saga must be rolled back using compensating transactions
  • a service publishes a message when a local transaction completes.
  • if recipient is unavailable, broker buffers message until it can be delivered

sagas use compensating transactions to roll back changes

  • saga executes the compensation transactions in reverse order of the forward transactions
  • choreography - distribute the decision making and sequencing among the participants. they primarily communicate by exchanging events
  • orchestration - centralize a saga's coordination logic in a saga orchestrator class. sends command messages to saga participants by telling them which operations to perform

choreography

  • database must update and publish event atomically
  • saga participants must use transactional messaging
  • each saga participant must be able to map each event that it receives to its own data
  • saga must publish events containing a correlation id, get an id to look up the right resource
  • simplicity & loose coupling, but more difficult to understand, cyclic dependencies, risk of tight coupling

orchestration

  • orchestrator class whose sole responsibility is to tell saga participants what to do
  • command async reply-style interaction
  • model saga orchestrator as state machine, set of states and set of transitions between states that are triggered by events
  • simplier dependencies (no cyclic dependencies), less coupling, separation of concerns, but risk of centralizing too much business logic in orchestrator

anomalies caused by lack of isolation

  • lost updates
  • dirty reads
  • fuzzy / nonrepeatable reads

countermeasures

  • compensatable transactions - can be rolled back

  • pivot transaction - go/no-go point in a saga

  • retriable transactions - follow the pivot transaction and are guaranteed to succeed

  • semantic lock - flag in any record that it updates or creates, indicates record isn't committed and could change (ex. order state field)

  • commutative updates: design the update operations to be commutative, executed in any order

  • pessimistic view - reorder the steps to minimize business risk due to dirty read

  • reread value - prevents lost updates, rereads a record before updating it and verify unchanged

  • version file - record operations as they arrive and execute them in the correct order

  • by value - select concurrency mechanisms based on business risk

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment