Sunday, August 16, 2026

Complete CI/CD Pipeline for .NET 9 Microservices on Azure Using Azure DevOps, Docker, ACR and AKS

 


Complete CI/CD Pipeline for .NET 9 Microservices on Azure Using Azure DevOps, Docker, ACR and AKS

Introduction

Modern enterprise applications require a reliable and automated process for building, testing, packaging, and deploying applications across multiple environments.

In a typical microservices-based application, developers continuously make changes to individual services. Manually building and deploying these services is time-consuming and error-prone.

This is where CI/CD — Continuous Integration and Continuous Delivery/Deployment — becomes extremely important.

In this article, we will build a complete CI/CD pipeline for the following enterprise architecture:

  • Angular Web Application

  • .NET 9 Web API / Microservices

  • Docker

  • Azure Container Registry (ACR)

  • Azure Kubernetes Service (AKS)

  • Azure SQL Database

  • Azure Service Bus

  • Azure Key Vault

  • Azure DevOps

  • Kubernetes Ingress

  • DEV, QA, UAT and PRODUCTION environments

We will specifically use the Azure DevOps Classic/Visual UI approach, so you can understand how to configure the pipeline directly through the Azure DevOps portal without initially writing an azure-pipelines.yml file.

Note: Microsoft recommends YAML pipelines for new development, but Classic pipelines remain useful for understanding the Azure DevOps pipeline concepts and for organizations that still use the Classic UI.


1. What Are We Going to Build?

The overall CI/CD architecture will look like this:

Developer
    |
    | Git Push
    v
Azure Repos
    |
    v
+-----------------------------+
|       CI / Build Pipeline   |
|                             |
|  1. Restore                 |
|  2. Build                   |
|  3. Unit Test               |
|  4. Publish                 |
|  5. Docker Build            |
|  6. Docker Push             |
+-------------+---------------+
              |
              v
      Azure Container Registry
              |
              | Docker Image
              v
+-----------------------------+
|      CD / Release Pipeline  |
|                             |
|       DEV                   |
|         |                   |
|         v                   |
|       QA                    |
|         |                   |
|         v                   |
|       UAT                   |
|         |                   |
|     Approval                |
|         |                   |
|         v                   |
|     PRODUCTION              |
+-------------+---------------+
              |
              v
             AKS
              |
       +------+------+
       |      |      |
       v      v      v
    Order  Customer Product
     API     API     API

The basic principle is:

Code → Build → Test → Docker Image → ACR → Deploy → AKS


2. Prerequisites

Before creating the pipeline, we need several Azure and Azure DevOps resources.

Azure Resources

You should have:

  • Azure Subscription

  • Resource Group

  • Azure Container Registry

  • Azure Kubernetes Service

  • Azure SQL Database

  • Azure Service Bus

  • Azure Key Vault

  • Azure Monitor / Application Insights

Azure DevOps

You should have:

  • Azure DevOps Organization

  • Azure DevOps Project

  • Azure Repos

  • Pipeline permissions

  • Microsoft-hosted agent capability

Microsoft-hosted agents are suitable for many standard .NET builds. Self-hosted agents can be used when an organization requires custom tooling or private-network access.


3. Example Enterprise Application

Let's assume our solution has the following structure:

EnterpriseApp
│
├── EnterpriseApp.sln
│
├── src
│   ├── CustomerService
│   │   └── CustomerService.csproj
│   │
│   ├── OrderService
│   │   └── OrderService.csproj
│   │
│   └── ProductService
│       └── ProductService.csproj
│
├── tests
│   └── OrderService.Tests
│
├── Dockerfile
│
└── k8s
    ├── namespace.yaml
    ├── order-deployment.yaml
    ├── order-service.yaml
    ├── customer-deployment.yaml
    ├── customer-service.yaml
    └── ingress.yaml

For our first example, we will deploy:

OrderService

Once the process is understood, the same approach can be applied to:

  • CustomerService

  • ProductService

  • InventoryService

  • PaymentService

  • NotificationService

  • Other microservices


4. Step 1 — Create an Azure DevOps Project

Open your Azure DevOps organization and create a project.

For example:

Organization
    |
    └── EnterpriseProject

Inside the project, Azure DevOps provides services such as:

Boards
Repos
Pipelines
Test Plans
Artifacts

For our CI/CD implementation, the most important areas are:

Repos
Pipelines
Project Settings

5. Step 2 — Add Source Code to Azure Repos

Navigate to:

Repos
    |
    └── Files

Create or import your Git repository.

For example:

EnterpriseApp

The repository might contain:

EnterpriseApp.sln

src/
    CustomerService/
    OrderService/
    ProductService/

tests/
    OrderService.Tests/

Dockerfile

k8s/

Developers can then work with the repository using Git:

git clone <repository>

After making changes:

git add .
git commit -m "Update order validation"
git push

This Git push can eventually trigger the CI pipeline automatically.


6. Step 3 — Create Azure Container Registry

The Azure Container Registry (ACR) stores the Docker images generated by the CI pipeline.

In the Azure Portal:

Create a resource
        ↓
Container Registry

For example:

Registry Name:
enterpriseacr

The registry endpoint could be:

enterpriseacr.azurecr.io

Our Docker image can then be tagged as:

enterpriseacr.azurecr.io/order-service:1.0

or, preferably, with a unique build number:

enterpriseacr.azurecr.io/order-service:1234

Using a unique build identifier makes it easier to identify exactly which source version produced a container image.


7. Step 4 — Create Azure Kubernetes Service

Create an AKS cluster from the Azure Portal or Azure CLI.

For example:

EnterpriseAKS

An AKS cluster contains:

AKS Cluster
    |
    ├── Node Pools
    |
    ├── Kubernetes Control Plane
    |
    └── Workloads

After connecting your local environment to the cluster, you can verify the nodes:

kubectl get nodes

