- Project Overview
- Architecture
- Implementation
Walgreens-Replica is a microservices-based platform designed to replicate the core functionalities of the Walgreens pharmacy management system. 🏥 Focused on efficiency and user accessibility, the system provides comprehensive services ranging from administrative controls to customer interactions. Engineered to handle robust traffic and secure data transactions, Walgreens-Replica utilizes cutting-edge technologies to ensure operational reliability and scalability. 🌟
View the User Management Architecture diagram.
View the Payment Architecture diagram.
View the Product Architecture diagram.
View the Order and Cart Architectures.
The system utilizes a variety of databases tailored to specific needs:
- PostgreSQL: Employs a robust relational centralized database for structured data storage and management. Used in User Management and Payment microservices to ensure data consistency and integrity due to their need for complex transactional operations.
- NoSQL (Apache Cassandra): Utilizes a scalable and distributed NoSQL database for handling large volumes of unstructured data with high availability and fault tolerance. This is employed by the Product, Order, and Cart microservices, where quick data access and high scalability are crucial.
- Firebase: Integrates a cloud-based database solution for media storage, facilitating efficient storage and retrieval of media files with minimal latency.
- Redis: Implements an in-memory data store used as a cache across all aforementioned services, optimizing response times and reducing computational overhead by caching frequently accessed data.
🐘 PostgreSQL
In the system architecture, PostgreSQL is employed for the User Management and Payment microservices, which require consistent and reliable data handling capabilities. This centralized database supports complex queries and transactions, ensuring data integrity and consistency necessary for sensitive operations such as user data management and financial transactions.👁 Apache Cassandra
Apache Cassandra is chosen for the Product, Order, and Cart microservices due to its high performance in environments that demand scalability and high-speed access to large volumes of data. Its distributed nature supports rapid growth and data distribution across multiple nodes, ensuring reliability and speed during high-demand periods.🔥 Firebase
Firebase serves as the media server for the system, providing a cloud-based solution for storing and serving media content. Its real-time database and storage capabilities enable seamless integration with the application, allowing users to upload, retrieve, and stream media files with minimal latency. Firebase's scalability and reliability ensure uninterrupted access to media content, while its authentication and security features safeguard sensitive data. By leveraging Firebase as a media server, the system delivers a seamless and responsive multimedia experience to users across platforms.💾 Redis
Redis plays a pivotal role in the system architecture, serving as a high-performance caching layer for optimizing data access and response times. Utilized across various microservices, Redis efficiently stores and retrieves frequently accessed data, such as session information, user preferences, and temporary application state. Its in-memory data storage and support for data structures enable fast and reliable caching, reducing the need for repeated computations and database queries. By leveraging Redis, the system enhances scalability, resilience, and overall performance, ensuring a seamless and responsive user experience. This caching mechanism significantly reduces the load on the database servers, alleviating potential bottlenecks and enhancing overall system performance by minimizing the need for repetitive and resource-intensive database queries.- All microservices are implemented using Java Spring Boot ☕.
- They consume messages from the Apache Kafka message broker and respond through Apache Kafka MQ as well.
- Requests are cached in Redis, so if the same request is sent more than once, there is no need to recompute the response every time and fetch the data again from the database as it can be retrieved directly from the cache 🗃️.
- In some cases, a microservice would have to communicate with another one to complete a certain functionality, which is done through Apache Kafka MQ. Every microservice can be scaled up or down independently of other microservices to adapt to the amount of incoming traffic.
👥 User Management Microservice
The User Management Microservice primarily focuses on user authentication (Login & Registration), implemented using Spring Boot Security. This service interacts mainly with PostgreSQL for user data storage and management. Additionally, to optimize authentication performance, the service caches the generated JWT tokens upon successful login in a shared Redis cache. This microservice also handles common operations shared by all users, such as changing usernames/passwords and managing user-related functionalities.💳 Payment Microservice
The Payment Microservice handles all aspects of financial transactions within the system, including processing payments, managing wallets, and maintaining transaction history. It employs PostgreSQL due to its strong ACID properties, ensuring data consistency and reliability for all financial operations. To enhance performance, frequently accessed data such as transaction histories and balance checks are cached using Redis, ensuring quick access and a smooth user experience.🛒 Cart Microservice
The Cart Microservice manages the shopping cart functionality, allowing users to add, update, or remove products from their cart. This service utilizes a NoSQL database for high performance and scalability, especially suitable for the dynamic nature of cart operations which require high-speed read and write capabilities. Redis is also used to cache cart data, significantly speeding up cart operations and improving response times during high traffic periods.📦 Orders Microservice
The Orders Microservice oversees the order processing workflow, from order placement to final delivery tracking. It leverages NoSQL databases to handle large volumes of orders with high availability and fault tolerance. This microservice is optimized for quick access to order data and scalability, using Redis to cache order statuses and summary data for fast retrieval.🛍️ Products Microservice
The Products Microservice is responsible for managing product listings, including creating, updating, and deleting product information. It uses NoSQL databases to store product data, ensuring scalability and rapid access when fetching product details. Redis is utilized here to cache frequently accessed data like product prices and descriptions, allowing for efficient and fast user interactions.The Media Server, powered by Firebase, serves as the cornerstone for handling multimedia content within the Guru.com replica platform. Leveraging Firebase's cloud-based storage and real-time database capabilities, this server facilitates seamless uploading, storage, and retrieval of media files, including images, videos, and documents. With Firebase's robust security features and scalability, the Media Server ensures secure and reliable access to multimedia content across devices and platforms.
Apache Kafka serves as the backbone for asynchronous communication between various microservices in this project 🚀. Kafka's message queues play a pivotal role in facilitating communication. Kafka consumes messages from different sources, including the User Management, Orders, Payment, Cart, and Products Microservices, each with its dedicated topic.
📦 Cleaning & Packaging Microservices
To Dockerize the application, the first step involved executing Maven commands to clean and package the microservices. This process entailed running mvn clean to remove any previously compiled artifacts and mvn package to compile the source code, run tests, and package the application into executable .jar files. Each microservice, structured as a Maven project, underwent this meticulous process to ensure that all dependencies were resolved and included in the packaged artifacts. These .jar files served as the executable units encapsulating the microservices, ready for containerization within Docker. This methodical approach laid a solid foundation for seamless integration and deployment within Docker containers.🔨 Building Docker Images
After cleaning and packaging the microservices, the next step involved building Docker images for each microservice. This process was accomplished using Dockerfile configurations, which specified the environment and dependencies required to run the microservice within a Docker container. Leveraging Docker's build capabilities, the Docker images were created with efficiency and consistency. Each Docker image encapsulated the packaged microservice artifact, ensuring that it could be executed within a containerized environment. This step ensured that the microservices were properly containerized and ready for deployment across various environments.📤 Uploading Images on DockerHub
Once the Docker images for the microservices were built, the final step involved uploading these images to DockerHub. DockerHub served as the central repository for storing and sharing Docker images, providing a convenient platform for managing and distributing containerized applications. Each Docker image was tagged with version information and securely uploaded to DockerHub. This process made the Docker images accessible online and facilitated seamless deployment across different environments. By leveraging DockerHub, it was ensured that the Docker images were readily available for deployment, streamlining the sharing and collaboration of containerized applications.In this project, the microservices were deployed locally on a Docker Kubernetes cluster along with Postgres, PgAdmin, RabbitMQ, Redis, Prometheus, and Grafana, enabling efficient management and scalability of the application components. Leveraging Docker containers orchestrated by Kubernetes, each microservice was encapsulated and deployed as a scalable and isolated unit. This deployment approach facilitated seamless integration and testing of the microservices in a controlled environment, allowing for rapid development iterations and ensuring consistency across deployments. Additionally, the use of Kubernetes provided automated deployment, scaling, and management capabilities, empowering the team to efficiently manage and orchestrate the deployment lifecycle of the microservices. Overall, deploying the microservices locally on a Docker Kubernetes cluster enhanced development agility and reliability, laying a solid foundation for future scalability and production deployment.