update
This commit is contained in:
215
README.md
215
README.md
@@ -1,41 +1,218 @@
|
|||||||
# 📋 Java Testing System - Microservices
|
# 📋 Java Testing System - Microservices
|
||||||
|
|
||||||
Dự án này là một hệ thống Microservices backend được xây dựng trên nền tảng **Spring Boot**, sử dụng **MongoDB** làm cơ sở dữ liệu chính và **Redis** để khóa giftcode-user tránh tình trạng thao tác quá nhanh. Toàn bộ hệ thống được đóng gói và quản lý bằng **Docker Compose**.
|
Hệ thống **Microservices** backend được xây dựng trên nền tảng **Spring Boot**, triển khai kiến trúc **Saga Pattern** để xử lý distributed transactions. Hệ thống sử dụng **MongoDB** làm cơ sở dữ liệu chính, **Redis** cho distributed locking và caching, được đóng gói hoàn toàn bằng **Docker Compose**.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🚀 Các dịch vụ chính
|
## 🎯 Tổng Quan Hệ Thống
|
||||||
|
|
||||||
|
Hệ thống bao gồm **2 microservices độc lập** giao tiếp với nhau qua **REST API**, sử dụng **Saga Pattern** với **compensating transactions** để đảm bảo tính nhất quán dữ liệu trong môi trường phân tán.
|
||||||
|
|
||||||
|
### 🔄 Luồng Hoạt Động Chính (Saga Pattern)
|
||||||
|
|
||||||
|
```
|
||||||
|
User Service GiftCode Service
|
||||||
|
| |
|
||||||
|
|---(1) Reserve---------------> |
|
||||||
|
| (Đặt trước gift code) | - Validate gift code
|
||||||
|
| | - Check usage history
|
||||||
|
| | - Create RESERVED transaction
|
||||||
|
|<---(2) Return Amount-----------|
|
||||||
|
| |
|
||||||
|
| (3) Process Local: |
|
||||||
|
| - Add balance to user |
|
||||||
|
| - Create RedeemLog |
|
||||||
|
| |
|
||||||
|
|---(4) Confirm----------------> |
|
||||||
|
| | - Update to CONFIRMED
|
||||||
|
| | - Increase usageCount
|
||||||
|
|<---(5) Success----------------|
|
||||||
|
| |
|
||||||
|
| (6) Update log to SUCCESS |
|
||||||
|
```
|
||||||
|
|
||||||
|
**Xử lý lỗi:**
|
||||||
|
- ❌ Lỗi ở bước 3 → Gọi `cancel()` để rollback
|
||||||
|
- ⏱️ Lỗi ở bước 4 → `RetryConfirmScheduler` tự động retry
|
||||||
|
- 🔄 Không confirm sau 5 phút → `ReclaimScheduler` tự động cancel
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 Các Dịch Vụ Chính
|
||||||
|
|
||||||
| Dịch vụ | Port | Công nghệ | Mô tả |
|
| Dịch vụ | Port | Công nghệ | Mô tả |
|
||||||
| :--- | :--- | :--- | :--- |
|
| :--- | :--- | :--- | :--- |
|
||||||
| **User Service** | `8601` | Spring Boot, MongoDB | Quản lý danh tính và thông tin người dùng. |
|
| **User Service** | `8601` | Spring Boot, MongoDB | Quản lý người dùng và xử lý áp dụng gift code |
|
||||||
| **Giftcode Service** | `8602` | Spring Boot, MongoDB | Quản lý, tạo và kiểm tra mã quà tặng. |
|
| **GiftCode Service** | `8602` | Spring Boot, MongoDB, Redis | Quản lý mã quà tặng và xử lý giao dịch redeem |
|
||||||
| **Redis** | `6379` | Redis | Bộ nhớ đệm dùng chung cho các service. |
|
| **Redis** | `6379` | Redis | Distributed locking và caching |
|
||||||
| **MongoDB** | `27017` | MongoDB | Cơ sở dữ liệu NoSQL chính của hệ thống. |
|
| **MongoDB** | `27017` | MongoDB | Cơ sở dữ liệu NoSQL chính |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🛠 Yêu cầu hệ thống
|
## 🧑💼 User Service (Port: 8601)
|
||||||
|
|
||||||
Trước khi bắt đầu, hãy đảm bảo máy tính của bạn đã cài đặt:
|
### Chức Năng Chính
|
||||||
* **Docker** & **Docker Compose**
|
Quản lý thông tin người dùng và xử lý việc áp dụng mã quà tặng.
|
||||||
* **Java 21** (Nếu muốn build code thủ công)
|
|
||||||
* **Maven 3.9+** (Nếu muốn build file Jar thủ công)
|
### API Endpoints
|
||||||
|
|
||||||
|
#### **Quản lý User**
|
||||||
|
- **`POST /users`** - Tạo người dùng mới
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"name": "Nguyen Van A",
|
||||||
|
"email": "user@example.com",
|
||||||
|
"password": "password123",
|
||||||
|
"phone": "0123456789",
|
||||||
|
"sex": "MALE"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- **`GET /users/{id}`** - Lấy thông tin user theo ID
|
||||||
|
|
||||||
|
- **`GET /users?page=0&size=10`** - Lấy danh sách users (có phân trang)
|
||||||
|
- Sắp xếp theo `createdAt` giảm dần
|
||||||
|
- `page`: số trang (default: 0)
|
||||||
|
- `size`: kích thước trang (default: 10, max: 100)
|
||||||
|
|
||||||
|
#### **Áp Dụng Gift Code**
|
||||||
|
- **`POST /users/apply-gift-code`** - User sử dụng mã quà tặng
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"userId": "507f1f77bcf86cd799439011",
|
||||||
|
"giftCode": "WELCOME2024"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
**Response:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"message": "Gift code applied successfully",
|
||||||
|
"status": "success",
|
||||||
|
"amount": 100000,
|
||||||
|
"transactionId": "uuid-transaction-id"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Data Models
|
||||||
|
- **User**: `id`, `name`, `email`, `password`, `phone`, `sex`, `balance`, `status`, `createdAt`, `updatedAt`
|
||||||
|
- **RedeemLog**: `transactionId`, `userId`, `giftCode`, `amount`, `status` (PENDING_CONFIRM/SUCCESS)
|
||||||
|
|
||||||
|
### Background Jobs
|
||||||
|
- **RetryConfirmScheduler** (mỗi 60 giây)
|
||||||
|
- Tự động retry các giao dịch `PENDING_CONFIRM`
|
||||||
|
- Đảm bảo eventual consistency khi network lỗi
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 📦 Hướng dẫn cài đặt và khởi chạy
|
## 🎁 GiftCode Service (Port: 8602)
|
||||||
|
|
||||||
|
### Chức Năng Chính
|
||||||
|
Quản lý mã quà tặng, kiểm soát việc sử dụng, và xử lý giao dịch redeem với distributed locking.
|
||||||
|
|
||||||
|
### API Endpoints
|
||||||
|
|
||||||
|
#### **Quản lý Gift Code**
|
||||||
|
- **`POST /gift-codes`** - Tạo mã quà tặng mới
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"type": "WELCOME",
|
||||||
|
"multiUse": true,
|
||||||
|
"onePerType": true,
|
||||||
|
"usageLimit": 1000,
|
||||||
|
"amount": 100000,
|
||||||
|
"startAt": "2024-01-01T00:00:00Z",
|
||||||
|
"endAt": "2024-12-31T23:59:59Z"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- Tự động generate `code` từ `type` (sử dụng SHA-256)
|
||||||
|
|
||||||
|
- **`GET /gift-codes?page=0&size=10`** - Lấy danh sách gift codes
|
||||||
|
|
||||||
|
- **`GET /gift-codes/{code}`** - Lấy thông tin gift code theo mã
|
||||||
|
|
||||||
|
#### **Xử Lý Giao Dịch (Internal APIs)**
|
||||||
|
- **`POST /gift-codes/reserve`** - Đặt trước gift code (Saga Step 1)
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"transactionId": "uuid",
|
||||||
|
"userId": "507f1f77bcf86cd799439011",
|
||||||
|
"code": "WELCOME2024"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
**Kiểm tra:**
|
||||||
|
- ✅ Gift code tồn tại và active
|
||||||
|
- ✅ Chưa hết hạn (startAt, endAt)
|
||||||
|
- ✅ Còn lượt sử dụng (usageLimit vs usageCount)
|
||||||
|
- ✅ User chưa dùng code này (nếu onePerType = true)
|
||||||
|
- 🔒 Sử dụng Redis Lock để tránh race condition
|
||||||
|
|
||||||
|
- **`POST /gift-codes/confirm`** - Xác nhận giao dịch (Saga Step 3)
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"transactionId": "uuid"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- Cập nhật: RESERVED → CONFIRMED
|
||||||
|
- Tăng `usageCount`
|
||||||
|
- Lưu vào `GiftCodeUsage` history
|
||||||
|
|
||||||
|
- **`POST /gift-codes/cancel`** - Hủy giao dịch (Compensating Transaction)
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"transactionId": "uuid"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- Cập nhật: RESERVED → CANCELLED
|
||||||
|
- Rollback, không tăng usageCount
|
||||||
|
|
||||||
|
### Data Models
|
||||||
|
- **GiftCode**: `id`, `code`, `multiUse`, `onePerType`, `type`, `usageLimit`, `usageCount`, `startAt`, `endAt`, `active`, `amount`
|
||||||
|
- **RedeemTransaction**: `transactionId`, `userId`, `giftCode`, `amount`, `status` (RESERVED/CONFIRMED/CANCELLED)
|
||||||
|
- **GiftCodeUsage**: `userId`, `giftCode`, `type`, `usedAt`
|
||||||
|
|
||||||
|
### Business Logic
|
||||||
|
- **multiUse**: Cho phép nhiều user sử dụng cùng 1 code
|
||||||
|
- **onePerType**: Mỗi user chỉ được dùng 1 lần cho mỗi loại (type)
|
||||||
|
- **usageLimit**: Giới hạn tổng số lần sử dụng
|
||||||
|
- **Validation**: Kiểm tra expired, active, usage limit
|
||||||
|
|
||||||
|
### Background Jobs
|
||||||
|
- **ReclaimScheduler** (mỗi 60 giây)
|
||||||
|
- Tìm transaction RESERVED quá 5 phút
|
||||||
|
- Tự động cancel để giải phóng gift code
|
||||||
|
- Xử lý trường hợp User Service crash
|
||||||
|
|
||||||
|
### Concurrency Control
|
||||||
|
- 🔒 **Redis Distributed Lock** (timeout: 10 giây)
|
||||||
|
- Key format: `giftcode:lock:{code}`
|
||||||
|
- Đảm bảo atomic operation khi nhiều request đồng thời
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🛡️ Cơ Chế Đảm Bảo Tính Nhất Quán
|
||||||
|
|
||||||
|
1. **Redis Distributed Lock** - Tránh race condition
|
||||||
|
2. **Transaction Status Tracking** - Theo dõi RESERVED/CONFIRMED/CANCELLED
|
||||||
|
3. **Retry Mechanism** - Tự động retry confirm nếu network lỗi
|
||||||
|
4. **Timeout Reclaim** - Tự động hủy transaction bị stuck
|
||||||
|
5. **Usage History** - Kiểm tra lịch sử để enforce onePerType rule
|
||||||
|
6. **Saga Pattern** - Compensating transactions cho rollback
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🛠 Yêu Cầu Hệ Thống
|
||||||
|
|
||||||
|
- **Docker** & **Docker Compose**
|
||||||
|
- **Java 21** (nếu build thủ công)
|
||||||
|
- **Maven 3.9+** (nếu build thủ công)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📦 Hướng Dẫn Cài Đặt và Khởi Chạy
|
||||||
|
|
||||||
### 1. Build và chạy toàn bộ bằng Docker Compose
|
### 1. Build và chạy toàn bộ bằng Docker Compose
|
||||||
Mở Terminal/CMD tại thư mục gốc của dự án và chạy lệnh sau:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Xóa sạch các container cũ và build lại từ đầu
|
# Xóa sạch các container cũ và build lại từ đầu
|
||||||
docker-compose down
|
docker-compose down
|
||||||
docker-compose up -d --build
|
docker-compose up -d --build
|
||||||
|
|
||||||
### 2. có thể chạy bằng dev IDE. yêu cầu có docker local.
|
|
||||||
docker run -d -p 27017:27017 --name mongo mongo:7
|
|
||||||
docker run -d -p 6379:6379 --name redis redis:7
|
|
||||||
Reference in New Issue
Block a user