8. Step 5 — Connect ACR with AKS

AKS needs permission to pull Docker images from Azure Container Registry.

A common Azure CLI approach is:

az aks update \
  --resource-group EnterpriseRG \
  --name EnterpriseAKS \
  --attach-acr enterpriseacr

The relationship becomes:

Azure Container Registry
          |
          | Pull Docker Image
          v
         AKS

This is important because the CI pipeline pushes the image into ACR, while AKS pulls that image when deploying the application.


9. Step 6 — Create Azure DevOps Service Connection

Azure DevOps needs permission to access Azure resources.

Navigate to:

Azure DevOps
    ↓
Project Settings
    ↓
Service connections
    ↓
New service connection

Select:

Azure Resource Manager

Configure the connection according to your organization's authentication and security requirements.

For example:

Service Connection Name:

Azure-Enterprise-Connection

Conceptually:

Azure DevOps
       |
       | Service Connection
       v
Azure Subscription
       |
       +---- ACR
       +---- AKS
       +---- Other Azure Resources

Service connections are a critical security boundary, so they should be granted only the permissions required by the pipeline.


10. Step 7 — Create the CI Build Pipeline

Now we can create the Continuous Integration pipeline.

Navigate to:

Pipelines
    ↓
Builds

Depending on your Azure DevOps UI, select the option to create a new pipeline and choose the Classic editor.

The Classic editor allows you to configure the build process using the Azure DevOps UI rather than writing YAML.

Select:

Azure Repos Git

Then select:

Project:
EnterpriseProject

Repository:
EnterpriseApp

Branch:
main

Click:

Continue

11. Step 8 — Select Empty Job

Instead of allowing Azure DevOps to automatically create all the tasks, select:

Empty Job

You should now see something similar to:

Agent Job 1

This approach is useful when learning CI/CD because you can understand each pipeline task individually.


12. Step 9 — Configure the Build Agent

Select:

Agent Job 1

Choose an agent specification.

For example:

ubuntu-latest

or:

windows-latest

For Docker and Linux-based containers, Ubuntu is commonly convenient.

Our pipeline now starts with:

Agent Job
     |
     v
Use .NET SDK

13. Step 10 — Install / Select .NET SDK

Add a task:

+

Search for the .NET SDK task.

Configure the required .NET version.

For example:

SDK Version:

9.x

This ensures that the build agent uses the expected .NET SDK version.


14. Step 11 — Restore NuGet Packages

Add a .NET Core task.

Configure:

Command:

restore

For example:

Path to project:

EnterpriseApp.sln

The pipeline becomes:

Use .NET SDK
      |
      v
Restore

This downloads the NuGet dependencies required by the solution.


15. Step 12 — Build the Application

Add another .NET task.

Configure:

Command:

build

Project:

EnterpriseApp.sln

Arguments:

--configuration Release --no-restore

The pipeline is now:

Use .NET SDK
      |
      v
Restore
      |
      v
Build

The equivalent .NET CLI operation is:

dotnet build EnterpriseApp.sln \
    --configuration Release \
    --no-restore

16. Step 13 — Execute Unit Tests

Add another .NET task.

Configure:

Command:

test

Project:

tests/**/*.csproj

Arguments:

--configuration Release --no-build

The pipeline becomes:

Restore
   |
   v
Build
   |
   v
Unit Tests

If the unit tests fail:

Build ❌

the pipeline should stop.

This is an important CI principle:

Code should not progress toward deployment if automated tests are failing.


17. Step 14 — Publish the .NET Application

Add another .NET task.

Configure:

Command:

publish

Project:

src/OrderService/OrderService.csproj

Configuration:

Release

Output:

$(Build.ArtifactStagingDirectory)/order-service

The flow becomes:

Build
  |
  v
Test
  |
  v
Publish
  |
  v
Build Artifact

18. Step 15 — Build the Docker Image

Now we move from application build to containerization.

Add a Docker task.

Select:

Docker

Command:

Build

Configure the Azure Container Registry connection.

Repository:

order-service

Dockerfile:

$(Build.SourcesDirectory)/src/OrderService/Dockerfile

Tag:

$(Build.BuildId)

The resulting image could be:

enterpriseacr.azurecr.io/order-service:1234

19. Step 16 — Push Docker Image to ACR

Add another Docker task.

Select:

Docker

Command:

Push

Repository:

order-service

Tag:

$(Build.BuildId)

The CI process is now:

Git Push
    |
    v
Restore
    |
    v
Build
    |
    v
Unit Test
    |
    v
Publish
    |
    v
Docker Build
    |
    v
Docker Push
    |
    v
Azure Container Registry

This is the core Continuous Integration workflow.


20. Step 17 — Save and Run the CI Pipeline

Save the pipeline with a name such as:

CI-OrderService

Then select:

Save & Queue

Run the pipeline.

You should see tasks such as:

✔ Restore
✔ Build
✔ Unit Test
✔ Publish
✔ Docker Build
✔ Docker Push

If everything succeeds:

BUILD SUCCESSFUL

21. Step 18 — Verify the Docker Image in ACR

Open:

Azure Portal
    ↓
Container Registry
    ↓
Repositories

You should see:

order-service

Inside the repository:

order-service
    |
    └── 1234

The tag 1234 represents the pipeline build number.


22. Step 19 — Create the CD / Release Pipeline

The next step is Continuous Delivery/Deployment.

In the Classic pipeline model, the release pipeline is separate from the build pipeline.

Navigate to:

Pipelines
    ↓
Releases
    ↓
New pipeline

Select:

Empty Job

Rename the first stage:

DEV

A typical enterprise release pipeline can contain:

DEV
  |
  v
QA
  |
  v
UAT
  |
  v
PRODUCTION

23. Step 20 — Configure the Release Artifact

Add the output from the CI/build process as the release artifact.

