Microservices with Nameko

An Example Webapp

  • Client-side code (JavaScript)
  • A data store (ex. mySQL server)
  • Backend app
    • Routing
    • HTTP, etc Requests
    • API to expose data
    • Database calls
    • Authentication

The Monolith

Pros

  • Easy access to other code
  • Centralized models in single data store (easy to backup)
  • Lower devops overhead

Cons

  • Scaling one thing == scaling everything
  • Easy to end up with "spaghetti" code, with tangled dependencies and tight coupling, so can be dangerous to change or upgrade.
  • Can have long deploy cycle

Microservices

  • Small, isolated functionality
  • Independently deployable, upgradable, scalable
  • Functionality exposed over network layers (HTTP, RPC)
  • Decentralized data stores (many different databases e.g.)
  • Focus on service / developer / team independence

Microservice Complexity

  • Complexity doesn't disappear...it relocates
  • More complex with microservices:
    • Authentication
    • Devops: Provisioning and deployment
    • Speed of calls (local vs. remote)
    • Managing backups
    • Service discoverability

Nameko

A python framework for creating microservices

  • Library of utilities for building and running microservices
  • CLI for easily running and interacting with services (nameko run / shell)
  • Way of thinking about dependencies and application logic that encourages microservices approach

Nameko Services

Microservices are classes with:

  • a "name" attribute
  • dependency attributes
  • methods with entrypoint decorators

 

Wait...how does the client actually call the service?

 A message broker implementing the Advanced Messaging Queue Protocol (AMQP), an open messaging protocol.

Don't run away, Nameko handles the RabbitMQ bits

Namenkolature

Entrypoint: Exposes a method, often by monitoring an external entity (e.g. a queue)

 

Dependencies: "Gateways" to other code, not managed by the service (other services, databases, APIs)

 

Workers: Instance of a service class. Dependencies are replaced with result of `get_dependency`

Example 1: HTTP

  • GET and POST methods supported
  • Decorator takes a method and route, with variables
  • Multiple decorators can be placed on the same method
  • Built on top of Werkzeug (request / response objects)

 

Let's try it!

Example 2: RPC

  • Stands for "Remote procedure call"
  • Nameko implements RPC over AMQP
  • rpc decorator: exposes method
  • RpcProxy: easily inject other rpc-exposed dependency
  • ClusterRpcProxy: allows non-nameko clients to make rpc calls to a cluster

 

Let's try it!

Example 3: Events

  • Publisher / Subscriber (Pub / Sub)
  • Event gets "dispatched" and 0 or more subscribers pick it up
  • EventDispatcher: dependency helper to easily dispatch events to subscribers
  • event_handler decorator: subscribes an endpoint to an event from a dispatcher service
  • event_dispatcher: for non-nameko clients

 

Let's try it!

Example 4: Timer

  • Want to do something every 3 seconds forever? @timer's got your back!
  • timer decorator: runs a method (e.g. pinging a server) at a specified interval

 

Let's try it!

"Great! How do I move all the things to microservices?"

Microservices not recommended...?

  • Microservices are new and need a particular amount of operational freedom ("devops culture").
  • They can easily lead to systems that are just and coupled and complex as monoliths

Do Try this at Home

  • Play around with Nameko / microservices
  • Next time there's something that benefits from being a service, consider building it as one or moving it
    • Using a library you want to isolate or can't upgrade
    • Isolating interaction with a third party
    • Want to try a new data store for some benefit it provides

Questions

Code available on GitHub

ripleyaffect/nameko_examples