The API gateway Ocelot uses Polly to handle some failures.

Source: Internet
Author: User

The API gateway Ocelot uses Polly to handle some failures.

In the process of implementing the API Gateway, another issue that needs to be considered is part of failure. This problem occurs in distributed systems when one service calls another service and times out or is unavailable. API Gateway should not be blocked and wait for downstream services indefinitely. However, how to handle such failures depends on specific scenarios and specific services. If the product information service does not respond, the API Gateway should return an error to the client.

Ocelot is an API Gateway on the. NET Core platform. Recently, I was involved in the development of this project. The first one after development was completed was to use Polly to handle some failures. You may not be familiar with the Polly project. First, I would like to briefly introduce Polly, an open-source project under the. NET Foundation. Polly records calls that exceed the predefined limit. It implements the circuit break model, allowing the client to stop from the endless waiting of the unresponsive service. If the error rate of a service exceeds the preset value, Polly will interrupt the service and all requests expire immediately within a period of time. Polly can define a fallback operation for request failure, for example, read the cache or return the default value, sometimes we need to call other APIs when there is a temporary connection failure timeout, then you can also perform Retry through Polly, specific information refer to the http://www.thepollyproject.org/2016/10/25/polly-5-0-a-wider-resilience-framework.

In terms of implementation, Ocelot is a series of middleware combinations. When an HTTP request arrives at Ocelot, it is processed by a series of middleware and forwarded to downstream services. The middleware responsible for invoking downstream services is HttpRequestBuilderMiddleware, by calling HttpClient request downstream HTTP service, we here is to call the HttpClient with the fuse function, Code refer to the https://github.com/TomPallister/Ocelot/pull/27/files, the main part of the code is as follows:

using Ocelot.Logging;using Polly;using Polly.CircuitBreaker;using Polly.Timeout;using System;using System.Net;using System.Net.Http;using System.Threading;using System.Threading.Tasks;namespace Ocelot.Requester{    public class CircuitBreakingDelegatingHandler : DelegatingHandler    {        private readonly IOcelotLogger _logger;        private readonly int _exceptionsAllowedBeforeBreaking;        private readonly TimeSpan _durationOfBreak;        private readonly Policy _circuitBreakerPolicy;        private readonly TimeoutPolicy _timeoutPolicy;        public CircuitBreakingDelegatingHandler(int exceptionsAllowedBeforeBreaking, TimeSpan durationOfBreak,TimeSpan timeoutValue            ,TimeoutStrategy timeoutStrategy, IOcelotLogger logger, HttpMessageHandler innerHandler)            : base(innerHandler)        {            this._exceptionsAllowedBeforeBreaking = exceptionsAllowedBeforeBreaking;            this._durationOfBreak = durationOfBreak;            _circuitBreakerPolicy = Policy                .Handle<HttpRequestException>()                .Or<TimeoutRejectedException>()                .Or<TimeoutException>()                .CircuitBreakerAsync(                    exceptionsAllowedBeforeBreaking: exceptionsAllowedBeforeBreaking,                    durationOfBreak: durationOfBreak,                    onBreak: (ex, breakDelay) =>                    {                        _logger.LogError(".Breaker logging: Breaking the circuit for " + breakDelay.TotalMilliseconds + "ms!", ex);                    },                    onReset: () => _logger.LogDebug(".Breaker logging: Call ok! Closed the circuit again."),                    onHalfOpen: () => _logger.LogDebug(".Breaker logging: Half-open; next call is a trial.")                    );            _timeoutPolicy = Policy.TimeoutAsync(timeoutValue, timeoutStrategy);            _logger = logger;        }        protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)        {            Task<HttpResponseMessage> responseTask = null;            try            {                responseTask = Policy.WrapAsync(_circuitBreakerPolicy, _timeoutPolicy).ExecuteAsync<HttpResponseMessage>(() =>                {                    return  base.SendAsync(request,cancellationToken);                });                return responseTask;            }            catch (BrokenCircuitException ex)            {                _logger.LogError($"Reached to allowed number of exceptions. Circuit is open. AllowedExceptionCount: {_exceptionsAllowedBeforeBreaking}, DurationOfBreak: {_durationOfBreak}",ex);                throw;            }            catch (HttpRequestException)            {                return responseTask;            }        }        private static bool IsTransientFailure(HttpResponseMessage result)        {            return result.StatusCode >= HttpStatusCode.InternalServerError;        }    }}

The above Code uses Policy. wrapAsync combines the fuse and retry policies to solve some of the failures. The idea is very simple. It defines the exceptions to be handled, such as the Policy. handle <HttpRequestException> (). or <TimeoutRejectedException> (). or <TimeoutException> (). When an exception occurs, use the fuse Or try again. The above code is also suitable for calling third-party services.

Welcome to join the construction of the. NET Core microservice development framework. Starting from the Ocelot thumb up and fork code for the project, I have contributed two feature codes, service discovery, and fuse described in this article to the project during the Spring Festival.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.