For containerized applications, the key deployment input is the Docker image and its version/tag stored in ACR.

Conceptually:

CI Pipeline
     |
     v
Docker Image
     |
     v
ACR
     |
     v
Release Pipeline
     |
     v
AKS

24. Step 21 — Configure DEV Deployment

Open the DEV stage.

Add a Kubernetes deployment task.

Configure the Azure connection:

Connection Type:

Azure Resource Manager

Select:

Azure Subscription:

Azure-Enterprise-Connection

Then select the AKS cluster:

EnterpriseAKS

Use a namespace such as:

dev

This allows the same AKS cluster to host workloads for multiple environments when that is appropriate for the organization's architecture.


25. Kubernetes Deployment

A simplified Kubernetes Deployment might look like:

apiVersion: apps/v1
kind: Deployment

metadata:
  name: order-service

spec:
  replicas: 3

  selector:
    matchLabels:
      app: order-service

  template:
    metadata:
      labels:
        app: order-service

    spec:
      containers:
        - name: order-service

          image: enterpriseacr.azurecr.io/order-service:1234

          ports:
            - containerPort: 8080

The important part is:

image: enterpriseacr.azurecr.io/order-service:1234

When a new version is released, the image tag changes.

For example:

Old:

order-service:1233

becomes:

New:

order-service:1234

Kubernetes then performs a rollout to replace the old application version with the new one.


26. DEV Deployment Flow

The deployment now looks like:

ACR
 |
 | order-service:1234
 v
AKS
 |
 v
DEV Namespace
 |
 +---- Pod 1
 |
 +---- Pod 2
 |
 +---- Pod 3

Running multiple replicas provides application redundancy and enables Kubernetes to distribute traffic across available Pods.


27. Step 22 — Create QA Stage

Add another stage:

QA

Configure the deployment to target:

QA

and use the appropriate Kubernetes namespace:

qa

The pipeline becomes:

DEV
 |
 v
QA

Configure the QA stage to execute after successful DEV deployment.


28. Step 23 — Create UAT Stage

Create another stage:

UAT

The release flow becomes:

DEV
 |
 v
QA
 |
 v
UAT

UAT is generally used for business/user acceptance validation before production.


29. Step 24 — Create Production Stage

Create the final stage:

PRODUCTION

The complete release flow is now:

DEV
 |
 v
QA
 |
 v
UAT
 |
 v
PRODUCTION

30. Step 25 — Add Production Approval

Production deployments should normally have appropriate controls.

Instead of allowing:

Developer
   |
   v
DEV
   |
   v
QA
   |
   v
UAT
   |
   v
PRODUCTION

without any control, introduce an approval gate:

DEV
 |
 v
QA
 |
 v
UAT
 |
 v
+----------------------+
| Production Approval  |
|                      |
| Lead / Manager       |
+----------+-----------+
           |
           v
      PRODUCTION

In the Classic Release pipeline, configure:

PRODUCTION
    ↓
Pre-deployment conditions
    ↓
Pre-deployment approvals

Add the authorized reviewers according to your organization's release-management process.


31. Complete CI/CD Architecture

The complete architecture now looks like this:

                         DEVELOPER
                             |
                             | Git Push
                             v
                      +--------------+
                      | Azure Repos  |
                      +------+-------+
                             |
                             v
                  +----------------------+
                  |    CI / BUILD        |
                  |                      |
                  | Restore              |
                  | Build                |
                  | Unit Test            |
                  | Publish              |
                  | Docker Build         |
                  | Docker Push          |
                  +----------+-----------+
                             |
                             v
                  +----------------------+
                  | Azure Container      |
                  | Registry (ACR)       |
                  +----------+-----------+
                             |
                             v
                  +----------------------+
                  |    CD / RELEASE      |
                  +----------+-----------+
                             |
                             v
                        +---------+
                        |   DEV   |
                        +----+----+
                             |
                             v
                        +---------+
                        |   QA    |
                        +----+----+
                             |
                             v
                        +---------+
                        |   UAT   |
                        +----+----+
                             |
                          Approval
                             |
                             v
                     +---------------+
                     | PRODUCTION    |
                     +-------+-------+
                             |
                             v
                            AKS
                             |
             +---------------+---------------+
             |               |               |
             v               v               v
        Customer API    Order API       Product API

32. Where Does Ingress Fit?

Ingress is part of the Kubernetes application architecture. It is not a replacement for Azure DevOps.

A typical AKS architecture can look like:

                         Internet
                            |
                            v
                     +--------------+
                     |    Ingress   |
                     |   / Gateway  |
                     +------+-------+
                            |
              +-------------+-------------+
              |             |             |
              v             v             v
        Customer API    Order API    Product API
              |             |             |
              v             v             v
            Pods          Pods          Pods
              |             |             |
              +-------------+-------------+
                            |
                   +--------+--------+
                   |                 |
                   v                 v
              Azure SQL       Azure Service Bus

The important distinction is:

Azure DevOps automates application delivery.

Kubernetes/AKS runs the application.

Ingress/Gateway manages incoming application traffic.


33. Where Do Azure SQL and Azure Service Bus Fit?

Azure SQL and Azure Service Bus are generally infrastructure dependencies rather than resources that should be recreated every time the application pipeline runs.

A typical environment contains:

Azure Infrastructure
    |
    +── AKS
    |
    +── ACR
    |
    +── Azure SQL
    |
    +── Azure Service Bus
    |
    +── Key Vault
    |
    +── Monitoring

The CI/CD pipeline then deploys the application:

CI/CD
   |
   v
AKS

The application can communicate with:

Order API
    |
    +---- Azure SQL
    |
    +---- Azure Service Bus

34. Managing Secrets

Sensitive information should never be hardcoded into:

  • Source code

  • Dockerfiles

  • Kubernetes manifests

  • Pipeline scripts

  • Git repositories

