In a microservices architecture, ensuring that each service is running and healthy is crucial for maintaining the overall system's reliability. Actuator, a library inspired by Spring Boot Actuator, can be used to expose operational information about an application running in production. This guide will walk through the implementation of health checks for two .NET microservices, Product and Order services, using Actuator.
Setting Up Actuator in ASP.NET Core
Actuator in the context of .NET is typically managed through libraries like AspNetCore.Diagnostics.HealthChecks offers various health check implementations and features.
1. Create Product and Order Services
Assume you already have two microservices: Product and Order. We'll add health checks using Actuator-like features to these services.
2. Install 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
3. Configure Health Checks in Startup.cs
In each service, configure health checks 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");
});
}
}
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");
});
}
}
4. Run and Test Health Checks
Run the services and test the health check endpoints.
- For Product Service
- Health Check: http://localhost:<port>/health
- Health Check UI: http://localhost:<port>/health-ui
- For Order Service
- Health Check: http://localhost:<port>/health
- Health Check UI: http://localhost:<port>/health-ui
You should see a JSON response indicating the health status of the service on the /health endpoint and a detailed UI on the /health-ui endpoint.
5. Aggregating Health Checks with Kubernetes or Docker
When deploying to Kubernetes or Docker, you can use readiness and liveness probes to ensure that your services are healthy.
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
Conclusion
Implementing health checks in ASP.NET Core for microservices like Product and Order services is straightforward and enhances the reliability of your system. By configuring health checks and a health check UI, you can monitor the status of your services effectively. Integrating this setup with orchestration tools like Kubernetes further ensures robust deployment strategies and the smooth operation of your microservices architecture.