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

Building Microservice Architectures in Go

Building Microservice Architectures in Go

Moving to a microservice architecture and embracing a cloud native approach is a complex challenge, which often requires re-evaluating our approach to technology. This talk looks at Mondo, a new digital bank, and how they are leveraging a microservice based platform, built almost entirely in Go, to build reliable systems which can scale. We also cover how to develop and migrate to a microservice based architecture using Go, common pitfalls to avoid, and lessons learnt when developing high volume, low latency, distributed applications.

mattheath

June 18, 2015
Tweet

More Decks by mattheath

Other Decks in Programming

Transcript

  1. message Profile { string user_id = 1; string name =

    2; string preferred_name = 3; string phone_number = 4; string email = 5; Address address = 6; string date_of_birth = 7; string gender = 8; map<string, string> metadata = 10; } PROTOBUF DEFINITIONS
  2. message Profile { string user_id = 1; string name =

    2; string preferred_name = 3; string phone_number = 4; string email = 5; Address address = 6; string date_of_birth = 7; string gender = 8; map<string, string> metadata = 10; }
  3. Service Service Service Load Balancer API / Routing Layer datacentre

    1 RabbitMQ Message Bus Cassandra Cassandra Service Service Service Load Balancer API / Routing Layer RabbitMQ Message Bus datacentre n Service L AP Rabb
  4. LOGIN
 API AUTH SERVICE PERMS SERVICE LOAD BALANCER API /

    ROUTING LAYER ACCOUNT SERVICE FEED SERVICE
  5. Library for building services that talk Protobuf via RMQ Self-configuring

    external service adapters library Logic Handler Storage Service libraries
  6. package handler import ( "..." ) func Foo(ctx context.Context, req

    server.Request) (protobuf.Message, error) { }
  7. func handleDelivery(delivery amqp.Delivery) { // Do something for this request

    response, err := executeRequest(delivery) // Send Response server.Respond(response) }
  8. var tokens = make(chan bool, 1000) 
 func handleDelivery(delivery amqp.Delivery)

    { // Throttle requests // error handling omitted... select { case <-tokens: response, err := executeRequest(delivery) tokens <- true // replace token case <-time.After(100 * time.Millisecond): response, err := timeoutResponse() } // Send Response server.Respond(response) }
  9. var tokens = make(chan bool, 1000) 
 func handleDelivery(delivery amqp.Delivery)

    { // Throttle requests // error handling omitted... select { case <-tokens: response, err := executeRequest(delivery) tokens <- true // replace token case <-time.After(100 * time.Millisecond): response, err := timeoutResponse() } // Send Response server.Respond(response) }
  10. • Provisioning • Service discovery • Configuration • Monitoring •

    Authentication/authorisation • AB testing • Self configuring connectivity 
 to third-party services Library for building services that talk Protobuf via RMQ Self-configuring external service adapters library Logic Handler Storage Service libraries
  11. { "timestamp": 1410262798416053450, "traceId": "d30479b8-1491-4390-7cf5-4cd14bc4b765", "type": "REQ", "messageId": "6404dd1e-c995-48a9-73dc-9edb1380f0bf", "parentMessageId":

    "a661f9ef-774c-49b2-6e74-cfed65f7d120", "from": "api.customer", "to": "service.customer", "hostname": "ip-10-13-2-251", "handlerInstanceId": “server-18bd089e-8ef1-4ca1-75cb-8...c”, "az": "eu-west-1a", "payload": "..." }
  12. { "timestamp": 1410262798416053450, "traceId": "d30479b8-1491-4390-7cf5-4cd14bc4b765", "type": "REQ", "messageId": "6404dd1e-c995-48a9-73dc-9edb1380f0bf", "parentMessageId":

    "a661f9ef-774c-49b2-6e74-cfed65f7d120", "from": "api.customer", "to": "service.customer", "hostname": "ip-10-13-2-251", "handlerInstanceId": “server-18bd089e-8ef1-4ca1-75cb-8...c”, "az": "eu-west-1a", "payload": "..." }
  13. Tracing: 33eda743-f124-435c-71fc-3c872bbc98e6 2015-06-03 02:20:19.867 [/] [START] → - 2015-06-03 02:20:19.867

    [eu-west-1a/ip-10-11-3-51] [REQ] api → api.customer.login - 2015-06-03 02:20:19.867 [eu-west-1a/ip-10-11-2-203] [IN] api → api.customer.login - 2015-06-03 02:20:19.868 [eu-west-1a/ip-10-11-2-203] [REQ] api.customer → service.feature-flags.features - 2015-06-03 02:20:19.869 [eu-west-1a/ip-10-11-3-111] [IN] api.customer → service.feature-flags.features - 2015-06-03 02:20:19.876 [eu-west-1a/ip-10-11-3-111] [REQ] service.feature-flags → service.experiment.list - 2015-06-03 02:20:19.877 [eu-west-1a/ip-10-11-3-168] [IN] service.experiment → service.config.compile - 2015-06-03 02:20:19.877 [eu-west-1a/ip-10-11-3-111] [IN] service.feature-flags → service.experiment.list - 2015-06-03 02:20:19.877 [eu-west-1a/ip-10-11-3-111] [REQ] service.experiment → service.config.compile - 2015-06-03 02:20:19.883 [eu-west-1a/ip-10-11-3-168] [OUT] service.experiment → service.config.compile - 5.59 ms 2015-06-03 02:20:19.886 [eu-west-1a/ip-10-11-3-111] [REP] service.experiment → service.config.compile - 8.40 ms 2015-06-03 02:20:19.887 [eu-west-1a/ip-10-11-3-111] [OUT] service.feature-flags → service.experiment.list - 9.72 ms 2015-06-03 02:20:19.889 [eu-west-1a/ip-10-11-3-111] [REP] service.feature-flags → service.experiment.list - 13.23 ms 2015-06-03 02:20:19.889 [eu-west-1a/ip-10-11-3-111] [OUT] api.customer → service.feature-flags.features - 20.58 ms 2015-06-03 02:20:19.890 [eu-west-1a/ip-10-11-2-203] [REP] api.customer → service.feature-flags.features - 22.59 ms 2015-06-03 02:20:19.902 [eu-west-1a/ip-10-11-2-203] [REQ] api.customer → service.customer.read - 2015-06-03 02:20:19.903 [eu-west-1a/ip-10-11-2-203] [REQ] api.customer → service.customer.read - 2015-06-03 02:20:19.903 [eu-west-1a/ip-10-11-2-203] [REQ] api.customer → service.customer.read - 2015-06-03 02:20:19.904 [eu-west-1a/ip-10-11-3-111] [IN] api.customer → service.customer.read - 2015-06-03 02:20:19.904 [eu-west-1a/ip-10-11-3-111] [OUT] api.customer → service.customer.read - 0.36 ms 2015-06-03 02:20:19.905 [eu-west-1a/ip-10-11-2-203] [REP] api.customer → service.customer.read - 1.97 ms 2015-06-03 02:20:19.905 [eu-west-1a/ip-10-11-2-214] [IN] api.customer → service.customer.read - 2015-06-03 02:20:19.905 [eu-west-1a/ip-10-11-2-203] [REQ] api.customer → service.transaction.search - 2015-06-03 02:20:19.905 [eu-west-1a/ip-10-11-2-214] [OUT] api.customer → service.customer.base - 0.10 ms 2015-06-03 02:20:19.906 [eu-west-1a/ip-10-11-2-214] [IN] api.customer → service.customer.base - 2015-06-03 02:20:19.906 [eu-west-1a/ip-10-11-2-214] [OUT] api.customer → service.customer.base - 0.06 ms 2015-06-03 02:20:19.907 [eu-west-1a/ip-10-11-3-58] [IN] api.customer → service.feed.search - 2015-06-03 02:20:19.907 [eu-west-1a/ip-10-11-3-58] [REQ] service.feed → service.zoning.search - 2015-06-03 02:20:19.908 [eu-west-1a/ip-10-11-3-58] [IN] service.feed → service.zoning.search - 2015-06-03 02:20:19.908 [eu-west-1a/ip-10-11-3-58] [OUT] service.feed → service.zoning.search - 0.20 ms 2015-06-03 02:20:19.909 [eu-west-1a/ip-10-11-3-58] [REP] service.feed → service.zoning.search - 2.25 ms 2015-06-03 02:20:19.909 [eu-west-1a/ip-10-11-3-58] [REQ] service.feed → service.raziel.multisearch - 2015-06-03 02:20:19.912 [eu-west-1a/ip-10-11-3-227] [IN] service.feed → service.raziel.multisearch - 2015-06-03 02:20:19.919 [eu-west-1a/ip-10-11-3-58] [REP] service.feed → service.raziel.multisearch - 9.46 ms 2015-06-03 02:20:19.919 [eu-west-1a/ip-10-11-3-58] [REQ] service.feed → service.location.multisearch - 2015-06-03 02:20:19.919 [eu-west-1a/ip-10-11-3-227] [OUT] service.feed → service.raziel.multisearch - 7.58 ms 2015-06-03 02:20:19.920 [eu-west-1a/ip-10-11-3-58] [IN] service.feed → service.location.multisearch - 2015-06-03 02:20:19.920 [eu-west-1a/ip-10-11-3-58] [OUT] service.feed → service.location.multisearch - 0.06 ms 2015-06-03 02:20:19.921 [eu-west-1a/ip-10-11-3-58] [REP] service.feed → service.location.multisearch - 1.77 ms 2015-06-03 02:20:19.921 [eu-west-1a/ip-10-11-3-58] [OUT] api.customer → service.feed.search - 14.02 ms 2015-06-03 02:20:19.921 [eu-west-1a/ip-10-11-2-203] [REP] api.customer → service.feed.search - 15.48 ms 2015-06-03 02:20:19.941 [eu-west-1a/ip-10-11-2-203] [REQ] api.customer → service.experiment.readlastupdated - 2015-06-03 02:20:19.945 [eu-west-1a/ip-10-11-2-214] [IN] api.customer → service.experiment.readlastupdated - 2015-06-03 02:20:19.947 [eu-west-1a/ip-10-11-2-214] [OUT] api.customer → service.experiment.readlastupdated - 1.82 ms 2015-06-03 02:20:19.947 [eu-west-1a/ip-10-11-2-203] [REP] api.customer → service.experiment.readlastupdated - 6.01 ms 2015-06-03 02:20:19.948 [eu-west-1a/ip-10-11-2-203] [OUT] api → api.customer.login - 80.46 ms 2015-06-03 02:20:19.950 [eu-west-1a/ip-10-11-3-51] [REP] api → api.customer.login - 82.71 ms
  14. PhosphorD Host Instances Publish Service A Trace Library goroutine chan

    UDP Service B Trace Library goroutine chan UDP Phosphor In-memory Aggregates Optional
 persistant storage Dashboards & Monitoring
  15. Image Credits ATM: Thomas Hawk
 IBM System/360: IBM Orbital Ion

    Cannon: www.rom.ac Go Gophers: Renee French Duopia: Jonny Hughes Control Room: NASA Microchips: Santi ATM Failure: George Redgrave THANKS!