Examples include:

SQL connection strings
Service Bus credentials
JWT secrets
API keys
Third-party credentials

A recommended architecture is:

                    Azure Key Vault
                          |
                          |
                    Managed Identity
                          |
                          v
                         AKS
                          |
                          v
                    Microservices

Azure DevOps variable/secret mechanisms can also be used where appropriate, but secrets should be managed according to your organization's security architecture.


35. What Happens When a Developer Commits Code?

Suppose a developer changes the OrderService validation logic.

The developer executes:

git add .

Then:

git commit -m "Update order validation"

Then:

git push origin main

The automated process becomes:

Git Push
   |
   v
CI Trigger
   |
   v
Restore
   |
   v
Build
   |
   v
Unit Tests
   |
   v
Docker Build
   |
   v
Docker Image
   |
   v
ACR
   |
   v
Release Pipeline
   |
   v
DEV
   |
   v
QA
   |
   v
UAT
   |
   v
Approval
   |
   v
PRODUCTION

This is the essence of CI/CD.


36. Continuous Integration vs Continuous Delivery

Understanding the difference between CI and CD is important.

Continuous Integration

Continuous Integration focuses on validating the application whenever code changes.

Code
 |
 v
Restore
 |
 v
Build
 |
 v
Test
 |
 v
Package
 |
 v
Docker Image
 |
 v
ACR

The primary question is:

"Is my code buildable, testable and packageable?"


Continuous Delivery / Deployment

Continuous Delivery/Deployment focuses on moving the validated application version through environments.

ACR
 |
 v
DEV
 |
 v
QA
 |
 v
UAT
 |
 v
Approval
 |
 v
PRODUCTION

The primary question is:

"Can this version be safely deployed to the required environments?"

Therefore:

CI = Build, test and package the application

CD = Deliver/deploy the application through environments


37. Classic Pipeline vs YAML Pipeline

The Classic UI is an excellent way to learn Azure DevOps because you can visually see:

Agent
Tasks
Stages
Artifacts
Approvals
Deployment

However, for modern enterprise projects, YAML pipelines are often preferred because the pipeline definition can be stored alongside the source code.

A modern architecture can look like:

Azure DevOps
      |
      v
YAML Pipeline
      |
      +---- CI
      |
      +---- Build
      |
      +---- Unit Tests
      |
      +---- Docker
      |
      +---- Security
      |
      +---- ACR
      |
      +---- CD
             |
             +---- DEV
             |
             +---- QA
             |
             +---- UAT
             |
             +---- PROD

The key advantage is Pipeline as Code.

The pipeline itself becomes version-controlled, reviewable, and reproducible.


38. Recommended Enterprise Improvements

The basic pipeline described above can be extended significantly for production environments.

Security

Add:

  • Azure Key Vault

  • Managed Identity

  • Microsoft Entra ID

  • Container image scanning

  • Dependency scanning

  • Secret scanning

  • Least-privilege service connections

Quality

Add:

  • Unit tests

  • Integration tests

  • Code coverage

  • SonarQube/SonarCloud

  • API testing

  • Performance testing

Deployment

Add:

  • Rolling deployments

  • Health probes

  • Readiness probes

  • Liveness probes

  • Deployment strategies

  • Automatic rollback

  • Environment approvals

Observability

Add:

  • Application Insights

  • Azure Monitor

  • Log Analytics

  • Kubernetes monitoring

  • Alerts

  • Dashboards


39. Production-Ready Microservices Flow

A mature enterprise architecture could eventually look like:

                         Developer
                             |
                             v
                        Azure Repos
                             |
                             v
                    Azure DevOps CI
                             |
          +------------------+------------------+
          |                  |                  |
          v                  v                  v
      Build/Test        Security Scan       Code Quality
          |                  |                  |
          +------------------+------------------+
                             |
                             v
                         Docker Build
                             |
                             v
                           ACR
                             |
                             v
                    Deployment Pipeline
                             |
            +----------------+----------------+
            |                |                |
            v                v                v
           DEV              QA               UAT
                                             |
                                         Approval
                                             |
                                             v
                                         PROD
                                             |
                                             v
                                            AKS
                                             |
                         +-------------------+-------------------+
                         |                   |                   |
                         v                   v                   v
                    Customer API        Order API          Product API
                         |                   |                   |
                         +-------------------+-------------------+
                                             |
                    +------------------------+----------------------+
                    |                                               |
                    v                                               v
                Azure SQL                                  Azure Service Bus
                    |
                    v
               Application
                 Insights
                    |
                    v
               Azure Monitor

40. Important Takeaways

The complete deployment journey can be remembered as:

Developer
   ↓
Git
   ↓
Azure DevOps
   ↓
CI
   ↓
Build
   ↓
Test
   ↓
Docker
   ↓
ACR
   ↓
CD
   ↓
DEV
   ↓
QA
   ↓
UAT
   ↓
Approval
   ↓
PRODUCTION
   ↓
AKS

The responsibilities of the major components are:

ComponentResponsibility
Azure ReposSource-code management
Azure DevOpsCI/CD automation
DockerApplication containerization
ACRDocker image storage
AKSContainer orchestration
KubernetesApplication workload management
Ingress/GatewayIncoming traffic routing
Azure SQLRelational database
Azure Service BusAsynchronous messaging
Key VaultSecret management
Application InsightsApplication telemetry
Azure MonitorMonitoring and alerting

41. Final Conclusion

Implementing CI/CD for a .NET microservices application on Azure provides a repeatable and controlled way to move software from development to production.

The complete lifecycle is:

Code
  ↓
Commit
  ↓
Build
  ↓
Unit Test
  ↓
Docker Image
  ↓
Azure Container Registry
  ↓
AKS Deployment
  ↓
DEV
  ↓
QA
  ↓
UAT
  ↓
Production Approval
  ↓
PRODUCTION

