10. Map calls User over the network
What can possibly go wrong?
11. Map calls User
What can possibly go wrong?
1. Connection refused
2. Slow answer
3. Veery slow answer (=never)
4. The result causes an exception in
the client library
12. Map calls User
What can possibly go wrong?
1. Connection refused => < 2 ms
2. Slow answer => 5 s
3. Veery slow answer => timeout
4. The result causes an exception in
the client library => depends
13. Map calls User
What can possibly go wrong?
1. Connection refused => < 2 ms
2. Slow answer => 5 s
3. Veery slow answer => timeout
4. The result causes an exception in
the client library => depends
Fails quickly
14. Map calls User
What can possibly go wrong?
1. Connection refused => < 2 ms
2. Slow answer => 5 s
3. Veery slow answer => timeout
4. The result causes an exception in
the client library => depends
May kill both
the server and
the client
15. Map calls User
Let’s assume:
Thread pr request
Response time - 4 s
Map has 60 req/s.
Fan-out to User is 2 => 120 req/s
240 / 480 threads blocking
16. mobilewebN has 130 req/s
Let’s assume:
Thread pr request
RandomApp has 130 req/s.
Fan-out to service is 2 => 260 req/s
520 / 1040 threads blocking
17. What happens in an app with 500 blocking threads?
Not much. Besides waiting. CPU is idle.
If maximum-threads == 500
=> no more connections are allowed
And what about 1040 occupied threads?
18. And where is the user after 8 s?
At Youtube, Facebook or searching for cute
kittens.
19. The problem we try to solve
An application with 30 dependent services - with 99.99%
uptime for each service
99.99^30 = 99.7% uptime
0.3% of 1 billion requests = 3,000,000 failures
2+ hours downtime/month even if all dependencies have excellent uptime.
98%^30 = 54% uptime
99.99% = 8 sec a day; 99.7% 4 min pr day;
20. Agenda
Why?
Tolerance for failure - How?
How to create a Hystrix Command
Monitoring and Dashboard
Examples from finn
One step further
21. Control over latency and failure from dependencies
Stop cascading failures in a complex distributed system.
Fail fast and rapidly recover.
Fallback and gracefully degrade when possible.
Enable near real-time monitoring, alerting
What is Hystrix for?
22. Fail fast - don’t let the user wait!
Circuit breaker - don’t bother, it’s
already down
Fallback - can you give a sensible
default, show stale data?
Bulkhead - protect yourself
against cascading failure
Principles
23. How?
Avoid any single dep from using up all threads
Shedding load and failing fast instead of queueing
Providing fallbacks wherever feasible
Using isolation techniques (such as bulkhead, swimlane,
and circuit breaker patterns) to limit the impact of any one
dependency.
24. Two different ways of isolation
Semaphore
“at most 5 concurrent calls”
only for CPU-intensive, local calls
Thread pool (dedicated couriers)
the call to the underlying service is handled by a pool
overhead is usually not problematic
default approach
26. Dependencies
Depends on
rxjava
archaius (& commons-configuration)
FINN uses Constretto for configuration
management, hence:
https://github.com/finn-no/archaius-constretto
27. Dependencies
There are useful addons:
hystrix-metrics-event-stream - json/http
stream
hystrix-codahale-metrics-publisher (currently
io.dropwizard.metrics)
(Follows the recent trend of really splitting up the dependencies - include only what you need)
28. Default properties
Quite sensible, “fail fast”
Do your own calculations of
number of concurrent requests
timeouts (99.8 percentile)
...by looking at your current performance
(latency) pr request and add a little buffer
34. How to create a Hystrix Command
A command class wrapping the “risky”
operation.
- must implement run()
- might implement fallback()
Since version 1.4 Observable implementation
also available
57. Metrics
Circuit breaker open?
Calls pr. second
Execution time?
Median, 90th, 95th and
99th percentile
Status of thread pool?
Number of clients in
cluster
70. Request Collapsing - why
decouples client model from server interface
reduces network overhead
client container/thread batches requests
71.
72. Request Collapsing
create two commands
Collapser
one new() pr client request
BatchCommand
one new() pr server request
73. Request Collapsing
Integrate two commands in two methods
createCommand()
Create batchCommand from a list of
singlecommands
mapResponseToRequests()
Map listResponse to single resposes
80. Request Collapsing - experiences
Each individual request will be slower for the
client, is that ok?
10 ms operation into 100 ms window
Max 110 ms for client
Average 60 ms
Read documentation first!!
81. Examples from Finn - Code
Fetch a map point
Fetch Several Profiles using collapsing
Operations
82. Example from Finn - Operations
[2015-06-31T13:37:00,485]
[ERROR] Forwarding to error page from request
due to exception
[AdCommand short-circuited and no fallback available.]
com.netflix.hystrix.exception.HystrixRuntimeException:
RecommendMoreLikeThisCommand short-circuited and no fallback available.
at com.netflix.hystrix.AbstractCommand$16.call
(AbstractCommand.java:811)
83. Error happens in production
Operations gets paged with lots of error
messages in logs
They read the logs
Lots or [ERROR]
They restart the application
84. Learnings - operations
Error messages means different things with
Hystrix
What they say, not where they occur
Built in error recovery with circuit breaker
Operations reads logs, not hystrix dashboard
Lots of unnecessary restarts
93. Experiences from FINN
Hystrix standardises things we did before:
Nitty gritty http-client stuff
Timeouts
Connection pools
Tuning thread pools
Dashboards
Metrics
94. Wrap up
Should you start using Hystrix?
- Bulkhead and circuit-breaker - explicit timeout and error
handling is useful
- Dashboards
Further reading
Ben Christensen, GOTO Aarhus 2013 - https://www.youtube.com/watch?v=_t06LRX0DV0
Updated for QConSF2014; https://qconsf.com/system/files/presentation-slides/ReactiveProgrammingWithRx-QConSF-
2014.pdf
Thanks for listening!
audun.fauchald.strand@finn.no & henning.spjelkavik@finn.no
I 2002 lanserte Bill Gates fase to av den visjonære dot-Net-strategien - hvor barrierer mellom systemer, organisasjoner og mennesker skulle brytes ned - via XML webtjenester! Allerede i 1996 lekte vi med socket programmering, men var noe nede, så virket vel ikke websiden. Kunne jeg ha gjort noe annerledes?
Noe senere, et stykke ut på 2000-tallet lanserte FINN kanskje Norges ledende løsninger på flysøk og kart - begge var avhengig av å snakke med eksterne systemer, og gjøre noe fornuftig om de ikke virket.
For å ha kontroll på ytelse og stabilitet hadde vi masse kode for å telle, måle ytelse, håndtere timeout og andre typer feil. En frekk sjel ville kanskje våget seg til å påstå at noe av det vi gjorde kunne ligne på - godt kokt spaghetti.
https://en.wikipedia.org/wiki/Bill_Gates#/media/File:Bill_Gates_mugshot.png
Dessverre lagde vi aldri gode abstraksjoner av dette, slik at vi kunne bli berømte. Det har derimot Netflix gjort.
https://flic.kr/p/cwHz9G
Slik kunne kode for å slå opp høyden gitt et punkt ha sett ut, i en adapter klasse mot SOAP-tjenesten.
Metoden “altitude” ringer til en ekstern leverandør, og leverer resultatet hvis internett er med oss.
Med Hystrix pakker vi dette inn i en Command, og får litt mer kode - men mange fordeler.
Constructor - har litt oppsett
To interessante metoder: run som gjør det samme som før, og getFallback - hvor du eksplisitt må ta stilling til hva som skjer ved en feilsituasjon.
Vi som presenterer er:
Audun - Lead developer Infrastructure, Travel, Telenor, NAV og slikt
Henning - arkitektur, ytelse, debugging og kart på FINN, epostadresse siden 1995, drev Skiinfo fra 1996
Start with why!
HS;
A property of a microservices architecture, is that different processes call each other. Like in this simple example…
grenser mellom systemene
Hva skjer når noe går ned? - siden du er her … så har du forhåpentlig tenkt at det er noe som bare skjer.
Let’s give them names.
Hvorfor kan dette gå galt? Han står jo feil vei!
Let’s give them names.
Traditional servlet API; i.e tomcat, resin, jetty.
NodeJs, Netty etc does not have a thread pr request.
Stabil situasjon: 240 på Map; 480 på User
Many would say: “Use node”; (or actually an event loop, or C select loop instead of a thread-pr-request-model) still fails from a user perspective. We’ve just made the parking lot bigger.
And where is the user after 8 s waiting?
https://www.flickr.com/photos/crsan/2571204698/
Eller noe enda verre.
(nei, vi viser IKKE twitter-feeden til @aphyr)
Reality is generally worse..
Even when all dependencies perform well the aggregate impact of even 0.01% downtime on each of dozens of services equates to potentially hours a month of downtime if you do not engineer the whole system for resilience.
Hva gir det oss - hvilke fordeler får vi?
Give protection from and control over latency and failure from dependencies accessed (typically over the network) via third-party client libraries.
cascade = forplanter seg
Bulk head - how you divide a ship into watertight compartments, so that one damage to the hull won’t sink the ship.
vanntette skott
=> begrenset “blast”-radius
Preventing any single dependency from using up all container (such as Tomcat) user threads.
“Rimi ved skolen”
Maintaining a small thread-pool (or semaphore) for each dependency; if it becomes full, requests destined for that dependency will be immediately rejected instead of queued up.
Dedikert antall tråder. Maksimal tid -timeout.
Tidligere skyarkitekt i Netflix - Adrian Cockcroft - gav denne boken til en utvikler på Netflix.
https://flic.kr/p/bo7b9
number of concurrent requests; small percentage of total available threads. calculate the resources available. As small as possible.
“requests per second at peak when healthy × 99th percentile latency in seconds + some breathing room”
timeouts - look at your existing 99+ percentile.
for eksempel - hvordan beregne antall tråder
Audun!
Switch to Audun;
Splitte opp monoiltten
Fortsatt feilet hele finn, når enkeltdeler gikk ned
Ekspriment i noen deler, så presentasjon for alle 130 utviklere
Se på koden og ting som har skjedd i finn
Hva har vi gjort og hva har vi lært
alle eksempler er fra finn og har kjørt i finn, noen har til og med tatt ned finn.no ,
MEN
Hystrix handler ikke så mye om kode, det handler mere om overvåkning, monitorering, dokumentasjon og drift
Vi skal likevel begynne med litt enkel kode
Reactive Streams RxJava
Først skal vi bare se på koden
Mye mere kode
Command pattern - Gof
Innkapsle alt som trengs for å utføre en operasjon.
De fleste utviklerne i finn har spurt om dette, da Henning og jeg begynte å snakke om Hystrix
https://flic.kr/p/fjFS1y
Vise risiko
Grense til eksterne systemer
Grenser mellom feilkilder
antitesen til distribuerte objekter (EJB Corba)
Gamle dager: remote og lokalt var likt, fortsatt mulig å gjøre det slik i dag.
Mstridende ønsker: Skille integrasjonslogikk of forretningslogikk. ‘
Men noen ganger er integrasjonslogikk relevant for forretningslogiikk.
Fallback verdier
Gå gjennom flyten som skjer når man oppretter og eksekverere en kommando
New
Hvordan skal man eksekvere kommandoe
Har sikringa gått
er det noen tråder som kan gjøre jobben
Bulkheads
Gjør det man skal
Fikk svar ok
Returnerer svar
Hele tiden så kalkulerer man
Dette er magien
Før man gjør kallet, så returnerer man
Kanskje kommer serveren til å ta seg inn igjen
Fallback verdier på timeout eller feil fra server
Hva er fallback
Cachet verdier (Stale)
Dummy verdier
Tomme lister
Anbefalte annonser -> statisk liste av populære annonser
Målinger fra finn har vist at det noen ganger er bedre enn fancy algoritmer
Ikke noe fallback
Ok fallback
Fallback kan tryne
Circuit health kalkulerers alltid
Veldig mye gratis her
gamle dager http klient og client pool
Instrumenterbare http klienter
Mister serialisering og data trans om man innkapsler hele operasjonen
Finn bruker statsd
Metrics kan enkelt kobles til statsd og graphite med et finn bibliotek
Grafer på dashboard
Metrics
Størrelse på sirkel angir mengde
Graf gir utvikling
Persentiler er det som gjelder
Snitt er gammeldags
Circuit Breaker
Logisk navn samler info på tvers av instanser
Bulkheads og Semafor
Simple operation
Synchronous execution
Hidden behind existing method
GroupKey
Fallback value indicates error
Reason of error not propagated
Graceful degredation
Får
circuit breaker
Dashboard
Bulkheads
får ikke
asynkronitet
Komplisert bruk av Hystrix
database, less overhead
network, less overhead
global or pr thread
Creates a batch command from all collapsed requests
default vindu er 10
Hystrix gjør at systemet oppfører seg annerledes når noe går galt
Best place for concurrency
Bulkheads at right level
Operations must be involved and understand Hystrix
Errors effects the circtuitbreaker
404
Hvis du vil få betalt for å utvikle Hystrix så søker Edge Api teamet til ben Christensen etter folk som kan jobbe i San Jose i Calfornia. Hvis ikke kan du….