Mønster: Kretsbryter
Kontekst
Du har brukt Microservice-arkitekturen.Tjenester samarbeider noen ganger når du håndterer forespørsler.Når en tjeneste synkront påkaller en annen, er det alltid mulighet for at den andre tjenesten er utilgjengelig eller har så høy ventetid, det er i hovedsak ubrukelig.Verdifulle ressurser som tråder kan brukes i den som ringer mens du venter på at den andre tjenesten skal svare.Dette kan føre til ressursutmattelse, noe som gjør at anropstjenesten ikke kan håndtere andre forespørsler.Svikt i en tjeneste kan potensielt kaskade til andre tjenester i hele programmet.
Problem
hvordan forhindre at et nettverk eller tjenestefeil faller til andre tjenester?
Løsning
en tjenesteklient bør starte en ekstern tjeneste via en proxy som fungerer på samme måte som en elektrisk bryter.Når antall påfølgende feil krysser en terskel, bryter bryteren, og i løpet av en tidsavbruddsperiode mislykkes alle forsøk på å påkalle den eksterne tjenesten umiddelbart.Etter tidsavbrudd utløper bryteren tillater et begrenset antall testforespørsler å passere gjennom.Hvis disse forespørslene lykkes, fortsetter bryteren normal drift.Ellers, hvis det er en feil timeout perioden begynner igjen.
Eksempel
RegistrationServiceProxy
Fra Microservices-Eksempelprogrammet er et eksempel på en komponent, som er skrevet I Scala, som bruker en bryter til å håndtere feil ved påkalling av en ekstern tjeneste.
@Componentclass RegistrationServiceProxy @Autowired()(restTemplate: RestTemplate) extends RegistrationService { @Value("${user_registration_url}") var userRegistrationUrl: String = _ @HystrixCommand(commandProperties=Array(new HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds", value="800"))) override def registerUser(emailAddress: String, password: String): Either = { try { val response = restTemplate.postForEntity(userRegistrationUrl, RegistrationBackendRequest(emailAddress, password), classOf) response.getStatusCode match { case HttpStatus.OK => Right(response.getBody.id) } } catch { case e: HttpClientErrorException if e.getStatusCode == HttpStatus.CONFLICT => Left(DuplicateRegistrationError) } }}
@HystrixCommand
ordner for samtaler til registerUser()
som skal utføres ved hjelp av en bryter.
effektbryterfunksjonen er aktivert ved hjelp av @EnableCircuitBreaker
– merknaden i UserRegistrationConfiguration
– klassen.
@EnableCircuitBreakerclass UserRegistrationConfiguration {
Resulterende Kontekst
dette mønsteret har følgende fordeler:
- Tjenester håndterer feilen i tjenestene de påberoper
dette mønsteret har følgende problemer:
- det er utfordrende å velge timeout verdier uten å skape falske positiver eller innføre overdreven ventetid.
- Microservice-Chassiset kan implementere dette mønsteret
- EN API-Gateway vil bruke dette mønsteret til å påkalle tjenester
- en ruter på serversiden kan bruke dette mønsteret til å påkalle tjenester
Se også
- Netflix Hystrix er et eksempel på et bibliotek som implementerer dette mønsteret