For learning Azure DevOps, the Classic UI pipeline is a very useful starting point because every stage and task is visible through the portal.

For a new enterprise implementation, however, it is worth moving toward YAML-based pipelines, infrastructure as code, automated security scanning, managed identities, automated testing, deployment strategies, and comprehensive monitoring.

The ultimate goal is not simply to automate deployment.

The goal is to create a secure, repeatable, observable, and reliable software delivery process.


Quick Reference

CI

Git
 ↓
Restore
 ↓
Build
 ↓
Test
 ↓
Publish
 ↓
Docker Build
 ↓
Docker Push
 ↓
ACR

CD

ACR
 ↓
DEV
 ↓
QA
 ↓
UAT
 ↓
Approval
 ↓
PRODUCTION
 ↓
AKS

Application Architecture

Internet
   ↓
Ingress / Gateway
   ↓
Microservices
   ↓
Azure SQL
   +
Azure Service Bus
   +
Key Vault
   +
Application Insights

This architecture provides a strong foundation for deploying modern .NET 9 microservices applications on Azure using Azure DevOps, Docker, ACR and AKS.

Friday, August 14, 2026

SignalR vs Azure Service Bus vs Kafka vs RabbitMQ: Complete Guide with Real-Time Examples and C# Code

 

SignalR vs Azure Service Bus vs Kafka vs RabbitMQ: Complete Guide with Real-Time Examples and C# Code

Modern enterprise applications often use multiple applications, microservices, background workers, and front-end clients that need to communicate with each other. Choosing the right communication technology is therefore an important architectural decision.

Four technologies frequently considered in .NET and microservices architectures are:

  • ASP.NET Core SignalR

  • Azure Service Bus

  • RabbitMQ

  • Apache Kafka

Although they are sometimes compared with each other, they are designed for different communication patterns.

The most important principle is:

SignalR is primarily for real-time client communication, Azure Service Bus and RabbitMQ are message brokers, while Kafka is primarily an event-streaming platform.


1. Introduction

Consider an enterprise e-commerce application:

                    Angular Application
                           |
                           v
                     Order Web API
                           |
             +-------------+-------------+
             |             |             |
             v             v             v
        Payment        Inventory     Notification
        Service          Service        Service

Now consider the following requirements:

  1. Notify the customer's browser immediately when the order status changes.

  2. Send an order-processing message reliably to another microservice.

  3. Route messages to different queues based on business requirements.

  4. Store large volumes of events and allow multiple applications to process them independently.

  5. Replay historical events for analytics or recovery.

One technology is not necessarily the best solution for all these requirements.

This is where SignalR, Azure Service Bus, RabbitMQ and Kafka come into the picture.


2. Quick Comparison

TechnologyPrimary PurposeBest Use Case
SignalRReal-time client communicationNotifications, chat, live dashboards
Azure Service BusEnterprise messagingReliable microservice communication
RabbitMQMessage brokerQueues, routing, work distribution
KafkaEvent streamingHigh-volume events, analytics, event pipelines

3. SignalR

SignalR is an ASP.NET Core library designed for real-time communication between a server and connected clients.

Instead of the client repeatedly asking:

Is my order ready?

Is my order ready?

Is my order ready?

the server can push an update immediately:

Order #1001 has been shipped.

SignalR supports WebSockets and fallback transports such as Server-Sent Events and Long Polling.

Typical SignalR use cases

  • Real-time notifications

  • Chat applications

  • Live dashboards

  • Order tracking

  • Stock/price updates

  • Monitoring applications

  • Progress notifications

  • Collaborative applications


4. SignalR Architecture

                ASP.NET Core Server
                       |
                       |
                    SignalR
                       |
              WebSocket Connection
                       |
          +------------+------------+
          |            |            |
          v            v            v
       Browser 1    Browser 2    Browser 3

The important point is that SignalR is generally about connected clients.

It is not intended to replace a durable enterprise message broker.


5. SignalR C# Example

Install the SignalR package if required:

dotnet add package Microsoft.AspNetCore.SignalR

Create a Hub:

public class NotificationHub : Hub
{
    public async Task SendNotification(string message)
    {
        await Clients.All.SendAsync(
            "ReceiveNotification",
            message);
    }
}

Configure the Hub:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddSignalR();

var app = builder.Build();

app.MapHub<NotificationHub>("/notificationHub");

app.Run();

A client can connect to:

/notificationHub

The server can then send:

await hubContext.Clients.All.SendAsync(
    "ReceiveNotification",
    "Order #1001 has been shipped.");

All connected clients receive the notification.


6. SignalR with Angular

Install the SignalR client:

npm install @microsoft/signalr

Create a connection:

import * as signalR from '@microsoft/signalr';

const connection =
    new signalR.HubConnectionBuilder()
        .withUrl('https://localhost:7000/notificationHub')
        .build();

connection.on('ReceiveNotification', message => {
    console.log(message);
});

await connection.start();

The communication looks like:

ASP.NET Core
     |
     | SignalR
     | WebSocket
     v
Angular Application

7. Azure Service Bus

Azure Service Bus is a fully managed enterprise message broker.

It is designed for reliable communication between applications and services.

Microsoft describes Azure Service Bus as a cloud messaging system supporting queues, topics, subscriptions and enterprise messaging scenarios.

Consider:

Order API
    |
    | OrderCreated
    v
Azure Service Bus
    |
    +------> Payment Service
    |
    +------> Inventory Service
    |
    +------> Notification Service

The producer and consumer don't need to execute at exactly the same time.

The broker provides the decoupling layer.


8. Azure Service Bus Queue

A queue generally represents a point-to-point communication model.

Producer
   |
   v
+----------------+
| Order Queue    |
+----------------+
   |
   v
Consumer

For example:

Order API
    |
    v
OrderQueue
    |
    v
Payment Service

