This repository contains a YouTube Clone microservices application built with .NET 7 and Angular 14.
Microservices Application (.NET)
SPA Application (Angular)
Screenshots
Demo Video
Running with Docker
Kubernetes
The microservices architecture of the application is based on ASP.NET Core 7, providing a scalable and flexible solution. Each microservice is designed to be horizontally scalable, allowing for granular resource allocation and efficient use of computing resources.
Domain-driven design pattern helps to clarify complex domains and ensure the consistency of the business rules.
Event bus based on RabbitMQ allows asynchronous communications between different services.
Transactional outbox implemented for both Entity Framework Core and MongoDB persistence layers to ensure reliable and ordered message publishing.
Integration events are requeued for transient errors and sent to dead-letter queue for unrecoverable errors.
Routing slip pattern (as used in event bus system like MassTransit) allows eventual consistency in distributed transactions.
Unit of work pattern implementation for committing changes in a single transactional batch for both Entity Framework Core and MongoDB
The Video Manager Service plays a crucial role in the video sharing platform, managing the videos and their metadata.
Video creation: The Video Manager Service handles the user request to create a new video.
Video upload authorization: The Video Manager Service generates upload tokens that authorizes the users to upload video files.
Video registration: After the video file is uploaded, the Video Manager Service registers the video with other microservices, including the Video Store, Library, Community, and History Services.
Video processing initiation: Once the video is registered to different services, the Video Manager Service publishes an integration event to the Video Processor Service to initiate the video processing.
Video processing completion notification: After the video is processed, the Video Manager Service publishes integration events to notify other microservices about the completion of the processing.
Video metadata management: The Video Manager Service manages and store the original metadata of the videos, such as video title, description, visibility, tags, etc. The updated metadata is synchronized to the Video Store Service for serving.
Video deletion: The Video Manager Service also has the ability to delete a video in response to user requests.
The Video Manager SignalR Hub Service enhances the Video Manager Service by delivering real-time notifications to users regarding the processing status of the videos.
The Video Processor Service is responsible for processing the video files. This service utilizes the power of FFmpeg for video processing and generates different resolutions and thumbnails of the uploaded video. For this service to run correctly, FFmpeg must be installed in advance, which will be done by the Dockerfile automatically.
The Video Processor Service will process the video file, generate different resolutions and preview thumbnails of the uploaded video using FFmpeg.
If the video processing is interrupted for transient issues, the video processing will be retried automatically.
The video processor service can be automatically horizontally scaled by Kubernetes horizontal pod autoscaler. This is implemented through the use of custom metrics, including the number of concurrent processing tasks, which are exposed by each instance of the video processor service and gathered by Prometheus. By integrating with the Prometheus adapter, the Kubernetes hpa can scale out the video processor service in response to the usage.
The Video Store Service is responsible for storing and serving the video metadata to the users. This service controls the publication of videos and ensures that the video metadata is replicated with other microservices, such as the Library Service.
The Storage Service is responsible for storing and serving the video and image files. Both the users and other services can upload files to the Storage Service. This service integrates with Entity Framework Core to store the metadata of the uploaded files.
For user upload, the user must provide a upload token.
After an image is uploaded, another token is returned to the user.
After a video is uploaded, the Storage Service will instead publish an integration event to notify the Video Manager Service for the processing, without returning a token to the user.
There is a background service to clean up file which is no longer in use.
It is possible to implement the IAntiVirusScanner for virus scanning.
It is possible to integrate this service to cloud-based storage solution like Azure Blob Storage.
The Identity Provider Service is a microservice that is responsible for user authentication and authorization. This service integrates with Duende Identity Server, which is a comprehensive solution for identity management and security.
Authorization code flow for user authorization and authentication.
Client credential flow for machine-to-machine authorization and authentication.
This service can be completely replaced by cloud-based identity management solution like Auth0, Azure AD.
The Users Service is responsible for managing and storing the user profiles and channel data.
User profile management: This service is responsible for creating, storing, and managing the user profiles, including the user's display name, handle, description email, thumbnail, etc. The user profile creation requires an asynchronous distributed transaction to register the user profile to other microservices to ensure that the all the services work correctly.
User channel management: The Users Service will also manage the data of the user's channel, such as the channel layout, banner, etc.
The Subscriptions Service is responsible for managing user subscriptions and storing user notifications.
Subscription management: The Subscriptions Service enables users to subscribe to their desired channels.
Storing user notifications: When a subscribed channel is updated, such as the publishing of a new video, the Subscriptions Service will store the corresponding notification messages. These notification messages are kept in a Redis database.
The Library Service is responsible for managing playlists and serving both the playlists and basic video metadata to users, as well as enabling video voting functionality.
Managing user playlists: The Library Service is responsible for managing the playlists of users, including liked playlist, watch later playlist, and custom playlist. The items in the watch later and custom playlists are re-orderable for greater user convenience.
Video voting: The Library Service allows users to vote on videos by liking or disliking them. This is essentially accomplished by adding the video to the user's liked or disliked playlist, respectively.
The Community Service is responsible for providing a platform for users to engage in discussions.
Video commenting: The Community Service enables users to add comments to videos, reply to other users' comments, edit and delete comments.
Comment voting: In addition to commenting, users can also vote on comments, allowing the community to signal which comments are most useful, insightful, or entertaining.
The History Service is responsible for managing and storing the user watch history, as well as counting the number of views for each video. The watch history records are efficiently stored in an Elasticsearch database, enabling search functionality and the ability to analyze users' favorite video tags.
The Search Service is integrated with Elasticsearch to deliver full-text search capabilities for videos. With its integration, users can find trending and relevant tags, search videos based on tags, creators, and full-text queries.
Full-text search: The Search Service supports full-text search, allowing users to search for videos based on titles, creator names, keywords, etc.
Tag-based search: Users can search for videos using tags, making it easier to find relevant videos.
Creator-based search: Users can search for videos by creator ids, enabling functionality such as subscription feeds.
Relevance scoring: The Search Service also incorporates relevance scoring based on metrics such as views count and likes count to recommend popular videos.
Tags search: The Search Service uses Elasticsearch's bucket aggregation to find find trending tags and relevant tags.
The API Gateway Service,integrated with YARP, provides a centralized entry point for all client requests and distributing them to the appropriate backend services, except for the Storage and Identity Provider Services. Additionally, it enables rate limiting functionality to protect the underlying backend services from excessive traffic.
The Web Status Service provides a web user interface for health checks. For automatic Kubernetes services discovery, please refer to Health Checks UI automatic Kubernetes services discovery.
The logs are sent to the ELK Stack (Elasticsearch, Logstash, and Kibana) by Serilog for storage, processing, and analysis. All the log data is collected and stored in a centralized Elasticsearch database, making it easy to search and analyze log data across all components of the system.
OpenTelemetry is used to instrument the microservices, generate tracing data, and export it to Jaeger to gain visibility into the performance and behavior of the application.
AKS Virtual Nodes: Support for AKS virtual nodes can be added to the video processor service, which allows it to run on the Azure container instances to enhance its scalability and efficiency.
Testing: The application currently lacks unit and functional testing. Adding tests would help to catch bugs and ensure the application works as expected.
Caching: More caching can be added to the application to improve its performance and reduce the load on the backend services.
The SPA (Single Page Application) is built using Angular, Angular Material, Ngrx, and Videogular. These technologies enable the creation of responsive user interfaces, providing a smooth user experience.
YouTube Clone Application Demo Video
To run the application and its necessary infrastructure, make sure that you have Docker and Docker Compose installed on your machine.
Navigate to the Scripts directory and use the following commands:
backend_build.bat
backend_up.bat
front_build.bat
front_up.bat
./backend_build.sh
./backend_up.sh
./front_build.sh
./front_up.sh
The scripts will launch 26 containers, including the web client, microservices and infrastructure.
After the application is completely launched, you should able to browse the different components by visiting
Web SPA : http://localhost:4200/
Web Status : http://localhost:16050/
Kibana : http://localhost:5601/
Jaeger UI : http://localhost:16686/
This application use the following ports:
PostgreSQL: 5432
Adminer: 8080
PgAdmin: 8081
RabbitMQ: 5672
RabbitMQ Management: 15672
MongoDB: 27017
MongoExpress: 8082
Elasticsearch: 9200
Logstash: 9600, 9250
Kibana: 5601
Redis: 6379
RedisCommander: 8083
Jaeger: 5565/udp, 6831/udp, 6832/udp, 5778, 14268, 14250, 9411
Jaeger UI: 16686
Storage: 14200
VideoManager: 15000
VideoManagerSignalRHub: 15050
IdentityProvider: 15100
VideoProcessor: 15200
VideoStore: 15300
Users: 15400
Community: 15500
Library: 15600
Search: 15700
Subscriptions: 15800
History: 15900
APIGateway: 16000
WebStatus: 16050
WebClient: 4200
This repository includes sample kubernetes manifests for deploying the application to Minikube and Azure Kubernetes Service (AKS).
To deploy the application to Minikube, you will need to have Docker, Kubectl, and Minikube installed on your machine. Here are the steps to get started:
minikube start
build_images.bat
./0_enable_metrics_server.ps1
./1_minikube_load_images.ps1
./2_install_prometheus.ps1
./3_bake.ps1
./4_apply.ps1
./5_minikube_tunnel.ps1
These commands enable the metrics server, load Docker images into Minikube, install Prometheus, bake the Kubernetes manifests with Kustomize, deploy the application, and start a tunnel to the Minikube cluster.
Once the application is fully launched, the services will be exposed by the following ports
Storage: 14200
IdentityProvider: 15100
APIGateway: 16000
To deploy the application to Azure Kubernetes Service, you'll need to have the following set up:
The DNS zone and domain name are required for domain-name-based routing. The Kubernetes cluster is also integrated with ingress-nginx, external-dns and cert-manager which automatically manage the DNS records and TLS certificates for the services.