close
close

Health checks in ASP.NET Core for .NET Microservices with Actuator

In a microservices architecture, keeping every service running and in good condition is critical to maintaining the overall reliability of the system. Actuator, a library inspired by Spring Boot Actuator, can be used to expose operational information about an application running in production. This guide describes how to implement health checks for two .NET microservices, Product and Order Services, using Actuator.

Set up actuator in ASP.NET Core

Actuator in the context of .NET is typically managed through libraries such as AspNetCore.Diagnostics.HealthChecks provides various implementations and functions for health checks.

1. Create product and order services

Suppose you already have two microservices: Product and Order. We will add health checks with Actuator-like features to these services.

2. Install the required packages

First install the necessary NuGet packages for health checks.

dotnet add package AspNetCore.HealthChecks.UI
dotnet add package AspNetCore.HealthChecks.UI.Client
dotnet add package AspNetCore.HealthChecks.UI.InMemory.Storage
dotnet add package AspNetCore.HealthChecks.SqlServer
Go to full screen mode

Exit full screen mode

3. Configure health checks in Startup.cs

Configure health checks in each service in the Startup.cs file.

Product service

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllers();

        // Add health checks
        services.AddHealthChecks()
                .AddCheck("self", () => HealthCheckResult.Healthy())
                .AddSqlServer(Configuration.GetConnectionString("ProductDatabase"), name: "ProductDB-check");

        // Add HealthChecks UI
        services.AddHealthChecksUI()
                .AddInMemoryStorage();
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseRouting();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();

            // Map health checks
            endpoints.MapHealthChecks("/health", new HealthCheckOptions()
            {
                Predicate = _ => true,
                ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
            });

            // Map HealthChecks UI
            endpoints.MapHealthChecksUI(setup => setup.UIPath = "/health-ui");
        });
    }
}
Go to full screen mode

Exit full screen mode

Order service

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllers();

        // Add health checks
        services.AddHealthChecks()
                .AddCheck("self", () => HealthCheckResult.Healthy())
                .AddSqlServer(Configuration.GetConnectionString("OrderDatabase"), name: "OrderDB-check");

        // Add HealthChecks UI
        services.AddHealthChecksUI()
                .AddInMemoryStorage();
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseRouting();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();

            // Map health checks
            endpoints.MapHealthChecks("/health", new HealthCheckOptions()
            {
                Predicate = _ => true,
                ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
            });

            // Map HealthChecks UI
            endpoints.MapHealthChecksUI(setup => setup.UIPath = "/health-ui");
        });
    }
}
Go to full screen mode

Exit full screen mode

4. Conduct health checks and testing

Run the services and test the health check endpoints.

  • For product service

  • For ordering service

Port number (80) should be replaced with your port numbers.
You should see a JSON response indicating the status of the service on the /health endpoint, and a detailed user interface on the /health-ui endpoint.

5. Merge health checks with Kubernetes or Docker

When deploying to Kubernetes or Docker, you can use readiness and liveness testing to ensure your services are up to par.

Kubernetes example

apiVersion: apps/v1
kind: Deployment
metadata:
  name: product-service
spec:
  replicas: 1
  selector:
    matchLabels:
      app: product-service
  template:
    metadata:
      labels:
        app: product-service
    spec:
      containers:
        - name: product-service
          image: your-docker-image
          ports:
            - containerPort: 80
          readinessProbe:
            httpGet:
              path: /health
              port: 80
            initialDelaySeconds: 5
            periodSeconds: 10
          livenessProbe:
            httpGet:
              path: /health
              port: 80
            initialDelaySeconds: 5
            periodSeconds: 10
Go to full screen mode

Exit full screen mode

Conclusion

Implementing health checks in ASP.NET Core for microservices such as Product and Order Services is simple and improves the reliability of your system. By configuring health checks and a health check user interface, you can effectively monitor the health of your services. Integrating this setup with orchestration tools such as Kubernetes further ensures robust deployment strategies and the smooth functioning of your microservices architecture.

🔥Don’t miss it! Discover more exciting bytes here! 🔍https://linktr.ee/dotnetfullstackdev and dive into the content!