Microservices

at NewStore

/whois

Jan-Oliver Pantel

Software Engineer Commerce Backend

@NewStore

Conway's Law

organizations which design systems ... are constrained to produce designs which are copies of the communication structures of these organizations

What do we want?

Quick reaction times

High Quality

Pick one

Small teams

  • Small problem domains
  • Less cognitive load
  • Less overhead
  • Not to much layers of communication
  • Small teams are quicker

Big teams

  • Big problem domains
  • No communication boundaries

Monoliths

and

Microservices

Preface

  • There is no perfect solution for everyone
  • Monolith and Microservices both have their trade-offs
  • Monolith != messy code
  • Microservices != clean code
  • Monolith is not evil!
  • Microservice architecture is a complete different architectual approach

The monolith

Monolith and small teams

  • Teams block each other while working on the same monolith
  • "We can not deploy this yet!"

Microservices

Microservices and small teams

  • One guy owns one service
  • Deep understanding
  • Threat: Silo knowledge

Copyright Martin Fowler

Deployment

Deployment

Why MS?

  • Scalability
  • Polyglotism
  • Independence
  • Best technology for the job
  • Replaceability

Expectations

  • Seperation of concerns
  • Decoupling
  • Clear fail spots

Who?

From PHP monolith

to Rails monolith

to MS with WebSocket API

1 Request ~= 100 Services

Search "Nike shoe" = 170 services

From monolith with huge DB

to 450 MS with own data management

Independent teams ('squads')

and the No-Shared-Data-Principle

Decoupling and async data transfer

through internal REST APIs

HOW?

we did it...

  • Easy deployment
  • No "works on my machine"
  • Easy scaling
  • Reproducable
  • Concurrency for free
  • Easy to learn
  • Rich stdlib
  • Fast compiling
  • Single static binary
  • No runtime on server
  • Open Source Community
  • AMQP protocol
  • Fast
  • Failsafe
  • Topic exchanges
  • Fanout exchanges
  • (Service discovery)
  • Caching
  • Caching
  • Inter instance sync
  • Distributed locks
  • Amazon RDS
  • JSON fields
  • JSON queries
  • Service Discovery
  • Health Checks
  • DNS
  • Property Store
  • Watch function
  • Metrics
  • Small protocol
  • Small footprint
  • Data pull

In the future

Implementation

RPC

Service A

{
    "exchange": "rpc", 
    "routing_key": "rpc.service_b.do",
    "context": {
        "user_id": "4711",
        "request_id": "0815",
        "tenant": "hannoverjs"
    },
    "body": {
        "hello": "world",
        "foo": "bar"
    }
}

Service B

{
    "request_id": "0815",
    "has_error": false,
    "response": {
        "done": true
    }
}

Events

Service A

{
    "exchange": "events", 
    "routing_key": "events.called_service_b",
    "context": {
        "user_id": "4711",
        "request_id": "0815",
        "tenant": "hannoverjs"
    },
    "body": {
        "hello": "world",
        "foo": "bar"
    }
}

Why RabbitMQ?

  • No service discovery bottleneck
  • Persistent messages
  • Acknowledging
  • Brokers available (host and go)

Service Discovery

for Infrastructure

Where is Rabbit / Postgres / ... ?

{
    "service": "rabbitmq",
    "host": "192.168.278.32",
    "port": "5432",
    "user": "guest",
    "password": "guest"
}

Service Discovery

for Services

Where is Service B?

{
    "service": "service_b",
    "host": "192.168.278.133",
    "port": "1337",
    "up": true,
    "up_since": 7437981
}
{
    "service": "service_b",
    "host": "",
    "port": "",
    "up": false,
    "up_since": null
}

Service Registration

Hey it's me Service A

{
    "service": "service_a",
    "host": "192.168.278.133",
    "port": "1337",
    "health_check": "/health"
}

Sample

Import

API

Import

Pers.

Prod.

Import

Prod.

Pers.

Post

processor

Indexer

Conclusion

Microservices are not the holy grail

  • Service can and will fail
  • Makes development harder
  • Network overhead
  • Transactions!

Should I do this thing?

  • Startup? Do the monolith!
  • You can always extract single services
  • Small team? Monolith!
  • If business domain is clear

But... why?

  • Lot of initial development for communication layer
  • Lots of conventions to create
  • Hard to focus on business goals
  • Deployment becomes a HUGE topic
  • Monitoring is hard
    • Monolith dies => completly clear
    • Single service dies => WTF?!?
  • Debugging is hard
    • Bye interactive debugging all the way
  • Refactoring is hard
  • Testing is hard
    • How guarantee that my service mocks behave equal to the production service

But you did?

  • Teamsize > 50 devs
  • 4 locations
  • 6 different business domains
  • Business domain is already fixed
  • We have dedicated ops people (!)
  • We designed our communication to fit

What's the right spot?

  • You already have a product
  • Or your entire team is big / distributed
  • And you have dedicated ops people
    • Server Admins != ops
  • And your company culture is ready
  • And you are aware of the trade-offs !!!

Copyright by ThoughtWorks

Learnings

Use open source solutions for communication layer

If possible

Mind HTTP when designing own RPC layer

If your protocol isn't HTTP anyway

Mind latency and the network itself

Think about versioning from the beginning

Test each service individually

Log everything!

Stick to a limited stack of technology in the beginning

Log everything!

Let everything be human readable and verbose

Questions?

Thank you!

Made with Slides.com