[아티클 리뷰] MSA 제대로 디자인하기 Design Microservice Architectures the Right Way- Michael bryznek

후기

  1. 이 발표 영상이 제일 헛웃음이 나왔다

  2. 모든것을 사람의 손에 맡기지 않고 JSON 스펙에 따른ODE GENERATION으로 해결한다.

  3. 선언적인 API, 어떻게 진화할까 궁금하다.

Great Architecture vs Not so Great Architecture

Scales Dev Teams | Near term Velocity

Delivers Quality | Future Paralysis

Enables High Performance/ Low Cost

Supports Future Features Naturally

Misconceptions


  1. Microservices enable our teams to choose the best programming langs and frameworks for their tasks

Reality:

We'll demonstrate just how expensive this is.

Team size and investment are critical inputs.

Google has 8 langs and 32000 employees

virtually, 1 lang / 4000 employees

  1. Code generation is Evil

    Reality:

What's important is creating adefined schema that is 100 % trusted.

Schema that is 100 % trusted.

We'll demonstrate one technique leveraging code generation

  1. The Event Log Must be the Source of Truth

Reality:

Events are critical parts of an interface.

But it's okay for services to be the system of record for their resources.

  1. Developers can maintain no more than 3 services each

Reality:

Wrong Metrics; we'll demonstrate where automation shines

Flow devs maintain ~5 services

Weekly maintenance <5% of time

Architecture of Flow.io

Only one set of APIs and Events in Flow

  1. How: Forms are used to create instances of rscs

API Definition

  1. Language Neutral in JSON

  2. Everything is resources

  3. Annotations included easily for GDPR

  1. How: Resource Oriented

Expose User's rsc by providing operations

  1. get by id

  2. post of user form

  3. How: Definitions in Git, with CI

Modify JSON and pull → triggered CI

Set of linters run on these JSON

  1. how: Tests Prevent Errors

Verify Potential braking changes during API Design Phase

  1. how: API Implementation Supported by Code Generation

Grpc→ code generation

specifications is the first thing we build

  1. how: Code Genration: Routes

  2. Absolute certainties specs matches implementations

  3. Built by one person feelings with consistent namings

  1. how: Code Generation: Client

  2. Optimize things to make it possible

  3. Implementations should be so nice so that devs wouldn't dev on them

  1. how: Mock Client

  2. Compiles and fully functional

  3. High fidelity and fast testing

  4. Sufficiently prove that testing works

  5. Mock client + extra to make them work

  6. Only 2 cases where it is not caught on by mocks (networking)

  1. how: Implementation

  2. Same awesome codes all micro services

Database Architecture

  1. Each microservices app owns its database

  2. No other service is allowed to connect to the database

    1. It is a np problem to prove that the db is correct ⇒ insiduous tech debts

  3. Other services use only the service interface (API + Events)

!https://s3-us-west-2.amazonaws.com/secure.notion-static.com/8eb1f5ae-7bee-486a-a598-a3e52a56cd37/Untitled.png

  1. HOW: Create a Database

    1. This is the only way to establish a database.

    2. entering "dev" returns help of this tool

    3. All databases are following the same db naming conventions make the users understand the system better

    4. One person knows all and other people benefit from their works

  2. How: Define storage req in metadata

    1. Describe "scala" req

    2. Describe "psql" req

    3. Code generate the table definition

    4. Code generate the data access obj

    5. Note data tier independent from API

    6. Just uses the same tool chain

  1. How: Code generation: Create a Table

  2. No empty string

  3. Consisten chekcs, meta data

  4. Enable global features like 'hash_code' to minimize the writes

    1. Ops hashcoded set to minimize the writes

    2. Creating dbs do not need a creativity strictly enforced

  5. How: Code generation: Scala Class

  6. Normalize access to DB

    1. indexes on ids, email, hasEmail, ... using findAll

  7. Ensure proper indexes exist from start

    1. One way to do it is that you index for what you want for retrieval.

      1. Devs will go in and use find_by_email method

      2. We have caught it in the beginning of dev process

  1. How: Test Resource Ops

    1. Use the generated mock clients to write simple tests

Continous delivery is a prerequisite to managing micro service architectures

  1. Deploy triggered by a git tag

  2. Git tags created automatically by a change on master (ex merge PR)

  3. 100 % Automated, 100 % reliable

It took one person to build CD entirely

!https://s3-us-west-2.amazonaws.com/secure.notion-static.com/a598cbc3-d1ae-49c2-a31e-4d371a6edafa/Untitled.png

Microservice Infrastructure — keep it simple

  1. Let the experts do this for you

Standard Health Checks

Events

We have an amazing API, but please subscribe to our event streams instead.

  1. They consumes events mostly

  2. Can use API but usually use events more

