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

Elastic scaling in a (micro)service oriented a...

Elastic scaling in a (micro)service oriented architecture

Splitting an application up into multiple independent services can be a good way to keep it scaling and ensure stability and developer productivity in larger, growing teams. But just splitting the codebase, creating APIs and deploying the code on some servers is not enough, somehow your services need to know where and how other services are accessible. Classical approaches like hardcoding everything in every service or having a central load-balancer can quickly lead to problems in terms of scalability and maintainability. In this talk I'll show how we at ResearchGate tackled this challenge. With the help of tools like Consul and haproxy we created a setup that allows us to quickly boot and shutdown services. This ensures that all servers are utilized optimally and load spikes can be reacted upon quickly and automatically.

Bastian Hofmann

February 18, 2016
Tweet

More Decks by Bastian Hofmann

Other Decks in Programming

Transcript

  1. •A big monolith •Multiple small to medium sized services •Lots

    of shared libraries •Tools and utilities •Hadoop jobs •Flink jobs •Server Provisioning
  2. •Nginx •PHP-FPM •Glassfish •Jetty •Dropwizard •haproxy •PostgreSQL •MongoDB •Memcached •Infinispan

    •Solr •Zookeeper •Elasticsearch •Logstash •Kibana •Graphite •StatsD •RabbitMQ •Hortonworks Data Platform •HBase •Hive •Consul •Vault •CheckMK •Azkaban •ActiveMQ •Apache HTTPD •Docker •Kafka
  3. Consul Server Consul Server Consul Server Consul Agent ver Consul

    Agent Server Consul Agent Server Co Ag Server
  4. $config = [ 'serviceA' => [ '192.168.0.1:8001', '192.168.0.2:8001', ], 'serviceB'

    => [ '192.168.0.1:8002', ], 'serviceC' => [ '192.168.0.2:8003', ] ];
  5. $config = [ 'serviceA' => [ '192.168.0.1:8001', '192.168.0.2:8001', ], 'serviceB'

    => [ '192.168.0.1:8002', ], 'serviceC' => [ '192.168.0.2:8003', ] ];
  6. $config = [ 'serviceA' => [ '192.168.0.1:8001', '192.168.0.2:8001', ], 'serviceB'

    => [ '192.168.0.1:8002', ], 'serviceC' => [ '192.168.0.2:8003', ] ];
  7. Consul Server Consul Server Consul Server Consul Agent ver Consul

    Agent Server Consul Agent Server Co Ag Server
  8. DNS

  9. admin@hashicorp: dig web-frontend.service.consul. ANY ; <<>> DiG 9.8.3-P1 <<>> web-frontend.service.consul.

    ANY ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 29981 ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 0 ;; QUESTION SECTION: ;web-frontend.service.consul. IN ANY ;; ANSWER SECTION: web-frontend.service.consul. 0 IN A 10.0.3.83 web-frontend.service.consul. 0 IN A 10.0.1.109
  10. Server Service A Server Service B Service C Service C

    Load balancer Consul Template Load balancer Consul Template
  11. web server http service http service http service http service

    create unique trace_id for request user request trace_id trace_id trace_id trace_id log log log log log
  12. Service A Service B Error Circuit Breaker Status: -> open

    Error rate: > threshold Test if still failing
  13. Service A Service B 200 OK Circuit Breaker Status: ->

    close Error rate: 0 Test if still failing
  14. Service A Service B Circuit Breaker Service C Circuit Breaker

    100% of calls wait until everything is ok