Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Simplifying microservices with Bondy

Simplifying microservices with Bondy

I introduce Leapsight Bondy, an open source networking platform for distributed Microservices and IoT applications written in Erlang. Bondy implements the open Web Application Messaging Protocol (WAMP) offering both Publish and Subscribe (PubSub) and Routed Remote Procedure Calls (RPC).
Bondy uses Lasp-lang’s Partisan and Plumtree libraries for clustering and data replication. In addition, Bondy embeds a REST API Gateway that simplifies exposing WAMP services via a REST API.

Alejandro M. Ramallo

June 12, 2018
Tweet

Other Decks in Technology

Transcript

  1. SIMPLIFYING MICROSERVICES WITH BONDY ALEJANDRO M. RAMALLO - CEO |

    CTO LEAPSIGHT https://gitlab.com/leapsight/bondy.git 1
  2. 2

  3. Microservices is a software development technique that structures an application

    as a collection of loosely coupled services. In a microservices architecture, services are fine-grained and the protocols are lightweight. — Wikipedia 3
  4. Service Service Service HTTP HTTP HTTP Client API GATEWAY LB

    HTTP JSON JSON JSON JSON MICROSERVICES | CHALLENGES - HTTP is stateless - For inter-service RPC forces you to carry state - Serialisation overhead - More complex client stubs (encoding) - RPC only 4
  5. MESSAGE BROKER Service Service Service HTTP HTTP HTTP RPC PubSub

    RPC PubSub RPC PubSub Proxies, sidecars, etc. Authentication RPC Load Balancing Service Discovery Client API GATEWAY LB HTTP WS TCP JSON X X JSON JSON MSGPACK X MICROSERVICES | CHALLENGES - + PubSub protocol e.g. AMQP - + API Gateway - + Auth Server - + Service Discovery service (etcd, consul) to cater for dynamic addressing (cloud) - API as aggregation of services' APIs - Coarse grained service -Service == IP Address 5
  6. It makes communication between service instances flexible, reliable, and fast.

    The mesh provides service discovery, load balancing, encryption, authentication and authorization, support for the circuit breaker pattern, and other capabilities — Nginx 8
  7. MESSAGE BROKER Service Service Service HTTP HTTP HTTP RPC PubSub

    RPC PubSub RPC PubSub Proxies, sidecars, etc. Authentication RPC Load Balancing Service Discovery Client API GATEWAY LB HTTP WS TCP JSON X X JSON JSON MSGPACK X linkerd linkerd linkerd SERVICE MESH AS SIDECAR - HTTP/1.1, HTTP/2, TLS, gRPC - Reliability primitives (retries, load balancing, etc) - But still no raw TCP/IP! - Does not solve the lack of PubSub - We still need API Gateway, Auth, Service Discovery 9
  8. THE NEED | SERVICE MESH AS BUS - Simplify development

    and deployment of microservices - Support service evolution through composition / decomposition (fine granularity) - Always-on & Realtime systems ➡ Eventual Consistency - Session-based - Polyglot yet a common protocol (RPC and PubSub) - Multiple transports and encodings - Auth, Service Discovery, API Management - Reliability primitives (LB, retries, circuit breaking, Sagas) 10
  9. SERVICE MESH Service Service Service CLIENT CLIENT CLIENT Client LB

    HTTP WS TCP WS TCP JSON MSGPACK ERL BERT Avoid the SOA/ESB pitfall: "dumb endpoints and smart pipes" — Martin Fowler 11
  10. WAMP is an open standard WebSocket subprotocol1 that provides two

    application messaging patterns in one unified protocol: Remote Procedure Calls + Publish & Subscribe. — Crossbar.io Technologies GmbH 1 Actually a WebSocket subprotocol and a TCP protocol a.k.a Raw Socket. 13
  11. WAMP - WebSockets or TCP/IP - Asynchronous message passing -

    Multiple encodings: json | msgpack | cbor (+12 slots) - Multiple authentication schemes - Service == Function - Supported in 13 programming languages 14
  12. SESSIONS - Session-based - Only clients can initiate a session

    - IoT ➡ no open ports required - Multiple authentication options 15
  13. CALLEE CALLER ROUTER (DEALER) CALL INVOCATION YIELD | ERROR RESULT

    | ERROR CANCEL INTERRUPT REGISTER ROUTED RPC [ REGISTER :: enum(), request_id :: non_neg_integer(), options :: map(), procedure :: uri() ] [ CALL :: enum(), request_id :: non_neg_integer(), options :: map(), procedure :: uri(), args :: [wamp_type()] args_kw :: map() ] 19
  14. CALLEE CALLER ROUTER (DEALER) CALL INVOCATION YIELD | ERROR RESULT

    | ERROR CANCEL INTERRUPT REGISTER ROUTED RPC [ RESULT :: enum(), request_id :: CALL.request_id, details :: map(), procedure :: uri(), args :: YIELD.args args_kw :: YIELD.args_kw ] OR [ ERROR :: enum(), request_type :: CALL request_id :: CALL.request_id, details :: map(), error_uri :: uri(), args :: YIELD.args args_kw :: YIELD.args_kw ] 20
  15. MESSAGE BROKER Service Service Service HTTP HTTP HTTP RPC PubSub

    RPC PubSub RPC PubSub Proxies, sidecars, etc. Authentication RPC Load Balancing Service Discovery Client API GATEWAY LB HTTP WS TCP JSON X X JSON JSON MSGPACK X WAMP ROUTER Service Service Service WAMP WAMP WAMP Client LB WS TCP WS TCP JSON MSGPACK ERL HTTP X BERT 22
  16. WAMP ROUTER Service Service Service WAMP WAMP WAMP Client LB

    WS TCP WS TCP JSON MSGPACK ERL HTTP X BERT ALMOST THERE - But still no API Management 23
  17. IMPLEMENTATIONS - Crossbar.io - Python, the cannonical implementation - Routers

    in many languages - All of them currently lack clustering 24
  18. RPC Features - Invocation Policy - single - dealer accepts

    only one registration for URI - first, last - hot stand-by - random, round_robin - load balancing - force_locality - when in cluster, if true gives priority to Callee local to the Caller, otherwise applies Invocation Policy cluster-wide 25
  19. Bondy is an open source networking platform (or service mesh)

    for distributed Microservices and IoT applications written in Erlang. It implements the open WAMP offering both Publish and Subscribe (PubSub) and routed Remote Procedure Calls (RPC) together with an HTTP/REST API Gateway. — the presenter 27
  20. BONDY - Written in Erlang - Eventual consistency through gossip

    (Plumtree) - Distribution via Lasp-lang's partisan library - Open source (Apache 2) - https://gitlab.com/leapsight/bondy.git 28
  21. VISION - A cloud service mesh as a bus -

    A fog IoT hub connected to the cloud (hub and spoke) - Smart endpoints and dumb pipes - Embrace eventual consistency ➡ CRDTs everywhere - Gateways as plugins (MQTT, CoAP, etc.) - Scaleable, Reliable, Always-on 29
  22. BONDY WEB / MOBILE APPS THINGS HTTP WS HTTP WS

    HTTP WS MICROSERVICE REST API GATEWAY ENCODING JSON MSGPACK BERT OTHER OTHER GATEWAYS TCP TCP WAMP ROUTER WAMP REST/HTTP MQTT GATEWAY RPC (DEALER) PUBSUB ( BROKER) AUTH & SESSION MANAGEMENT ERL UDP DISTRIBUTED LOG ADAPTERS RBAC AUTH ADAPTERS REGISTRY OAUTH2 SERVICE DB PEER SERVICE 30
  23. BONDY WEB / MOBILE APPS THINGS HTTP WS HTTP WS

    HTTP WS MICROSERVICE REST API GATEWAY ENCODING JSON MSGPACK BERT OTHER OTHER GATEWAYS TCP TCP WAMP ROUTER WAMP REST/HTTP MQTT GATEWAY RPC (DEALER) PUBSUB ( BROKER) AUTH & SESSION MANAGEMENT ERL UDP DISTRIBUTED LOG ADAPTERS RBAC AUTH ADAPTERS REGISTRY OAUTH2 SERVICE DB PEER SERVICE leapsight/plum_db (riak_core_metadata_*) lasp-lang/partisan lasp-lang/plumtree ninenines/cowboy leapsight/mops lasp-lang/partisan lasp-lang/plumtree jsx msgpack bert STATS / TRACING prometheus opencensus-erlang 31
  24. plum_db is a globally replicated via Epidemic Broadcast Trees and

    lasp-lang’s Partisan. An offspring of Plumtree and Partisan, a descendant of Riak Core Metadata Store. — https://gitlab.com/leapsight/plum_db 32
  25. Feature plum_db plumtree (riak_core_metadata) API A simplification of the Riak

    Core Metadata API. A single function to iterate over the whole database i.e. across one or all shards and across a single or many prefixes Riak Core Metadata API (plumtree_metadata_manager is used to iterate over prefixes whereas plumtree_metadata is used to iterate over keys within each prefix. The API is confusing and is the result of having a store (ets + dets) per prefix. cluster membership state partisan membership state which uses an AWSET ORSWOT (riak_dt) data model Riak Core Metadata (dvvset) Riak Core Metadata (dvvset) persistence leveldb. A key is sharded across N instances of leveldb, where N is configurable at deployment time. Each prefix has its own ets and dets table. active anti-entropy Based on Riak Core Metadata AAE, uses a separate instance of leveldb to store a merkle tree on disk. Updated to use the new API and gen_statem Based on Riak Core Metadata AAE, uses a separate instance of leveldb to store a merkle tree on disk. pubsub Based on a combination of gen_event and gproc, allowing to register a Callback module or function to be executed when an event is generated. gproc dependency allows to pattern match events using a match spec Based gen_event, allowing to register a Callback module or function to be executed when an event is generated 33
  26. art - The algorithm we are using to replace the

    existing poorsman implementation of the Registry 34
  27. STATE ENTITY TYPE STORE RPC Registrations glocal memory, plum_db RPC

    State local memory PubSub Subscriptions glocal memory, plum_db API Gateway Spec global plum_db RBAC global plum_db OAUTH2 global plum_db 35
  28. MAGENTA IOT PLATFORM CLOUD Docker, Kubernetes, Private or Public Cloud

    API Open REST and WAMP API COSAS ARCHITECTURE Distributed system based on microservices, 
 Erlang, Real-time Stream Processing, 
 Big Data. Adaptability Modular architecture allows rapid integration of new protocols and devices. GATEWAYS AGENTES PERSONAS 37
  29. ( '   * SIGNAL STREAMS MAGENTA IOT PLATFORM

    GATEWAYS ' AGENT THINGS AGENTS 38
  30. MAGENTA OPEN API ACCOUNT USER PERSON NOTIF THING AGENT REMINDER

    TASK GEOFENCE TRIP LOCATION ACTION DEVICE TYPE 40
  31. state The properties that represent the internal state of the

    thing. info Metadata about a thing, a set of properties, some of them are modifiable by the end user e.g. vehicle color. In future releases this uses a Knowledge Graph platform (Semantic Web). properties All information about a thing is accessed through a set of properties. actions Actions that can be performed on a thing disarm arm armed = false mrn:things:alarm_1 41
  32. MAGENTA IOT PLATFORM BONDY DEVICE GATEWAY WEB / MOBILE APPS

    THINGS MICROSERVICES REST API GATEWAY COAP GATEWAY TCP MQTT GATEWAY ! " # $ % * LM DIRECT HTTP WS HTTP WS TCP UDP   TCP OTHERS DISTRIBUTED LOG RAW SIGNAL EVENT CMD DATA STORAGE SERVICES WAMP ROUTER WS TCP TCP KV TS KGRAPH SQL RAW ACCOUNTS THINGS AGENTS / STREAM PROCESSORS … | ILM CLOUD PLATFORM COREOS KUBERNETES PROMETHEUS | PRIVATE CLOUD PUBLIC CLOUD Polyglot Microservices are written in the best programming language for the task e.g. Python for Machine Learning. Multi-protocol Open API Third-parties can develop services using API via REST/HTTP or WAMP/WS . Multi-protocol Supported via Bondy and custom Gateways. Metadata-driven New thing types can be added using metadata (capabilities) Portable Private or Public Cloud 42
  33. API Gateway Spec Example (1/6) We extract the query_params from

    the Cowboy HTTP Request and split it in to maps using mops id: com.magenta.public name: Magenta Platform API host: _ realm_uri: com.magenta.public variables: query_spec: "{{request.query_params |> with([_q,_p,_limit,_sort,_page,_include])}}" query_match: "{{request.query_params |> without([_q,_p,_limit,_sort,_page,_include])}}" 45
  34. API Gateway Spec Example (2/6) paths: "/things": is_collection: true get:

    action: type: wamp_call procedure: com.magenta.things.find options: {} arguments: - "{{variables.query_match}}" arguments_kw: query_spec: "{{variables.query_spec}}" security: "{{security}}" trace_id: "{{request.id}}" response: on_error: status_code: "{{status_codes |> get({{action.error.error_uri}}, 500) |> integer}}" body: "{{action.error.arguments_kw |> put(code, {{action.error.error_uri}})}}" on_result: body: "{{action.result.arguments |> head}}" 46
  35. API Gateway Spec Example (3/6) post: action: type: wamp_call procedure:

    com.magenta.things.create options: {} arguments: - "{{request.body}}" arguments_kw: security: "{{security}}" trace_id: "{{request.id}}" response: on_error: status_code: "{{status_codes |> get({{action.error.error_uri}}, 500) |> integer}}" body: "{{action.error.arguments_kw |> put(code, {{action.error.error_uri}})}}" on_result: uri: '"{{request.path}}/{{action.result.arguments |> head |> get(id)}}"' body: "{{action.result.arguments |> head}}" 47
  36. API Gateway Spec Example (4/6) "/things/:id": get: action: type: wamp_call

    procedure: com.magenta.things.fetch options: {} arguments: - "{{request.bindings.id}}" arguments_kw: query_spec: "{{variables.query_spec}}" security: "{{security}}" trace_id: "{{request.id}}" response: on_error: status_code: "{{status_codes |> get({{action.error.error_uri}}, 500) |> integer}}" body: "{{action.error.arguments_kw |> put(code, {{action.error.error_uri}})}}" on_result: body: "{{action.result.arguments |> head}}" 48
  37. API Gateway Spec Example (5/6) delete: action: type: wamp_call procedure:

    com.magenta.things.delete options: {} arguments: - "{{request.bindings.id}}" arguments_kw: security: "{{security}}" trace_id: "{{request.id}}" response: on_error: status_code: "{{status_codes |> get({{action.error.error_uri}}, 500) |> integer}}" body: "{{action.error.arguments_kw |> put(code, {{action.error.error_uri}})}}" on_result: body: "{{action.result.arguments |> head}}" 49
  38. API Gateway Spec Example (6/6) patch: action: type: wamp_call procedure:

    com.magenta.things.update options: {} arguments: - "{{request.bindings.id}}" - "{{request.body}}" arguments_kw: security: "{{security}}" trace_id: "{{request.id}}" response: on_error: status_code: "{{status_codes |> get({{action.error.error_uri}}, 500) |> integer}}" body: "{{action.error.arguments_kw |> put(code, {{action.error.error_uri}})}}" on_result: body: "{{action.result.arguments |> head}}" 50
  39. Basic Pro!le Features Feature Required Implemented Multiple realms per router

    ✔ ✔ Websockets ✔ ✔ Serialisations JSON, Msgpack, CBOR JSON, Msgpack, Bert, Erl RPC routing ✔ ✔ RPC Load Balancing ✔ ✔ PubSub routing ✔ ✔ 52
  40. Advanced Pro!le Features Feature Required Implemented Session Meta API ✔

    coming soon Challenge-response Authentication ✔ ✔ Cookie Authentication ✔ ❌ Ticket Authentication ✔ ✔ Challenge-response Authentication ✔ ✔ Raw socket transport ✔ ✔ Batched WS transport ✔ ❌ Longpoll transport ✔ ❌ 53
  41. RPC Advanced Pro!le Features Feature Required Implemented Progressive Call Results

    ✔ ❌ Progressive Calls ✔ ❌ Call Timeout ✔ ✔ Call Canceling ✔ ✔ Caller Identification ✔ ✔ Caller Trustlevels ✔ ❌ Registration Meta API ✔ ✔ Pattern-based registration ✔ coming soon Shared registration ✔ ✔ Sharded registration ✔ coming soon Registration revocation ✔ ❌ Procedure reflection ✔ ❌ 54
  42. PubSub Advanced Pro!le Features Feature Required Implemented Subscription Meta API

    ✔ ✔ Subscriber blackwhite-listing ✔ ✔ Publisher exclusion ✔ ✔ Publication trustlevels Timeout ✔ ❌ Pattern-based subscription ✔ coming soon Sharded subscription ✔ coming soon Registration revocation ✔ ❌ Event history ✔ coming soon Topic reflection ✔ " 55
  43. N/A Features Feature Others Bondy REST API Gateway ❌ ✔

    Distributed RPC routing ❌ ✔ Distributed PubSub routing ❌ ✔ 56