!https://s3-us-west-2.amazonaws.com/secure.notion-static.com/9149f28a-8ec7-4ebd-b77f-8d4cbea2d421/Untitled.png

Principles of an Event Interface

  1. gRPC(binaries) — forcing devs to use code generation to consume events to depict the events are awesome

  2. Correctness is important to keep the specs in prod and current specified specs

  3. They use Kinesis

  4. We emphasize simplicity

Events: Approach

Producers:

  1. Create a journal of ALL ops on table

    1. All the insert, deletes along with the ops

  2. Record Ops (Insert, Update, Delete)

  3. On creation, queue the journal record to be published

  4. Real time, async, we publish 1 event per journal record

  5. Enable replay by simply requeuing journal record

Consumers:

  1. Store new events in local db, partitioned for fast removal

  2. On event arrival, queue recrod to be consumed

  3. Process incoming events in micro batches (250 ms)

  4. record failures locally

    1. You don't have to go to kinesis or journal

    2. You have a copy of it in local

    !https://s3-us-west-2.amazonaws.com/secure.notion-static.com/11e0d157-74f8-44ee-a334-cbe0a9988a39/Untitled.png

Events: Schema First

They use api builder here as well.

This goes through linters as well

user_event → naming convention

  1. 1 model/ event

  2. N events in one union type

  3. 1 union type /stream

  4. Stream owned by 1 service

  5. Most services define exactly 1 stream

!https://s3-us-west-2.amazonaws.com/secure.notion-static.com/5a86d9c1-5f96-4f1a-9330-ce6cec2c9968/Untitled.png

Events: Schema Linter

  1. timestamp

  2. orgs

  3. ALL the events will look the same

  4. same structures

  5. Consistencies let you do a lot of interseting things

!https://s3-us-west-2.amazonaws.com/secure.notion-static.com/7494116a-0a09-4a59-99b1-d25b0645a1b0/Untitled.png

Producers: Database Journal

  1. Document retention period

  2. Code generate journal

  3. Use Partitions to manage stroage

!https://s3-us-west-2.amazonaws.com/secure.notion-static.com/4f8bac8f-6b96-4de3-87c8-35dd79bdcebb/Untitled.png

Producers: Streams

  1. Devs should feel easy to use it

!https://s3-us-west-2.amazonaws.com/secure.notion-static.com/640e8f7c-3852-4bd8-8eed-2da4c8d95c8d/Untitled.png

  1. All the app codes will look very similar to these

  2. Any microservices will be relevant because it behaves the same

  3. Other than domain knowledge and context

!https://s3-us-west-2.amazonaws.com/secure.notion-static.com/3f989c4b-e66a-46af-9a7a-d7269613577d/Untitled.png

Producers: Testing

  1. This works on prod

  2. High fidelity testing

!https://s3-us-west-2.amazonaws.com/secure.notion-static.com/b5882f25-7a8b-4af2-af96-19978f321579/Untitled.png

!https://s3-us-west-2.amazonaws.com/secure.notion-static.com/1307b60e-0fd8-433a-8ab3-ab3f78d1700b/Untitled.png

Consumers Testing

  1. End to end test

  2. easy

Dependencies

Goals: Automatically update all services to latest dependencies

  1. Critical for security patches / bug fixes in core libs

  2. Takes hours (not weeks or months)

  3. Same process for internally developed libs and open src

  4. Flow: we upgrade all services every week to latest dependencies

Keep things up to date

!https://s3-us-west-2.amazonaws.com/secure.notion-static.com/2e553ef9-9fe9-4ced-8a9f-5fe8721e64d6/Untitled.png

  1. Dependencies: Tracking

    1. Git hub extract all libs and binaries

      1. Crawls all of them and keep tracks of them

      2. Event stream to you to provide these recommendations

      3. Version tag parsers in Scala combinators

      4. These works perfectly without false positive

      5. Totally worth it.

    2. Recommended Upgrades packages

    3. Recommendations

    4. Dependencies

    !https://s3-us-west-2.amazonaws.com/secure.notion-static.com/0d05692a-1a1f-474a-b302-03d217e6863e/Untitled.png

  2. Dependencies: Updating

    one command to do this

Dependencies & Continous Delivery

  1. deploy once the build passes

Summary

  1. Design schema first for all APIs and Events

    1. consume events by default

  2. Invest in automation

    1. deployment, code generation, dependency management

  3. Enable teams to write amazing and simple tests

    1. drives quality, streamlines maintenance, enables continous delivery

TDD in Prod

looks amazing

tests run as cronjobs

How to manage features and different branches and CD?

  1. Every features are usually factored in.

  2. Open Pull Requests are not going to be existent

    1. When you are done it is in prod

    2. Everyday implementations need to be decomposed and pulled in.

    3. Feature flag that is enabled and prod will use it.

Last updated