The message can remain available until a consumer successfully processes it.

This is particularly useful for background processing and microservice workflows.


9. Azure Service Bus C# Producer

Install:

dotnet add package Azure.Messaging.ServiceBus

Producer:

using Azure.Messaging.ServiceBus;
using System.Text.Json;

string connectionString = "...";
string queueName = "orders";

await using var client =
    new ServiceBusClient(connectionString);

ServiceBusSender sender =
    client.CreateSender(queueName);

var order = new
{
    OrderId = 1001,
    CustomerId = 5001,
    Amount = 2500
};

string json = JsonSerializer.Serialize(order);

var message = new ServiceBusMessage(json);

await sender.SendMessageAsync(message);

Architecture:

Order API
    |
    | SendMessageAsync()
    v
Azure Service Bus
    |
    v
Order Queue

10. Azure Service Bus Consumer

ServiceBusProcessor processor =
    client.CreateProcessor(queueName);

processor.ProcessMessageAsync += async args =>
{
    string message =
        args.Message.Body.ToString();

    Console.WriteLine(message);

    await args.CompleteMessageAsync(args.Message);
};

processor.ProcessErrorAsync += args =>
{
    Console.WriteLine(args.Exception);
    return Task.CompletedTask;
};

await processor.StartProcessingAsync();

The consumer processes the message and explicitly completes it.


11. Azure Service Bus Topic

A topic is useful when the same business event needs to reach multiple subscribers.

                    Order API
                       |
                       v
                 OrderCreated
                       |
                       v
                Azure Service Bus
                     Topic
                       |
          +------------+------------+
          |            |            |
          v            v            v
     Subscription  Subscription  Subscription
       Payment       Inventory    Notification

For example:

OrderCreated
      |
      +---- Payment Service
      |
      +---- Inventory Service
      |
      +---- Notification Service
      |
      +---- Audit Service

Azure Service Bus topics and subscriptions provide a publish/subscribe model.


12. RabbitMQ

RabbitMQ is a popular message broker.

One of its most important architectural concepts is the exchange.

The typical flow is:

Producer
   |
   v
Exchange
   |
   | Routing
   |
   +--------+--------+
   |        |        |
   v        v        v
Queue A   Queue B   Queue C
   |        |        |
   v        v        v
Consumer  Consumer  Consumer

RabbitMQ supports different exchange types, including:

  • Direct

  • Topic

  • Fanout

  • Headers

This provides flexible message-routing capabilities.


13. RabbitMQ C# Producer

A commonly used .NET package is:

dotnet add package RabbitMQ.Client

Example:

using RabbitMQ.Client;
using System.Text;

var factory = new ConnectionFactory
{
    HostName = "localhost"
};

using var connection =
    await factory.CreateConnectionAsync();

using var channel =
    await connection.CreateChannelAsync();

await channel.QueueDeclareAsync(
    queue: "orders",
    durable: true,
    exclusive: false,
    autoDelete: false);

string message = "Order #1001 created";

byte[] body =
    Encoding.UTF8.GetBytes(message);

await channel.BasicPublishAsync(
    exchange: "",
    routingKey: "orders",
    body: body);

The message is sent to the RabbitMQ broker.


14. RabbitMQ Consumer

var consumer =
    new AsyncEventingBasicConsumer(channel);

consumer.ReceivedAsync += async (sender, args) =>
{
    string message =
        Encoding.UTF8.GetString(args.Body.ToArray());

    Console.WriteLine(message);

    await channel.BasicAckAsync(
        args.DeliveryTag,
        multiple: false);
};

await channel.BasicConsumeAsync(
    queue: "orders",
    autoAck: false,
    consumer: consumer);

The acknowledgement tells RabbitMQ that the message has been successfully processed.


15. Kafka

Apache Kafka is primarily an event-streaming platform.

This is an important distinction.

Kafka is not simply:

Producer -> Queue -> Consumer

Instead, Kafka uses:

Producer
    |
    v
Kafka Topic
    |
    +--- Partition 0
    |
    +--- Partition 1
    |
    +--- Partition 2

Kafka topics are divided into partitions, allowing data to be distributed and processed in parallel. Kafka consumers use offsets to track their position in the stream.


16. Kafka Consumer Groups

This is one of Kafka's most important concepts.

Suppose:

OrderCreated

is published to Kafka.

Multiple independent systems can consume it.

                    Kafka Topic
                        |
              +---------+---------+
              |         |         |
              v         v         v
          Payment    Analytics   Fraud
           Group       Group      Group

Each consumer group maintains its own position.

Therefore, the same event can be processed independently by multiple systems.


17. Kafka C# Producer

Install:

dotnet add package Confluent.Kafka

Producer:

using Confluent.Kafka;

var config = new ProducerConfig
{
    BootstrapServers = "localhost:9092"
};

using var producer =
    new ProducerBuilder<string, string>(config)
        .Build();

await producer.ProduceAsync(
    "orders",
    new Message<string, string>
    {
        Key = "1001",
        Value = "Order #1001 created"
    });

The architecture is:

Order API
    |
    v
Kafka Producer
    |
    v
orders topic

18. Kafka Consumer

var config = new ConsumerConfig
{
    BootstrapServers = "localhost:9092",
    GroupId = "payment-service",
    AutoOffsetReset = AutoOffsetReset.Earliest
};

using var consumer =
    new ConsumerBuilder<string, string>(config)
        .Build();

consumer.Subscribe("orders");

while (true)
{
    var result = consumer.Consume();

    Console.WriteLine(
        $"Received: {result.Message.Value}");
}

The consumer group is:

payment-service

Kafka uses offsets to keep track of which events have been processed.


19. The Most Important Difference: Queue vs Event Stream

This is one of the most frequently asked interview questions.

Traditional Message Queue

Conceptually:

Producer
   |
   v
Queue
   |
   v
Consumer

