Socialize

Saturday, October 18, 2025

๐Ÿงช Practical Example — Implementing Resilience in .NET Core Using Polly

 ๐Ÿ—️ Scenario

Let’s say we have a microservice called OrderService that needs to call another service — PaymentService — through an HTTP API.
We want to make sure our OrderService:

  • Retries if the call fails (Retry Pattern)

  • Stops repeated failing calls (Circuit Breaker Pattern)

  • Times out long requests (Timeout Pattern)

  • Returns fallback data if all else fails (Fallback Pattern)


๐Ÿงฐ Step 1: Install Required Package

Run this command in your OrderService project:

dotnet add package Polly dotnet add package Microsoft.Extensions.Http.Polly

⚙️ Step 2: Configure Resilience Policies in Program.cs

using Polly; using Polly.Extensions.Http; var builder = WebApplication.CreateBuilder(args); // Define resilience policies var retryPolicy = HttpPolicyExtensions .HandleTransientHttpError() .WaitAndRetryAsync(3, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt))); // exponential backoff var circuitBreakerPolicy = HttpPolicyExtensions .HandleTransientHttpError() .CircuitBreakerAsync(5, TimeSpan.FromSeconds(30)); // break after 5 failures var timeoutPolicy = Policy.TimeoutAsync<HttpResponseMessage>(3); // 3-second timeout // Add HttpClient with resilience policies builder.Services.AddHttpClient("PaymentServiceClient", client => { client.BaseAddress = new Uri("https://payments.example.com/api/"); }) .AddPolicyHandler(retryPolicy) .AddPolicyHandler(circuitBreakerPolicy) .AddPolicyHandler(timeoutPolicy); builder.Services.AddControllers(); var app = builder.Build(); app.MapControllers(); app.Run();

๐Ÿ’ก Step 3: Use HttpClient in Controller

using Microsoft.AspNetCore.Mvc; [ApiController] [Route("api/[controller]")] public class OrderController : ControllerBase { private readonly HttpClient _httpClient; public OrderController(IHttpClientFactory httpClientFactory) { _httpClient = httpClientFactory.CreateClient("PaymentServiceClient"); } [HttpPost("create")] public async Task<IActionResult> CreateOrder([FromBody] object order) { try { var response = await _httpClient.PostAsJsonAsync("process", order); if (response.IsSuccessStatusCode) return Ok("Order placed successfully!"); return StatusCode((int)response.StatusCode, "Payment service failed."); } catch (BrokenCircuitException) { // Circuit breaker is open, fallback response return StatusCode(503, "Payment service temporarily unavailable. Try again later."); } catch (Exception ex) { // Fallback or logging return StatusCode(500, $"Unexpected error: {ex.Message}"); } } }

๐Ÿ” Step 4: Add Health Check for Kubernetes or Azure

Add in Program.cs:

builder.Services.AddHealthChecks(); app.MapHealthChecks("/health");

✅ This allows Kubernetes or Azure App Service to detect and restart unhealthy instances automatically.


๐Ÿ“Š Step 5: Add Observability (Optional)

Integrate Application Insights, Serilog, or ELK Stack to monitor:

  • Retry attempts

  • Circuit breaker states

  • Timeout events

This helps detect performance or availability issues early.


๐Ÿง  Output Behavior Summary

Failure TypePattern TriggeredSystem Reaction
Temporary network errorRetryAutomatically retries
Persistent downstream failureCircuit BreakerBlocks further calls temporarily
Long responseTimeoutCancels request after 3 seconds
Service completely downFallbackReturns cached/default message
Pod unhealthyHealth CheckAuto restarted by Kubernetes

๐Ÿš€ Result

With these configurations:

  • Your microservices become self-healing.

  • You prevent cascading failures.

  • The system delivers consistent performance and high availability.

Pro Tip: Combine Polly with Serilog for logging and OpenTelemetry for tracing to create a fully observable resilient microservice system.

No comments:

Blog Archive

Don't Copy

Protected by Copyscape Online Plagiarism Checker

Pages