
We will start a new journey with this course. You can overview the journey with following the medium articles that I shared the link with this video.
Identify prerequisites for the microservices course, clarifying that you don't need prior knowledge of cross-cutting concerns, and outline starting points with the AspnetMicroservices base repository, tools, and setup from scratch.
Docker Commands
docker-compose -f docker-compose.yml -f docker-compose.override.yml up -d
docker-compose -f docker-compose.yml -f docker-compose.override.yml up --build
docker-compose -f docker-compose.yml -f docker-compose.override.yml down
You can launch microservices as below urls:
Catalog API -> http://host.docker.internal:8000/swagger/index.html
Basket API -> http://host.docker.internal:8001/swagger/index.html
Discount API -> http://host.docker.internal:8002/swagger/index.html
Ordering API -> http://host.docker.internal:8004/swagger/index.html
Shopping.Aggregator -> http://host.docker.internal:8005/swagger/index.html
API Gateway -> http://host.docker.internal:8010/Catalog
Rabbit Management Dashboard -> http://host.docker.internal:15672 -- guest/guest
Portainer -> http://host.docker.internal:9000 -- admin/admin1234
pgAdmin PostgreSQL -> http://host.docker.internal:5050 -- admin@aspnetrun.com/admin1234
Elasticsearch -> http://host.docker.internal:9200 -- To Be Develop
Kibana -> http://host.docker.internal:5601 -- To Be Develop
Web Status -> http://host.docker.internal:8007 -- To Be Develop
Web UI -> http://host.docker.internal:8006
Launch http://host.docker.internal:8007 in your browser to view the Web Status. Make sure that every microservices are healthy.
Launch http://host.docker.internal:8006 in your browser to view the Web UI. You can use Web project in order to call microservices over API Gateway. When you checkout the basket you can follow queue record on RabbitMQ dashboard.
Docker Commands
docker-compose -f docker-compose.yml -f docker-compose.override.yml up -d
docker-compose -f docker-compose.yml -f docker-compose.override.yml up --build
docker-compose -f docker-compose.yml -f docker-compose.override.yml down
You can launch microservices as below urls:
Catalog API -> http://host.docker.internal:8000/swagger/index.html
Basket API -> http://host.docker.internal:8001/swagger/index.html
Discount API -> http://host.docker.internal:8002/swagger/index.html
Ordering API -> http://host.docker.internal:8004/swagger/index.html
Shopping.Aggregator -> http://host.docker.internal:8005/swagger/index.html
API Gateway -> http://host.docker.internal:8010/Catalog
Rabbit Management Dashboard -> http://host.docker.internal:15672 -- guest/guest
Portainer -> http://host.docker.internal:9000 -- admin/admin1234
pgAdmin PostgreSQL -> http://host.docker.internal:5050 -- admin@aspnetrun.com/admin1234
Elasticsearch -> http://host.docker.internal:9200 -- To Be Develop
Kibana -> http://host.docker.internal:5601 -- To Be Develop
Web Status -> http://host.docker.internal:8007 -- To Be Develop
Web UI -> http://host.docker.internal:8006
Launch http://host.docker.internal:8007 in your browser to view the Web Status. Make sure that every microservices are healthy.
Launch http://host.docker.internal:8006 in your browser to view the Web UI. You can use Web project in order to call microservices over API Gateway. When you checkout the basket you can follow queue record on RabbitMQ dashboard.
Introduction - Distributed Logging with Elastic Stack (Elasticsearh + Logstach + Kibana and SeriLog)
Elasticsearch enables distributed logging and fast, near real-time full-text search for microservices, with a RESTful API, built on Lucene, and easy Docker deployment.
Learn how Kibana provides visualization for Elasticsearch data and how SeriLog enables logging in ASP.NET Core microservices with sinks like file, SQL, and Elasticsearch.
Start Docker compose :
docker-compose -f docker-compose.yml -f docker-compose.override.yml up -d
docker-compose -f docker-compose.yml -f docker-compose.override.yml down
Learn ASP.NET log levels and log filtering using application settings json, covering trace to none, and configure defaults to filter http client logs and capture exceptions.
Adding ElasticSearch and Kibana image into Docker-Compose File for Multi-Container Docker Environment
-- Now we can add ElasticSearch and Kibana image into our docker-compose.yml files
docker-compose.yml
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:7.9.2
kibana:
image: docker.elastic.co/kibana/kibana:7.9.2
volumes:
mongo_data:
portainer_data:
postgres_data:
pgadmin_data:
elasticsearch-data: --------------> ADDED
-- added 2 image, 1 volume
---
docker-compose.override.yml
elasticsearch:
container_name: elasticsearch
environment:
- xpack.monitoring.enabled=true
- xpack.watcher.enabled=false
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
- discovery.type=single-node
ports:
- "9200:9200"
volumes:
- elasticsearch-data:/usr/share/elasticsearch/data
kibana:
container_name: kibana
environment:
- ELASTICSEARCH_URL=http://localhost:9200
depends_on:
- elasticsearch
ports:
- "5601:5601"
-- added elasticsearch and kibana
-- We set elasticsearch and kibana configuration as per environment variables.
Open In Terminal
RUN with below command on that location;
docker-compose -f docker-compose.yml -f docker-compose.override.yml up -d
docker-compose -f docker-compose.yml -f docker-compose.override.yml down
Go to -> AspnetRunBasics
Install Packages
Install-Package Serilog.AspNetCore
Install-Package Serilog.Enrichers.Environment
Install-Package Serilog.Sinks.Elasticsearch
Check item group project file
<ItemGroup>
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.10.9" />
<PackageReference Include="Serilog.AspNetCore" Version="3.4.0" />
<PackageReference Include="Serilog.Enrichers.Environment" Version="2.1.3" />
<PackageReference Include="Serilog.Sinks.Elasticsearch" Version="8.4.1" />
</ItemGroup>
Configure SeriLog
After that, we will configure logging in Program.cs by adding the following details on Main method.
AspnetRunBasics
Program.cs -- UseSerilog --- ADDED
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseSerilog((context, configuration) =>
{
configuration
.Enrich.FromLogContext()
.Enrich.WithMachineName()
.WriteTo.Console()
.WriteTo.Elasticsearch(
new ElasticsearchSinkOptions(new Uri(context.Configuration["ElasticConfiguration:Uri"]))
{
IndexFormat = $"applogs-{Assembly.GetExecutingAssembly().GetName().Name.ToLower().Replace(".", "-")}-{context.HostingEnvironment.EnvironmentName?.ToLower().Replace(".", "-")}-logs-{DateTime.UtcNow:yyyy-MM}",
AutoRegisterTemplate = true,
NumberOfShards = 2,
NumberOfReplicas = 1
})
.Enrich.WithProperty("Environment", context.HostingEnvironment.EnvironmentName)
.ReadFrom.Configuration(context.Configuration);
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
-- We have configured Serilog according to writing Console and Elastic Search. When Configure for the Elastic Search we provide some sink options.
Test SeriLog For ElasticSearch and Kibana Sink Integration in Shopping Web Microservices
Create SeriLog Common Logging Library For ElasticSearch and Kibana Sink Integration to All Microservices
Adding SeriLog Common Logging Library Project References to Aspnetrun Shopping Web Application
Adding LoggingDelegatingHandler for Intercepting Microservices Request-Response Logging on ElasticSearch and Kibana
Adding SeriLog for Shopping.Aggregator Microservices for Logging on ElasticSearch and Kibana
Adding SeriLog for Catalog.API Microservices for Logging on ElasticSearch and Kibana
Adding SeriLog for Basket.API Microservices for Logging on ElasticSearch and Kibana
Adding SeriLog for Discount.API Microservices for Logging on ElasticSearch and Kibana
Adding SeriLog for Discount.Grpc Microservices for Logging on ElasticSearch and Kibana
Adding SeriLog for Ordering.API Microservices for Logging on ElasticSearch and Kibana
Adding SeriLog for OcelotApiGw Microservices for Logging on ElasticSearch and Kibana
Containerize All Microservices with SeriLog using Docker Compose for Logging on ElasticSearch and Kibana
Containerize All Microservices with SeriLog using Docker Compose for Logging on ElasticSearch and Kibana Part 2
Test on Docker environment - SeriLog Microservices into Docker Compose for Logging on ElasticSearch and Kibana
Develop resilience and fault tolerance for distributed microservices by applying retry and circuit-breaker patterns with Polly across service communications and database migrations via the Ocelot API gateway.
Explore microservices resilience patterns and how Polly implements retry, circuit breaker and timeout policies to ensure durable, uninterrupted service in distributed architectures.
Apply the retry pattern to microservices communication to recover from transient failures, using exponential back-off to retry failed http 500 or gRPC calls through the api gateway until success.
Discover the circuit breaker pattern in .NET microservices, monitoring inter-service calls, opening after failures, and using Polly to manage open, half-open, and closed states.
Apply the bulkhead pattern to isolate failing services and protect other microservices by allocating separate resources. Use timeout, retry, circuit breaker, and fallback in that order with Polly.
Apply Retry Pattern with Polly policies on HttpClientFactory for Shopping.Aggregator Microservices
Apply Circuit Breaker Pattern with Polly policies on HttpClientFactory for Shopping.Aggregator Microservices
Develop Advance Policies for Retry and Circuit Breaker Pattern with Polly policies on HttpClientFactory
Nuget Package
Install-Package Microsoft.Extensions.Http.Polly
See that
<PackageReference Include="Microsoft.Extensions.Http.Polly" Version="5.0.1" />
Apply Policies for Retry and Circuit Breaker Pattern with Polly policies for AspnetRun Shopping Microservices
Nuget Package
Install-Package Microsoft.Extensions.Http.Polly
See that
<PackageReference Include="Microsoft.Extensions.Http.Polly" Version="5.0.1" />
Using Polly for Database Migration Retries for Ordering.API EF.Core Sql Server Migration
Using Polly for Database Migration Retries for Discount.API/Grpc Dapper PostgreSQL Migration
Implement health checks in ASP.NET Core microservices using HealthChecks and WatchDog, including sub checks for Redis and RabbitMQ, and expose health status in JSON for the WebStatus UI.
Enable built-in health monitoring in ASP.NET core microservices with the Microsoft.Extension.Diagnostic.HealthCheck package, and use HealthChecks.UI to visualize endpoint states like healthy, unhealthy, or degraded.
Nuget Package
Install-Package Microsoft.AspNetCore.Diagnostics.HealthChecks
Adding json response
Nuget Package
Install-Package AspNetCore.HealthChecks.UI.Client
Startup.cs -> Configure
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapHealthChecks("/hc", new HealthCheckOptions()
{
Predicate = _ => true,
ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
});
});
Adding Health Check for Basket.API Microservices with Checking Redis and RabbitMQ Connection
Add health checks for the discount microservices by wiring PostgreSQL connectivity into ASP.NET Core, configure JSON responses, and validate health status through Docker runtime tests.
Adding Health Check for Ordering.API Microservices with Checking Sql Server and RabbitMQ Connection
Adding Health Check for Shopping.Aggregator Microservices with Checking Internal Microservices Integrations
Adding Health Check for AspnetRunBasics Shopping Microservices with Checking Ocelot ApiGw Integrations
Developing WebStatus App for Centralized Microservices Health Monitoring Using Watchdogs for Visualization
Developing WebStatus App for Centralized Microservices Health Monitoring Using Watchdogs for Visualization Part 2
appsettings.json file
"HealthChecks-UI": {
"HealthChecks": [
{
"Name": "Catalog Health Check",
"Uri": "http://localhost:8000/hc"
},
{
"Name": "Basket Health Check",
"Uri": "http://localhost:8001/hc"
},
{
"Name": "Discount Health Check",
"Uri": "http://localhost:8002/hc"
},
{
"Name": "Ordering Health Check",
"Uri": "http://localhost:8004/hc"
},
{
"Name": "Shopping Aggregator Health Check",
"Uri": "http://localhost:8005/hc"
},
{
"Name": "AspnetRunBasics WebMVC Health Check",
"Uri": "http://localhost:8006/hc"
}
],
Containerize web status health monitoring microservices with Docker Compose, generating Docker files via Visual Studio container orchestrator, updating Docker Compose files, and overriding health check configurations for containerized .NET apps.
Test All Microservices on Docker environment - WebStatus Health Monitoring Microservices into Docker Compose for Visulize WatchDog HC
Explore distributed tracing for microservices with OpenTelemetry and Zipkin, using Activity objects to visualize and correlate traces across ASP.NET Core services and improve resilience.
Please check video resources for example implementation of the distributed tracing with OpenTelemetry and Jaeger as a tracing tool.
When you are developing projects in microservices architecture, it is crucial to following Microservices Observability, Microservices Resilience and Monitoring principles.
So, we will separate our Microservices Cross-Cutting Concerns in 4 main pillars;
Microservices Observability with Distributed Logging using ElastichSearch
Microservices Resilience and Fault Tolerance with Appling Retry and Circuit-Breaker patterns using Polly
Microservices Monitoring with Health Checks using WatchDog
Microservices Tracing with OpenTelemetry using Zipkin
So we are going to follow this 4 main pillars and develop our microservices reference application with using latest implementation and best practices on Cloud-Native Microservices architecture style.
We have already developed this microservices reference application in the microservices course, So with this course, we will extend this microservices reference application with Cross-Cutting Concerns for provide microservices resilience.
We are going to cover;
Cross-Cutting Concerns in 4 main parts;
Microservices Observability with Distributed Logging,
This applying Elastic Stack which includes ElasticSearh + Logstach + Kibana and SeriLog Nuget package for .Net microservices.
We will docker-compose Kibana image from docker hub and feed Kibana with elastic stack
Microservices Resilience and Fault Tolerance using Polly
This will apply Retry and Circuit-Breaker Design Patterns on microservices communication with creating Polly policies.
Microservices Health Monitoring with using WatchDog
This will be the Aspnet Health Check implementation with custom health check methods which includes database availabilities - for example in basket microservices, we will add sub-health check conditions for connecting Redis and RabbitMQ.
Microservices Distributed Tracing with OpenTelemetry using Zipkin
This will be the implementation of OpenTelemetry with Zipkin.
By the end of this course, you'll learn how to design and developing Microservices Cross-Cutting Concerns - Microservices Observability with Distributed Logging, Health Monitoring, Resilient and Fault Tolerance with using Polly".
Before beginning the course, you should be familiar with C#, ASP.NET Core and Docker. This course will have good theoretical information but also will be 90% of hands-on development activities.