The primary purpose is to deliver work/messages to consumers.

Examples:

Azure Service Bus Queue
RabbitMQ Queue

Kafka Event Stream

Kafka is based around a durable event log:

Producer
   |
   v
+-----------------------------+
| Kafka Topic                 |
|                             |
| E1 E2 E3 E4 E5 E6 E7 ...    |
+-----------------------------+
       |
       +---- Consumer Group A
       |
       +---- Consumer Group B
       |
       +---- Consumer Group C

Events can be retained according to Kafka's retention configuration, and consumers can maintain their own offsets.

This makes Kafka particularly powerful for:

  • Event streaming

  • Event replay

  • Analytics

  • Data pipelines

  • Audit/event history

  • High-volume processing


20. SignalR vs Azure Service Bus

These technologies solve very different problems.

SignalR

Server
   |
   | Real-time
   v
Browser

Azure Service Bus

Service A
   |
   v
Azure Service Bus
   |
   v
Service B
FeatureSignalRAzure Service Bus
Real-time browser updatesExcellentNo
WebSocketsYesNo
Service-to-service messagingNot primaryExcellent
Durable messagingNot primaryYes
QueueNoYes
Topic/SubscriptionClient groupsYes
ChatExcellentNot primary
Background processingNot primaryExcellent
Enterprise workflowsNot primaryExcellent

21. Azure Service Bus vs RabbitMQ

These are much closer competitors.

FeatureAzure Service BusRabbitMQ
Message queueYesYes
Pub/SubYesYes
RoutingGoodExcellent
Managed Azure serviceYesNo, unless using a managed RabbitMQ offering
Self-hostingNoYes
Azure integrationExcellentGood
ExchangesNoYes
Routing keysNoYes
Enterprise messagingExcellentExcellent
Operational overheadLowerHigher if self-managed

If your application is heavily based on Azure, Azure Service Bus is often a natural choice because it is a managed Azure service.

RabbitMQ becomes attractive when you need broker-level control, flexible routing, self-hosting, or a platform-independent messaging layer.


22. RabbitMQ vs Kafka

These are also frequently compared.

FeatureRabbitMQKafka
Primary purposeMessage brokerEvent streaming
QueueExcellentDifferent model
RoutingExcellentGood
Event streamingLimited compared with KafkaExcellent
Event retentionNot its primary modelCore capability
Event replayNot primaryExcellent
Consumer groupsDifferent modelCore capability
PartitioningNo Kafka-style partition modelCore capability
High-volume streamsGoodExcellent
Work queuesExcellentPossible
Complex routingExcellentLess central
Analytics pipelinesGoodExcellent

23. Kafka vs Azure Service Bus

FeatureKafkaAzure Service Bus
Event streamingExcellentGood
Traditional queuesPossibleExcellent
Event replayExcellentDifferent model
Consumer groupsCore featureDifferent model
PartitioningCore featureDifferent scaling model
Enterprise messagingExcellentExcellent
AnalyticsExcellentGood
Data pipelinesExcellentGood
Azure-native applicationsGoodExcellent
Operational complexityHigherLower
Event historyExcellentDifferent model

24. Real-World E-Commerce Architecture

Let's combine these technologies in a realistic enterprise application.

                        Angular
                           |
                           | HTTPS
                           v
                     Order Web API
                           |
                           |
                    +------+------+
                    |             |
                    v             v
              Azure Service      Kafka
                  Bus              |
                    |              |
          +---------+---------+    +----------+
          |         |         |    |          |
          v         v         v    v          v
       Payment   Inventory Notification Analytics
       Service     Service    Service
                                     
                           |
                           v
                       SignalR
                           |
                           v
                     Angular Browser

Let's understand the flow.


25. Step 1 — Customer Places Order

Angular calls:

POST /api/orders

The Order API creates the order.

Angular
   |
   v
Order API
   |
   v
Order Created

26. Step 2 — Azure Service Bus

The Order API sends a business message:

OrderCreated

to Azure Service Bus.

Order API
    |
    v
Azure Service Bus
    |
    +---- Payment Service
    |
    +---- Inventory Service

This gives the services loose coupling.


27. Step 3 — Kafka

The system can also publish an event:

OrderCreated

to Kafka.

                    Kafka
                      |
          +-----------+-----------+
          |           |           |
          v           v           v
      Analytics      Fraud      Reporting

These systems can independently process the event.


28. Step 4 — SignalR

Once the order status changes:

Order Processing
       |
       v
Order Shipped

the backend sends a SignalR notification:

Order Service
      |
      v
SignalR Hub
      |
      v
Angular

The customer immediately sees:

Your order has been shipped!

29. Complete Enterprise Architecture

                         +----------------+
                         |    Angular     |
                         +-------+--------+
                                 |
                                 | REST
                                 v
                         +---------------+
                         |   API Layer   |
                         +-------+-------+
                                 |
                         +-------+-------+
                         |               |
                         v               v
                +----------------+   +----------+
                | Azure Service  |   |  Kafka   |
                |     Bus        |   |          |
                +-------+--------+   +-----+----+
                        |                  |
             +----------+----------+      |
             |          |          |      |
             v          v          v      v
          Payment   Inventory  Notification Analytics
          Service     Service      Service
             |
             |
             v
       Business Processing
             |
             v
         SignalR Hub
             |
             v
          Angular UI

This architecture demonstrates why these technologies should not automatically be treated as interchangeable.


30. When Should You Use SignalR?

Use SignalR when the requirement is:

"I need to push information from my server to connected clients immediately."

Examples:

Live notification
Live chat
Order status
Real-time dashboard
Progress updates
Monitoring
Collaboration

31. When Should You Use Azure Service Bus?

Use Azure Service Bus when the requirement is:

"I need reliable enterprise messaging between applications or microservices."

Examples:

