1. Tổng quan kiến trúc dữ liệu#
API sử dụng 2 database cho 2 loại dữ liệu khác nhau:| Database | Công nghệ | Mục đích |
|---|
| MySQL | Relational DB | D ữ liệu cấu trúc: users, servers |
| MongoDB | Document DB | Task pool: keyword tasks, anchor text tasks |
| Redis | Cache | Cache kết quả anchor text (TTL 5 phút) |
2. MySQL — Bảng quan hệ#
2.1. Bảng users#
Quản lý tài khoản người dùng và phân quyền.
| Column | Type | Constraint | Default | Mô tả |
|---|
id | INT | PRIMARY KEY, AUTO_INCREMENT | — | ID user |
name | VARCHAR(255) | NOT NULL | — | Tên hiển thị |
password | VARCHAR(255) | NOT NULL | — | Mật khẩu (đã hash bcrypt) |
email | VARCHAR(255) | UNIQUE, NOT NULL | — | Email đăng nhập |
first_name | VARCHAR(255) | NULL | — | Họ |
last_name | VARCHAR(255) | NULL | — | Tên |
role | TINYINT | NOT NULL | 1 | Phân quyền: 0 = admin, 1 = user |
created_at | DATETIME | — | AUTO | Thời điểm tạo |
updated_at | DATETIME | — | AUTO | Thời điểm cập nhật cuối |
deleted_at | DATETIME | NULL | — | Soft delete (GORM model) |
| Giá trị | Tên | Mô tả |
|---|
0 | admin | Toàn quyền quản trị |
1 | user | Người dùng thông thường |
2.2. Bảng servers#
Danh sách worker server để phân phối tác vụ tìm kiếm.
| Column | Type | Constraint | Default | Mô tả |
|---|
id | INT | PRIMARY KEY, AUTO_INCREMENT | — | ID server |
name | VARCHAR(255) | NOT NULL | — | Tên server |
ip | VARCHAR(255) | NOT NULL | — | Địa chỉ IP của server |
is_active | TINYINT(1) | NOT NULL | 0 | 1 = server đang hoạt động |
is_priority | TINYINT(1) | NOT NULL | 0 | 1 = server ưu tiên (weight 5 vs 2) |
limit_process | INT | NOT NULL | — | Số tác vụ tối đa server có thể xử lý đồng thời |
current_process | INT | — | 0 | Số tác vụ đang chạy hiện tại |
created_at | DATETIME | — | AUTO | Thời điểm tạo |
updated_at | DATETIME | — | AUTO | Thời điểm cập nhật cuối |
deleted_at | DATETIME | NULL | — | Soft delete (GORM model) |
Server có is_priority = true → weight 5
Server có is_priority = false → weight 2
Tasks được phân phối theo tỷ lệ trọng số giữa các server active
3. MongoDB — Collections#
3.1. Collection keyword_pool_tasks#
Task pool cho tìm kiếm keyword. Documents được thêm vào bởi /search/ và được cron job xử lý mỗi 60 giây.
| Field | Type | Mô tả |
|---|
_id | ObjectID | ID duy nhất (auto-generated với primitive.NewObjectID()) |
keyword | String | Từ khoá cần tìm kiếm |
result_num | Int | Số kết quả mong muốn |
engine | String/Enum | Search engine sử dụng |
device | String/Enum | Loại thiết bị (desktop / mobile) |
device_os | Int | OS của device: 0 = Windows/Android, 1 = MacOS/iOS |
webhook_url | String | URL nội bộ API sẽ nhận kết quả từ worker (do API tự tạo) |
proxy_url | String | URL API để worker gọi lấy proxy |
search_youtube | Bool | true = tìm cả YouTube |
search_image | Bool | true = tìm cả Google Image |
searched | Int | Số lần đã thử tìm kiếm |
status | Int | Trạng thái task: 0 = new, 1 = processing |
geo_location | Object | Vị trí địa l ý (tuỳ chọn) |
geo_location.lat | Float64 | Vĩ độ (-90 đến 90) |
geo_location.lng | Float64 | Kinh độ (-180 đến 180) |
| Giá trị | Tên | Mô tả |
|---|
0 | Status_New | Task mới, chưa được giao |
1 | Status_Processing | Đang được worker xử lý |
{WEBHOOK_UPDATE_SEARCH_RESULT}/{task_id}?hook_url={client_webhook_url}
3.2. Collection anchor_text_tasks#
Task pool cho tìm kiếm anchor text. Documents được thêm vào bởi /anchor-text/search và được cron job xử lý mỗi 60 giây.
| Field | Type | Mô tả |
|---|
_id | ObjectID | ID duy nhất (auto-generated) |
domain | String | Domain cần tìm anchor text |
anchor_key | []String | Danh sách anchor key cần tìm |
webhook_url | String | URL nội bộ API để nhận kết quả từ worker |
proxy_url | String | URL API để worker gọi lấy proxy |
searched | Int | Số lần đã thử tìm kiếm (tối đa 10 lần) |
status | Int | Trạng thái: 0 = new, 1 = processing |
| Giá trị | Tên | Mô tả |
|---|
0 | Status_New | Task mới |
1 | Status_Processing | Đang xử lý |
Webhook URL format (do API tự sinh):{WEBHOOK_UPDATE_SEARCH_ANCHOR_TEXT}/{task_id}?hook_url={client_webhook_url}
3.3. Cấu trúc AnchorText kết quả (từ worker callback)#
{
"task_id": "string",
"domain": "example.com",
"anchor_key": ["key1", "key2"],
"result_status": 1,
"proxy": {
"host": "proxy.example.com",
"port": 8080,
"username": "user",
"password": "pass"
},
"search_data": {
"url": "https://example.com/page",
"anchor_text": [
{
"key": "anchor key",
"link": "https://target.com",
"element": "<a href='...'>text</a>"
}
]
}
}
ResultStatus values (AnchorText):| Giá trị | Tên | Mô tả |
|---|
0 | Status_Unknown | Không xác định |
-1 | Status_Error | Lỗi khi tìm kiếm |
-2 | Status_NotFound | Không tìm thấy |
-3 | Status_Captcha | Bị chặn bởi captcha |
1 | Status_Success | Tìm kiếm thành công |
4. Redis — Cache#
4.1. Cache anchor text kết quả#
| Key pattern | Value | TTL |
|---|
{domain}_anchor_text | JSON string của UpdateSearchAnchorTextRequest | 5 phút |
{domain}_{anchor_key_1}_{anchor_key_2}... | JSON string của kết quả search | 5 phút |
Mục đích: Nếu cùng một domain/anchor key được request lại, API trả ngay từ cache mà không cần giao task cho worker, sau đó xoá task khỏi pool.
5. Auto Migration#
Khi AUTO_MIGRATE_DATABASE=true trong .env, API sẽ tự động tạo/cập nhật schema MySQL khi khởi động.Các bảng được migrate: users, servers.Ngày cập nhật 2026-03-31 01:59:03