Order processing
Payment processing
Inventory processing
Background jobs
Business workflows
Microservice communication
Enterprise integration

32. When Should You Use RabbitMQ?

Use RabbitMQ when the requirement is:

"I need a flexible message broker with sophisticated routing and queue-based processing."

Examples:

Work queues
Task distribution
Microservice messaging
Complex routing
Pub/Sub
Self-hosted messaging infrastructure

33. When Should You Use Kafka?

Use Kafka when the requirement is:

"I need a high-throughput, durable event stream that can be consumed independently by many applications."

Examples:

IoT events
Clickstream
Analytics
Data pipelines
Event-driven architecture
Audit events
Financial events
Real-time processing
Large-scale event ingestion

34. Can We Use All Four Together?

Yes.

In a large enterprise system, using multiple technologies can be completely valid.

For example:

                 Customer
                    |
                    v
                Angular
                    |
                    v
                ASP.NET
                    |
          +---------+---------+
          |                   |
          v                   v
    Azure Service Bus       Kafka
          |                   |
          v                   v
   Business Services      Analytics
          |
          v
       SignalR
          |
          v
       Angular

RabbitMQ could also be introduced for a specialized workload where its routing or queueing model is advantageous.

The important thing is not to add technologies unnecessarily.


35. Common Architectural Mistakes

Mistake 1: Using SignalR as a message broker

Don't design:

Order API
    |
    v
SignalR
    |
    v
Payment Service

just because SignalR can send messages.

SignalR is primarily intended for real-time client communication.


Mistake 2: Using Kafka for every small background job

Kafka is extremely powerful, but that doesn't mean every background task requires Kafka.

For a simple:

Order API
    |
    v
Process Invoice

a traditional queue such as Azure Service Bus or RabbitMQ may be simpler.


Mistake 3: Choosing Kafka because it is "fast"

Architecture should not be:

Kafka is fast
       ↓
Use Kafka everywhere

Instead ask:

Do I need event streaming?
Do I need retention?
Do I need replay?
Do I need many consumer groups?
Do I need high-volume event processing?

If yes, Kafka becomes a strong candidate.


36. Interview Question: Are SignalR, Kafka, RabbitMQ and Service Bus Alternatives?

Answer: Not completely.

They overlap in some areas, but their primary purposes are different.

SignalR
   ↓
Real-time client communication

Azure Service Bus
   ↓
Enterprise message broker

RabbitMQ
   ↓
Message broker + flexible routing

Kafka
   ↓
Distributed event streaming

37. Interview Question: Kafka vs RabbitMQ?

A good answer:

RabbitMQ is primarily a message broker focused on queues, routing and message delivery, whereas Kafka is primarily an event-streaming platform designed around durable event streams, partitions, consumer groups and high-throughput processing. I would typically consider RabbitMQ for work queues and complex routing, and Kafka when I need scalable event streaming, retention, replay and multiple independent consumers.


38. Interview Question: SignalR vs Kafka?

A good answer:

SignalR is designed for real-time communication between servers and connected clients, typically browsers or mobile applications. Kafka is designed for durable, scalable event streaming between backend systems. In an enterprise application, I might use Kafka to distribute an OrderShipped event internally and SignalR to push the resulting status update to the customer's browser.


39. Interview Question: Service Bus vs RabbitMQ?

A good answer:

Both are message brokers. Azure Service Bus is a managed Azure messaging service with strong integration into the Azure ecosystem, while RabbitMQ provides a flexible broker with exchanges, bindings and routing capabilities and can be self-hosted. If the application is Azure-centric and we want minimal infrastructure management, Service Bus is attractive. If we require greater broker-level control or specific RabbitMQ routing capabilities, RabbitMQ can be a better choice.


40. Interview Question: Can SignalR and Azure Service Bus Be Used Together?

Absolutely.

For example:

Order Service
     |
     | OrderCompleted
     v
Azure Service Bus
     |
     v
Notification Service
     |
     v
SignalR
     |
     v
Browser

The Service Bus provides reliable backend messaging.

SignalR provides real-time delivery to the user.

This is often a cleaner architecture than trying to use SignalR for both responsibilities.


41. Final Decision Matrix

RequirementRecommended Technology
Real-time browser notificationSignalR
ChatSignalR
Live dashboardSignalR
Microservice commandAzure Service Bus / RabbitMQ
Enterprise business messagingAzure Service Bus
Complex broker routingRabbitMQ
Background work queueAzure Service Bus / RabbitMQ
High-volume event streamKafka
Event replayKafka
Data/analytics pipelineKafka
Multiple independent consumersKafka
Azure-native messagingAzure Service Bus
Self-hosted brokerRabbitMQ / Kafka
Server-to-browser communicationSignalR

42. Conclusion

SignalR, Azure Service Bus, RabbitMQ and Kafka are powerful technologies, but they solve different problems.

The easiest way to remember the difference is:

+---------------------------------------------------+
|                   COMMUNICATION                   |
+---------------------------------------------------+
|                                                   |
|  SignalR                                          |
|  Server ---> Connected Clients                   |
|                                                   |
|  Azure Service Bus                                |
|  Application ---> Reliable Business Message      |
|                                                   |
|  RabbitMQ                                         |
|  Producer ---> Broker ---> Routed Queue           |
|                                                   |
|  Kafka                                            |
|  Producer ---> Durable Event Stream ---> Consumers|
|                                                   |
+---------------------------------------------------+

In one sentence:

Use SignalR for real-time client communication, Azure Service Bus for reliable Azure enterprise messaging, RabbitMQ for flexible broker-based messaging and routing, and Kafka for scalable, durable event streaming.

For a modern .NET 9/10 + Angular + Microservices + Azure enterprise application, a combination such as Azure Service Bus + Kafka + SignalR can be very effective when each technology is assigned a clear responsibility.

Don't Copy

Protected by Copyscape Online Plagiarism Checker