1. Bussiness | Logic
Traffic Tool
  • Traffic Tool Docs
    • Tổng Quan
    • project
      • admin
        • Hướng dẫn sử dung
          • Đăng Nhập & Xác Thực Hai Bước
          • Thống Kê Hệ Thống
          • Thống Kê Hàng Ngày
          • Tìm Kiếm Tự Động
          • Trung Tâm Báo Cáo
          • Quản Lý Tài Khoản
          • Quản Lý Server
          • Quản Lý Proxy
          • Quản Lý Gói Proxy
          • Quản Lý Nhà Cung Cấp Proxy
          • Quản Lý Backup Proxy
          • Quản Lý Tài Khoản Google
      • api + tool
        • Hướng dẫn sử dụng
          • User Guide
          • Setup Guide
        • Bussiness | Logic
          • 1. Thống kê hàng ngày (Daily Statistics)
          • 2. Thống kê hệ thống (System Statistics)
          • 3. Tìm kiếm tự động (Automated Discovery)
          • 4. Trung tâm Báo cáo (Report Center)
          • 5. Quản lý tài khoản (Account Management)
          • 6. Quản lý Hệ thống (System Management)
          • 7. Quản lý tài khoản Google (Google Account Management)
        • Architecture
          • Database Schema
          • System Architecture
          • Code Structure
          • Logs and Monitoring
          • Environment & Configuration
        • Deployment
          • Local
          • Staging
          • Product
  • Traffic Backend API
    • 🔑 Identity & Session
      • Đăng nhập hệ thống (Login)
      • Đăng ký tài khoản mới (Public)
      • Lấy danh sách người dùng (Phân trang)
      • Admin tạo người dùng mới
      • Lấy thông tin cá nhân hiện tại
      • Khởi tạo bảo mật 2FA
      • Xác thực mã OTP
      • Chi tiết người dùng theo ID
      • Cập nhật thông tin người dùng
      • Xóa tài khoản người dùng
      • Đổi mật khẩu
      • Kiểm tra Cấu hình Thông báo Telegram Toàn hệ thống
      • Bật/Tắt Thông báo Telegram Toàn cục
    • 📁 Campaign Management
      • Danh sách Chiến dịch Toàn cầu
      • Khởi tạo Chiến dịch Mới
      • Chi tiết Chiến dịch
      • Cập nhật Chiến dịch
      • Xóa Chiến dịch
      • Tắt/Mở Chiến dịch (Hàng loạt)
      • Dữ liệu Hình mẫu SEO (Negative SEO)
    • ⚙️ Project Mechanics
      • Danh sách Dự án (Projects List)
      • Khởi tạo Kịch bản Mô phỏng
      • Lấy chi tiết cấu hình Dự án
      • Cập nhật Kịch bản chạy
      • Xóa Dự án
      • Chỉnh sửa Hàng loạt (Bulk)
      • Bật/Tắt Dự án
    • 👤 Profile Management
      • Danh sách Vân tay số (Profiles Data)
      • Tạo Hồ sơ Đơn lẻ (Tạo Vân tay mới)
      • Nhập kho Tài khoản Email (Bulk Import)
      • Chi tiết Session/Cookies
      • Chỉnh sửa Hồ sơ/Ghi chú
      • Xóa Vân tay số và Dữ liệu Local
      • Mở khóa Captcha/Trạng thái Blocked
      • Tra cứu Kho Profile Khả dụng
      • Báo cáo Sức khỏe Kho Tài Khoản
    • 🦾 Worker Interface
      • Đăng ký Khởi tạo Node (Handshake)
      • Nhịp Tim Khảo Sát Tình Trạng (Heartbeat)
      • Nhận Cấu hình Bypass & Hệ thống
      • Kéo (PULL) Nhiệm vụ Traffic SEO
      • Báo cáo Sự cố Node (Crash Report)
    • 📊 Report: Execution
      • Kéo Công việc Báo cáo (Worker Pull)
      • Quản lý Giám sát Nhiệm vụ (Task Dashboard)
      • Bắn Lại Báo Cáo Thất Bại (Manual Retry)
    • 📊 Report: Discovery
      • Danh sách Tên miền Chờ Xử Lý (Discovery Pool)
      • Nhập Mục Tiêu Thủ Công (Manual Insert)
      • Kích hoạt Heuristic Scanner (Cào tự động)
      • Chi tiết Bằng Chứng (Evidence Data)
      • Dán nhãn Vi Phạm / Cập nhật Screenshot
      • Loại Bỏ Mục Tiêu
      • Duyệt Yêu Cầu (Approve to Execution)
    • 📊 Report: Platforms Configuration
      • Truy vấn Danh sách Nền tảng Đối tác (Vendor)
      • Tạo Nền tảng Vendor Báo cáo Mới
      • Bật/Tắt Trang báo cáo theo Loại
      • Cập nhật Metadata Trang
      • Xóa Trang Báo Cáo
      • Lấy Cài đặt LLM cho Vendor cụ thể
      • Cập nhật Cài đặt Tạo mẫu LLM
      • Lấy Cấu hình Schema Biểu mẫu cho Vendor
      • Cập nhật Yêu cầu Trường Biểu mẫu
    • 📊 Report: Email Automation
      • Danh sách SMTP/Mailer Server
      • Thêm kết nối SMTP Mới
      • Nhật ký Nhiệm vụ Gửi Mail (Email Log)
      • Phân tích Tỉ lệ Chuyển đổi (Email Delivery Analytics)
    • 🌐 Global Proxies
      • Danh sách Kho Proxy Phân trang (Proxy Pool)
      • Thêm mới Tuyến IP (Bulk Import)
      • Cập nhật Thông tin máy chủ Proxy
      • Xóa Proxy (Thu hồi tài nguyên)
      • Kích hoạt Xoay vòng (Rotate IP) Cưỡng bức
    • 📈 System Intelligence
      • Báo cáo Luồng Bảo mật Hợp nhất (Colossal Report)
      • Bản Đồ Lưu Lượng GeoIP (Heatmap)
    • 🪝 Webhook Integrations
      • Callback Hoàn tất Gói Lưu lượng SEO (Traffic Node)
      • Callback Thông báo Hoàn tất Bắn Report AI
    • Schemas
      • AppError
      • LoginRequest
      • UserResponseDto
      • UserModel
      • CreateUserRequest
      • UpdateUserRequest
      • PagingInfo
      • ProfileModel
      • CreateProfileRequest
      • BulkImportProfileReq
      • UpdateProfileRequest
      • CampaignModel
      • CampaignConfigs
      • CreateCampaignRequest
      • UpdateCampaignRequest
      • BulkUpdateCampaignStatusReq
      • NegativeSeoData
      • CreateProjectRequest
      • UpdateProjectRequest
      • ProjectModel
      • BulkUpdateProjectRequest
      • ProjectAttribute
      • WorkerHandshakeRequest
      • WorkerHandshakeResponse
      • WorkerHeartbeatPayload
      • WorkerGlobalSettings
      • TaskPullRequest
      • WorkerFatalLog
      • TaskModel
      • TaskTrafficType
      • TaskUpdateDto
      • ReportTaskModel
      • ReportTaskResult
      • PCReportResponse
      • SummaryStats
      • DailyStats
      • BrandStats
      • ProfileStats
      • ReportTaskItem
      • ReportSiteItem
      • CreateReportSiteRequest
      • GPTConfig
      • ResponseConfig
      • FieldConfig
      • ReportDomainsResponse
      • ReportDomainItem
      • AddReportDomainRequest
      • UpdateReportDomainRequest
      • BulkUpdateDashboardRequest
      • ProxyModel
      • CreateProxyRequest
      • UpdateProxyRequest
      • SMTPServerConfig
      • EmailTaskLog
      • GeoLocation
  • Traffic Tools V2 API
    • Tasks
      • Lọc và Truy vấn Nhật ký Phiên Duyệt lẻ
      • Get all tasks
      • Nạp Kết Quả Chạy của Puppeteer (Update Callback)
      • Xóa toàn bộ Tasks lẻ
      • Get all tasks
      • Xóa một Task (ID)
    • Group task
      • Đẩy nhóm công việc Traffic theo lô (Batch Pipeline Task Creation)
      • Lấy sơ đồ trạng thái hàng đợi Group Tasks
      • Endpoint /api/task-traffics/
      • Clear/Flush Hàng đợi Group Task (Kill Queue)
      • Endpoint /api/task-traffics/
      • Xóa 1 nhóm nhiệm vụ (Theo ObjectID Mongoose)
      • Parse chuỗi Proxy
    • Test
      • Kiểm tra Proxy hoạt động ngầm
      • Endpoint /api/test
      • Kho Fingerprint Thử Nghiệm
      • Endpoint /api/test/account-stats
      • Endpoint /api/test/session-recommendation
      • Endpoint /api/test/check-browser
      • Endpoint /api/test/clear-browser-sessions
    • Proxies
      • Lấy kho Proxy server
      • Khai báo Pool Tuyến Proxy mới
      • Get all proxies
      • Get all proxies
      • Xóa toàn bộ Proxy
      • Get all proxies
      • Xóa Proxy theo ID
      • Reset lại số đếm tiến trình (Cron Proxy Thread)
    • Report Platforms
      • Submit report to multiple platforms
      • Submit report to specific platform
      • Get available platforms
      • Get platform statistics
      • Health check
    • Reports
      • Create a new report
      • Create a new report
      • Get report by ID
      • Get report by ID
      • Get report statistics
      • Get report groups
      • Get report groups
      • Get report group
      • Add report to group
      • Bulk add reports to group
      • Get report group statistics
      • Get analytics data
      • Get platform success rates
      • Get reports by platform
      • Get reports by group
      • Create test reports in bulk
    • Test Report
      • Test Microsoft report submission
      • Test AdGuard report submission
      • Test Google Ads report submission
      • Test Spamhaus report submission
      • Test ESET report submission
      • Test multi-platform report submission
      • Get available platforms
    • ESET Test
      • Simple test
      • Minimal POST test
      • Generate ESET report content
      • Get sample test data
      • Test form filling
      • Test full form submission
    • Spamhaus Test
      • Simple test
      • Minimal POST test
      • Generate Spamhaus report content
      • Get sample test data
      • Test Spamhaus form filling
      • Test full Spamhaus form submission
    • Report Scheduler
      • Get report scheduler statistics
      • Process ad detection result
      • Submit a scheduled report
      • Start report scheduler
      • Stop report scheduler
      • Get scheduler status
      • Process scheduled reports
      • Test browser session (non-headless)
      • Test report submission (non-headless)
    • Comprehensive Analytics
      • Get comprehensive dashboard analytics
      • Get overview statistics
      • Get brand-wise statistics
      • Get daily statistics
      • Get platform success rates
      • Get account performance
      • Get summary report
    • Search
      • Ra lệnh Máy Lọc Dữ Liệu TOP SEO Hàng Loại (Scraper Engine)
      • Đếm tổng số dòng tìm kiếm (Length)
    • Report Tasks
      • Tạo chiến dịch Report (Auto Spawn 14 tasks)
      • Tạo chiến dịch Report Form hàng loạt (Bulk Abuse Report)
      • Create Direct Report (Từ API hệ thống thay vì Frontend)
      • Tạo Nhiệm Vụ Sinh Email Khiếu nại (Automated Bulk Mail Spam)
      • Worker Pull - Lấy task Báo cáo đang Pending
      • Worker Trả kết quả (Report Status)
      • Danh mục Platfoms & Providers
      • Dashboard Statistic Báo Cáo
      • Force Run Cronjob
    • Monitor
      • Xuất dữ liệu đo đếm Hardware (Telemetry OS Watchdog)
    • Schemas
      • CreateTask
      • UpdateTask
      • CreateTaskGroupRequest
      • CreateProxy
      • CreateSearch
      • ReportTaskCreation
      • CreateEmail
      • CreateMultipleSearchRequest
      • CreateMultipleReportRequest
      • UpdateReportStatusRequest
      • TestProxyRequest
  1. Bussiness | Logic

6. Quản lý Hệ thống (System Management)

Quản Lý Hệ Thống (Server Management) — Technical Documentation

Module: server-management
Frontend: admin/src/views/server-management/
Backend:

  • api/internal/server/
  • api/internal/proxy/
  • api/internal/proxy_packages/
  • api/internal/proxy_providers/
  • api/internal/backup_proxy/
    Database tables: servers, proxies, proxy_packages, proxy_providers, backup_proxies

I. Tổng quan module

Module Quản Lý Hệ Thống là một module lớn, quản lý toàn bộ hệ thống cơ sở hạ tầng phục vụ việc chạy traffic, bao gồm các máy chủ (worker nodes) và mạng lưới proxy để giả mạo IP.

Module bao gồm 5 trang (tabs) chính:

TrangRoute nameBackend FolderChức năng chính
Quản Lý Serverserver_management.serverserverQuản lý các worker server thực thi task.
Quản Lý Proxyserver_management.proxyproxyQuản lý danh sách IP Proxy, gán với các Gói.
Quản Lý Gói Proxyserver_management.packageproxy_packagesQuản lý giá tiền và phân loại Proxy.
Quản Lý Nhà Cung Cấpserver_management.providerproxy_providersNguồn cung cấp Proxy (ví dụ Proxifly).
Quản Lý Backup Proxy(riêng biệt)backup_proxyNguồn proxy dự phòng tự chạy Health Check.

Kiến trúc UI chung:

  • Sử dụng cấu trúc IndexView.vue làm Layout chính chứa RouterLink tab menu.
  • RouterView render các component tab con, kèm Transition fade-transform.
  • Mỗi tab là một thư mục riêng biệt (VD: servers/, proxies/) có mô hình chuẩn:
    IndexView.vue + stores/ + composables/ + components/.
  • UI Tables dùng component tùy chỉnh + API pagination + Pinia để lưu trạng thái filter.

II. Quản Lý Server (Quản lý Hoạt động)

Frontend thư mục: server-management/servers/
Backend API route: /api/servers/

Quản lý danh sách các Worker Nodes — các máy sẽ định kỳ gọi lên hệ thống để nhận Task và thực thi (Browser-based tasks).

1. Store & Filter (useServerStore)

type UrlSearchParams = {
  page: number;
  limit: number;
  keywords?: string; // Tên server
  is_active?: number; // 1: Hoạt động, 0: Tạm dừng
};
  • Refresh tự động hoặc qua nút "Chạy lại" trên UI.
  • Có tính năng bulk operations để quản lý hàng loạt.

2. DataTable (servers/components/DataTable.vue)

CộtBinding fieldTính năng đặc biệt
CheckboxselectionChức năng Bulk Delete / Refresh.
TênnameSort alphabet.
IPipĐịa chỉ IP tĩnh của Server.
Hoạt độngis_activeNSwitch inline toggle. Gọi API cập nhật ngay.

Tính năng nổi bật: Inline Optimistic Update
Khi user gạt công tắc "Hoạt động":

  1. Lưu row.id vào set updatingRows (hiển thị loading trên công tắc).
  2. Optimistic update: Cập nhật row.is_active = value ngay trên UI.
  3. Cập nhật vào Pinia serverStore.listData để đảm bảo reactivity.
  4. Gọi apiServers.changeStatus(row.id, value).
  5. Nếu API rollback (error) → Vue sẽ tự catch error và nên trả lại trạng thái (tuy logic hiện tại chỉ ném lỗi, không revert state UI — điểm cần cải thiện).

Tính năng Bulk Actions (Sử dụng composable useBulkSelection)

  • Render component <BulkActions> để xóa hoặc làm mới nhiều server một lúc.
  • Lấy danh sách ID đã checked → apiServers.bulkDelete(ids) → Fetch lại page=1.

3. Modals & Data Formats

CreateModal / UpdateModal:

  • Sử dụng Form Hook useFormData()
  • Payload: { name: "", ip: "", is_active: true, limit_process: 10 }
  • Chú ý: Backend có các field limit_process, current_process nhưng trên form hiện đang lưu default limit_process = 10. Các input nhập số quá trình đang bị comment out ở template.

4. Backend Server Service (api/internal/server)

Model MySQL (servers table):

type Server struct {
	Name           string `gorm:"size:255;not null"`
	IsActive       bool   `gorm:"default:0"` // Type boolean nhưng query từ frontend hay truyền 0/1
	IP             string `gorm:"size:255;not null"`
	LimitProcess   int    `gorm:"column:limit_process"`
	CurrentProcess int    `gorm:"column:current_process"`
}

Các Endpoint chính:

RouteHandlerMô tả
GET /GetListWithPaginationPhân trang, có tích hợp filter theo name và is_active.
GET /mongo-serversGetMongoServersEndpoint lấy từ MongoDB cho hệ thống tracking cũ/khác.
GET /reportGetReportBáo cáo tỷ lệ process / success / fail của server.
PUT /update-status/:idChangeStatusHandler chuyên biệt cho Switch Toggle.
GET /health-check/statsGetHealthCheckStatsBáo cáo sức khỏe.
GET /task-monitor/statsGetTaskMonitorStatsHiện đang trả placeholder.

Thay đổi trạng thái (ChangeStatus):

func (h *Handler) ChangeStatus(c *fiber.Ctx) error {
	id := strconv.Atoi(c.Params("id"))
	var dto dto.ChangeStatus // { is_active: bool }
	err = h.serverService.UpdateActive(uint(id), dto.IsActive)
	return c.JSON(...)
}

III. Quản Lý Proxy

Frontend thư mục: server-management/proxies/
Backend API route: /api/proxies/ (dự kiến)

Là trang phức tạp nhất, cho phép liệt kê và thao tác trên lượng lớn IPs, gán nó vào Gói và Nhà cung cấp.

1. Store, Filters & Bulk Load

Pinia useProxyStore bao gồm các dependencies dropdown:
Mỗi trang Proxy khi load phải gọi cùng lúc 3 API:

Promise.all([
  proxyStore.fetchData(), // Lấy danh sách Proxy IPs
  proxyStore.fetchProvidersSearch(), // Lấy list Nhà Cung Cấp đổ vào Dropdown
  proxyStore.fetchPackagesSearch({ limit: 100 }), // Lấy list Gói Proxy đổ vào Dropdown
]);

Bộ Lọc Phức Tạp (UrlSearchParams):

  • recorded_at: Lọc theo khoảng thời gian "Ngày hết hạn" (expired_start, expired_end).
  • proxy_provider_id: ID Provider. Khi chọn Provider → Tự động trigger fetchPackagesSearch để lấy Gói thuộc về Provider đó bằng việc reset URL Package ID.
  • proxy_package_id: Lọc sâu theo Gói Proxy.
  • is_active: Dropdown select "" (Tất cả), "true", "false". Note: Khởi tạo ép buộc giá trị rỗng để hiển thị All mặc định.
  • keyword: Tìm kiếm chuỗi văn bản (thường là địa chỉ IP).

2. Các Action Tùy Chỉnh (Top Bar Buttons)

Trong màn hình proxies/IndexView.vue có 3 nút:

  1. Update proxy (UploadIcon):

    • Gọi apiProxies.uploadProxyv2()
    • Backend sẽ chạy cron/service import hàng loạt.
    • Frontend parse JSON summary trả về.
    • Phản hồi form: Thành công: X/Y providers, Z proxies.
  2. Tải file lên (UploadIcon):

    • Mở ImportDomainModal (thực chất là Import Proxy IPs Modal). Cho phép admin upload file JSON/TXT để push mass IPs.
  3. Thêm mới (AddIcon):

    • Mở Form thêm 1 proxy bằng tay qua CreateModal.

IV. Quản Lý Gói Proxy (Packages)

Frontend thư mục: server-management/packages/

Proxy được nhóm lại thành các "Package" (gói dịch vụ). Ví dụ Gói "IP Tĩnh US", Gói "IP Xoay VN".

1. Dependencies

Màn hình Package gọi state listProvidersSearch từ Store để cho phép chọn Package thuộc Provider nào.

onBeforeMount(() => {
  Promise.all([
    packageStore.fetchData(),
    packageStore.fetchDataProvider(), // Lấy list Providers
  ]);
});

2. Form Model (Create/Update)

Tùy chọn tạo ra một package sẽ gắn với proxy_provider_id. Điều này setup 1 relation 1-N: Provider -> N Packages -> M Proxy IPs.


V. Quản Lý Nhà Cung Cấp Proxy (Providers)

Frontend thư mục: server-management/providers/

Cấp cao nhất của cấu trúc Proxy hằng bậc: Quản lý đối tác bán Proxy (Ví dụ: WebShare, Proxifly, vv).

Backend Flow

Chủ yếu là ứng dụng CRUD chuẩn + Status Toggling.

  • Provider table lưu: Name, Active
  • statusOptions: Hoạt động (true) / Tạm dừng (false).

VI. Quản Lý Backup Proxy

Frontend thư mục: server-management/backup-proxies/
Backend API route: /api/backup-proxies/

Hệ thống Backup Proxy hoạt động độc lập (nằm ngoài route con của server-management) và chủ yếu focus vào việc query external service tự động và Monitor trạng thái die/live (Health Check).

1. Store, Filters

Lọc theo đặc điểm proxy tĩnh:

  • Lọc country: List cứng Vietnam, Thailand, Singapore, Japan, Korea, vv...
  • Lọc is_working: Đang hoạt động / Không hoạt động
  • Khóa tìm kiếm keyword: Thường là IP hoặc Host.

2. Hai nút Action chính

  • Import Proxifly: Nút gọi apiBackupProxies.importFromProxifly(). Kéo API từ service bên thứ 3 (Proxifly) đẩy thẳng vào MySQL.
  • Health Check: Nút gọi apiBackupProxies.healthCheck(). Bắn ping và proxy auth request tới tất cả DB Backup Proxy để check sống / chết lập tức trên Backend. Cập nhật is_working.


VII. Schema Data Models (MongoDB)

Tất cả các thành phần về Proxy (Khác với servers nằm trong MySQL) đều được lưu trữ hoàn toàn trong MongoDB.

1. proxies collection

type Proxy struct {
ID                primitive.ObjectID `bson:"_id"`
Ip                string             `bson:"ip"`
Port              int                `bson:"port"`
Username          string             `bson:"username"`
Password          string             `bson:"password"`
RotateUrl         ProxyRotateUrl     `bson:"rotate_url"`
RotateTime        int                `bson:"rotate_time"` // Giây
NextRotate        time.Time          `bson:"next_rotate"` // Thời gian tính toán cho chu kỳ đổi
LastUsedAt        time.Time          `bson:"last_used_at"`
InUse             int                `bson:"in_use"` // Số task đang dùng
DomainUsed        []TaskUseProxy     `bson:"domain_used"` // Danh sách domain đã/đang dùng proxy này
DomainBlocks      []string           `bson:"domain_blocks"` // Danh sách domain block proxy này
IsCaptcha         bool               `bson:"is_captcha"`
IsError           bool               `bson:"is_error"`
ErrorCount        int                `bson:"error_count"` // Đếm chuỗi lỗi liên tiếp
IsActive          bool               `bson:"is_active"`
IpPublic          string             `bson:"ip_public"` // IP thực sự sau khi proxy đổi
Region            string             `bson:"region"`
DisableAutoRotate bool               `bson:"disable_auto_rotate"`
IsRotating        bool               `bson:"is_rotating"` // Đang trong quá trình đổi (lock)
RotateServer      *string            `bson:"rotate_server"` // Server đang thực hiện việc đổi proxy
Area              ProxyArea          `bson:"area"` // global / vn
ProxyPackageID    primitive.ObjectID `bson:"proxy_package_id"`
ExpiredAt         *time.Time         `bson:"expired_at"` // Ngày hết hạn (đồng bộ với Proxy Provider)
}

2. proxy_packages collection

type ProxyPackages struct {
ID              primitive.ObjectID  `bson:"_id"`
Code            string              `bson:"code"`
Name            string              `bson:"name"`
Price           int                 `bson:"price"`
Note            string              `bson:"note"`
ProxyProviderID *primitive.ObjectID `bson:"proxy_provider_id"` # Liên kết đến Provider
Active          bool                `bson:"active"`
}

3. proxy_providers collection

Sử dụng custom struct FlexibleTime để parse thời gian từ BSON có thể lưu dưới dạng String / Int64 Timestamp / DateTime từ các tool export / import đa dạng.

type ProxyProvider struct {
ID        primitive.ObjectID `bson:"_id"`
Name      string             `bson:"name"`     // Ví dụ: KiotProxy, ProxyXoay, Tinsoft
Account   string             `bson:"account"`
Domain    string             `bson:"domain"`
Active    bool               `bson:"active"`
}

4. backup_proxies collection

type BackupProxy struct {
ID           primitive.ObjectID `json:"id" bson:"_id"`
Host         string             `json:"host" bson:"host"`
Port         int                `json:"port" bson:"port"`
Username     string             `json:"username" bson:"username"` // Authentication
Password     string             `json:"password" bson:"password"`
Country      string             `json:"country" bson:"country"`   // Quốc gia chỉ định (VN, TH, US...)
IPPublic     string             `json:"ip_public" bson:"ip_public"`
IsWorking    bool               `json:"is_working" bson:"is_working"` // Kết quả Health Check
LastTested   time.Time          `json:"last_tested" bson:"last_tested"`
SuccessCount int                `json:"success_count" bson:"success_count"`
FailureCount int                `json:"failure_count" bson:"failure_count"` // Nếu quá 3 -> fail
Source       string             `json:"source" bson:"source"` // Ví dụ: "Proxifly"
}

VIII. Luồng Xoay Proxy Tự Động (Cron)

Chức năng Rotate Proxy là phần nhân lõi nhất của module Proxy, đảm bảo IP liên tục thay đổi, tránh bị tracking hoặc captcha từ các nền tảng Search Engine, Ads.
Handler File: api/internal/proxy/cron/start_rotate.go

1. Hàm StartRotateV2() (Mới nhất)

Mục tiêu: Tính toán xoay nhiều proxy cùng lúc bằng cách dùng các Worker Servers (để tránh IP máy chủ gốc kết nối đến Provider quá nhiều gây rate-limit hoặc chặn).

Bước thực thi:

  1. Lấy tất cả Proxy hợp lệ cần xoay (GetManyCanRotate()). Điều kiện: is_active = true, disable_auto_rotate = false, next_rotate <= NOW(), is_rotating = false.
  2. Lấy tất cả Servers đang hoạt động (GetActiveServers()).
  3. Lấy số liệu xoay (serverRotateCounts) của từng Server hiện tại từ DB để Load Balancing.
  4. Chọn ra server đang chịu tải xoay ít nhất (count_current).

Luồng Retry & Rotate per Proxy:

// Lặp qua danh sách cần xoay
for i := 0; i < proxyLength; i++ {
    proxy := proxies[i]

    for _, server := range mapServer {
        // Skip server đã crash/lỗi
        if server.IsError { continue }

        // Tìm server có tải xoay đang dưới/bằng mức cân bằng
        if server.Count <= countCurrent {
            // FIRE HTTP POST sang Server (webhook callback)
            result := api_proxy.CreateProxyRotate(server.Ip, body{
                WebhookUrl: <Hệ_thống_gốc>/webhook/proxy-rotation-result/<Proxy_ID>,
                RotateUrl: proxy.RotateUrl,
                IpPublic:  proxy.IpPublic,
                ... auth info ...
            })

            if !result { server.IsError = true; continue }

            // Khóa (lock) proxy này báo là đang xoay
            c.proxyService.UpdateOneIsRotating(proxy.ID, true, &server.Ip)
            break // Done queueing proxy này
        }
    }
}

Nhận diện Webhook kết quả:
Sau khi Server Node xoay thành công, nó đẩy HTTP Request về lại WebhookUrl kèm theo IP Public mới.
Nếu nhận thành công:

  1. proxy.Reset(): Đưa Error = 0, xóa list DomainBlocked.
  2. proxy.IpPublic = mới, proxy.NextRotate = NOW + rotate_time.
  3. Lưu vào DB MongoDB.

IX. Luồng Health Check - Backup Proxy

Sử dụng Backup Proxy phòng ngừa trường hợp các provider lớn die.

Hàm MarkFailed():

func (bp *BackupProxy) MarkFailed() {
bp.FailureCount++
bp.LastTested = time.Now()
bp.UpdatedAt = time.Now()
// Failover logic - Quá ngưỡng fail -> đánh sập status
if bp.FailureCount >= 3 {
bp.IsWorking = false
}
}

Hàm MarkWorking():
Nếu Check thành công 1 lần, reset IsWorking = true ngay lập tức và tăng SuccessCount. Rất hữu ích khi các list proxies trôi nổi có thể sống lại bất ngờ.


X. Kết luận Kiến trúc & Security Notes

  1. Bảo mật: Table Server dùng IsActive logic Optimistic update trên frontend khiến UX rất mượt. Nhưng API change status không có cơ chế Rollback() trực tiếp khi lỗi, chỉ bắn thông báo.
  2. Cron Optimization: Load Balancing số lượng rotate tasks trên các worker bằng cách map số task hiện có (serverRotateCounts) giúp Server Node (worker) không bị kiệt quệ tài nguyên.
  3. Database Scale: Tách proxy info ra khỏi MySQL sang MongoDB (đặc tính no schema mạnh) do dữ liệu proxy (DomainBlocks dạng mảng, DomainUsed lưu object nested) scale rất to nếu DB lớn.
  4. Resiliency: Cơ chế tự retry (tối đa 3 lần cho cùng 1 payload xoay vòng), Lock Proxy (IsRotating) tránh Duplicate Request lên proxy providers.

XI. Hệ thống Notifications (Telegram)

Hệ thống có một cơ chế cron job riêng (cron_notificate_to_telegram.go) dùng thư viện github.com/go-co-op/gocron/v2 để tự động báo cáo các proxy/package sắp hết hạn qua Telegram (pkg.Env.ChatNotiId).

Hai luồng báo cáo chính:

  1. monthly_expiration_report: Chạy theo pkg.Env.ScheduleMonthlyReport.
  2. weekly_expiration_report: Chạy theo pkg.Env.ScheduleWeeklyReport.

Cơ chế hoạt động:

s := scheduler.StartScheduler()

s.NewJob(
    gocron.CronJob(pkg.Env.ScheduleWeeklyReport, true),
    gocron.NewTask(c.sendWeeklyReport),
    gocron.WithName("weekly_expiration_report"),
    gocron.WithSingletonMode(gocron.LimitModeWait), // Tránh spam cron đè nhau
)

Mục đích: Báo cáo cho đội ngũ vẩn hành biết trước 7 ngày, hoặc trong tháng những nhà cung cấp proxy nào sắp hết hạn/hết tiền (Zing, ProxyXoay) dựa trên hạn của Proxy Packages.


XII. Cấu trúc và API Endpoints (Server Management)

Dưới đây là chi tiết tất cả các endpoint được định nghĩa trong api/internal/server.

1. GET /api/servers/ (Pagination)

Handler: GetListWithPagination

  • Controller File: get_list_with_pagination.go
  • Workflow: Lấy Context -> Phân tích Query string (page, limit, keywords, is_active) -> Validate qua Go-Playground -> Tính toán PagingData -> Trả về messages.SuccessDataPagination().

2. GET /api/servers/get-all (Danh sách đầy đủ)

Handler: GetList
Dành cho các dropdown chọn server trên hệ thống mà không cần phân trang.

3. GET /api/servers/mongo-servers

Sử dụng MongoDB thay cho MySQL với những server được khởi tạo trên collection cũ phục vụ tương thích ngược.

4. GET /api/servers/report

Data Model Trả Về: ServerReportResponse
Trả về report biểu đồ giờ của các Server, với chi tiết các lỗi nhúng trong Mongo:

  • Success, Fail, Waiting, Unknown, Error, NotFound, Captcha.
  • Đồng thời track các lỗi cụ thể trong lúc xoay proxy: RSuccess, RFail, RUnknown, RError, vv...

5. Khối Health Check

  • GET /api/servers/health-check/stats: Trigger ping TCP đến các Worker Server.
  • GET /api/servers/task-monitor/stats: Theo dõi phân phối Task có bị nghẽn (bottleneck) không.
  • GET /api/servers/failure-records & failure-stats: Ghi nhận những lúc worker down hoặc timeout kết nối API.

XIII. Cấu trúc và API Endpoints (Proxy Management)

Module Proxy là phức tạp nhất do nó là tổ hợp giữa CRUD truyền thống trên MongoDB và các hệ thống bulk import + API 3rd party.

1. Các lệnh CRUD cơ bản

  • POST /api/proxies/: Tạo mới 1 proxy.
  • GET /api/proxies/: Fetch danh sách phân trang (kèm filters proxy_provider_id, proxy_package_id, exp time...).
  • GET /api/proxies/:id: Chi tiết 1 proxy.
  • PUT /api/proxies/:id/change-status: Bật/Tắt hoạt động thủ công bằng NSwitch ngoài frontend (optimistic update).
  • PUT /api/proxies/:id: Cập nhật cấu hình: Username, Password, IP Public, Rotate URL, Disable Auto Rotate.
  • DELETE /api/proxies/:id: Xóa proxy đơn lẻ khỏi DB MongoDB.
  • POST /api/proxies/bulk-delete: Cho phép Frontend tick nhiều rows và gọi đồng loạt để xóa theo IDs.
  • DELETE /api/proxies/: (DeleteAll) Xóa sạch rổ proxy đang hiện hữu tùy theo package.

2. Các lệnh Excel & Bulk Export

  • GET /api/proxies/demo-excel: Tải file sample mẫu header để nhập proxy bằng file.
  • GET /api/proxies/export: Export danh sách filter hiện tại ra dạng file .xlsx.
  • POST /api/proxies/multiple: Thêm nhanh một list proxy IP:Port dạng văn bản.

3. Cổng Integration Các Nhà Cung Cấp Mới

Lưu cấu trúc module sử dụng file rẽ nhánh riêng để maintain cho từng Provider Endpoint:

  • import_kiot_proxy.go
  • import_proxyxoay_proxy.go
  • import_zing_proxy.go
  • import_enode_proxy.go
  • import_m2_proxy.go

Luồng Handler chung ImportAllProxies:
Được kích hoạt khi bấm "Update Proxy" ở Frontend Proxy/IndexView.vue (apiProxies.uploadProxyv2()).

// Khởi chạy hàng loạt goroutines dùng WaitGroup
var wg sync.WaitGroup
var mu sync.Mutex

// Ví dụ import Zing
h.importZing(ctx, req.Zing, &wg, &mu, results, errors, &successProviders, &totalProxies, providerDetails)

// Đợi tất cả fetch API xong hoặc Context Timeout (2 phút)
select {
case <-ctx.Done(): ...
case <-done: ...
}

Quản lý Token tĩnh / động:
importZing check Request token -> File Config -> Env Params. Tự động parse và push update/create Proxy objects vào collection proxies trong MongoDriver dựa theo danh sách mới kéo về từ API của nhà cung cấp. Thời gian import song song chỉ mất vài giây.


XIV. Data Models - Typescript & Pinia (Frontend)

Mỗi store useXXXStore.ts trong các tab Proxy đều ánh xạ cấu trúc backend cực kỳ chuẩn.

1. useServerStore.ts

Chứa các biến statusOptions (Hoạt động/Tạm dừng) và typeOptions (record-domain/check-domain).
Định nghĩa Pagination Type standard của Naive UI Table:

listData: Pagination<Server.Item> | undefined;

Chức năng Validation tự dọn rác URL:

resetUrlParams() {
    this.urlParams.page = zod.number().min(1).default(1).catch(1).parse(Number(this.urlParams.page))
    this.urlParams.limit = zod.number().min(1).default(20).catch(20).parse(Number(this.urlParams.limit))
}

2. useProxyStore.ts

Đây là state management khổng lồ giữ toàn bộ lookup table:

  • listProviders và listProvidersSearch (Mapped Options có format {label: Name, value: ID}).
  • listPackages và listPackagesSearch: Mapping theo proxy_provider_id làm điều kiện phụ.

Mỗi khi load, bảng Proxy phải pull:

  1. apiProxies.getList với expired_start và expired_end mapping từ array [string, string] của component Naive NDatePicker.
  2. Truy xuất lỗi trực tiếp in lên notification message bằng custom Utils useHelper().showMessageError().

3. useBackupProxyStore.ts

Mang đặc thù riêng, BackupProxy có list Option Code cứng:

countryOptions: [
  { label: "Vietnam", value: "VN" },
  { label: "Thailand", value: "TH" },
  //...
];

XV. Chi tiết Composables - useDataTable.ts

1. Servers Table Render Logic

Tính STT phân trang bằng logic: (page - 1) * limit + index + 1.

Cột Hoạt động là h() function render dynamic:

render: (row: Server.Item) =>
  h(NSwitch, {
    value: row.is_active,
    loading: updatingRows.value.has(row.id),
    onUpdateValue: async (value: boolean) => {
      // ... Logic call apiServers.changeStatus
    },
  });

Sắp xếp (Sorter) theo Client-side (localeCompare cho tên và timestamp trừ thời gian cho date).

2. Cột Tuỳ chọn của Proxy và Provider

Các module Proxy đều sử dụng NButton Action lồng bên trong div Flex Gap:

h('div', { class: 'flex gap-2 justify-center' }, [
    h(NButton, { text:true, onClick: EditIcon }, [...]),
    h(NButton, { text:true, onClick: DeleteIcon }, [...])
])

Dialog xóa confirm hiển thị Tên Item trực tiếp. Ví dụ: "Bạn có chắc chắn muốn xóa hệ thống KiotProxy?"


XVI. Chi tiết Phân Quyền Kiến Trúc Hybrid File/Database

Khối System/Server có đặc trưng về Data storage rất độc đáo:

  1. MySQL Instances: Dành cho các module tĩnh, cần ranh giới quan hệ mạnh (Foreign Keys).

    • servers (id, name, ip, limit_process)
    • Hoạt động ổn định với GORM.
  2. MongoDB Database: Dành cho mạng Proxy khổng lồ và Bulk Inserts.

    • Ưu điểm: Khả năng chứa Nested Array Document cho Proxy (TaskUseProxy - chứa Domain Used History).
    • Quản lý Object Lifecycle dài hạn tốt, truy vấn primitive.ObjectID linh hoạt.

Vị trí của Repository sẽ kết nối song song các Dependency Injection bằng Container.Invoke.

Ví dụ tại file server Handler handler.go:

injection.Container.Invoke(func(
    service *service.Service,
    activityLogService *activityLogService.Service // Từ package ActivityLog lưu mysql
) {
    h = &Handler{
        serverService: service,
        activityLogService: activityLogService,
    }
})

XVII. UI Components: DatePicker và Search

Kỹ thuật Performance:
Để tránh Request API đập liên tục vào Backend mỗi khi người dùng gõ phím vào khung IP Search, toàn bộ các sự kiện thay đổi Form List filter đều map vào onChangeFilter.
Hàm này đính kèm hook @vueuse/core debounce:

const onChangeFilter = useDebounceFn(() => {
  proxyStore.onChangePage(1);
}, 500); // Delay 0.5 giây kể từ khi kết thúc gõ.

NaiveUI Table config:

  • :scroll-x="1000": Đảm bảo giao diện không gãy ở màn hình tablet.
  • :max-height="620": Thanh cuộn nội tuyến trong block table.
  • Thêm BulkActions component tùy chỉnh ở phía trên NDataTable để count số checkbox.

XVIII. Xử Lý Logic Ngoại Lệ của Frontend

Trong useDataTable.ts khi thực thi API xóa/sửa với Provider API, Response của Error rất đa dạng theo cấp độ. Frontend của Traffic Tool V2 bắt buộc xử lý qua chaining optional properties phòng trừ backend trả về Null Object thay vì Error Message JSON:

const errorMessage =
  error?.response?.data?.message || // Lỗi từ API Fiber
  error?.message || // Lỗi Axios Network
  "Có lỗi xảy ra khi cập nhật"; // Lỗi Undefined Catch

Kết quả báo cáo thành công (Import all) cũng làm tương tự do JSON parse có chèn Object Summary nếu thành công có điều kiện.


XIX. Tổng kết quy trình Lifecycle hoàn chỉnh

Một Proxy Service sẽ đi qua vòng đời:

  1. Thiết lập: Mua Proxy Provider (Kiot/ProxyXOAY) -> Thêm record vào Table Provider. Gán API Token vào Codebase (Env).
  2. Kéo dữ liệu: Nút ImportAll / Cron Fetch chạy API nhà rực cấp -> Lấy Proxy Nodes -> Phân bổ thành các Proxy Packages -> Lưu hàng loạt Proxy IP vào MongoDB proxies. Tính Default ExpiredAt.
  3. Phân phối: Các Worker (servers table mysql) ping lên API StartRotateV2, Backend lựa chọn Server rảnh nhất và giao Proxy để gọi webhook Rotate IPs.
  4. Sử dụng: Task Manager gán Task vào Worker, bắt đầu browser theo Proxy đó. (Lưu danh sách DomainUsed vào Array JSON trong Proxy Document để tránh trùng DNS).
  5. Dọn rác: Cron telegram gửi cảnh báo gia hạn khi Package gần ngày hết. Proxy lỗi 3 lần liên tiếp sẽ bị IsError = true và ngắt dòng Task.

XX. Kiến trúc Tích hợp Database (MySQL & MongoDB)

Module "Quản Lý Hệ Thống" là một điển hình của kiến trúc lưu trữ lai (Hybrid Storage) kết hợp sức mạnh của Relational Database (MySQL) và NoSQL (MongoDB).

1. Tại sao dùng Hybrid Storage?

  • MySQL (servers table):
    • Quản lý Master/Worker node cần độ ổn định tuyệt đối và liên kết người dùng (Users -> CreatedBy).
    • Schema rõ ràng: ID, Name, IP, Max/Current Process.
    • Phù hợp với GORM migrations và các query đơn giản.
  • MongoDB (proxies, proxy_packages, proxy_providers collections):
    • Số lượng record rất lớn (lên tới hàng nghìn hoặc chục nghìn proxy).
    • Cần chứa dữ liệu phi cấu trúc và dynamic array:
      • Array domain_used (chứa các struct history của quá trình quay website).
      • Lịch sử xoay proxy.
      • FlexibleTime - để hứng các format time lộn xộn từ các Provider bên thứ ba mà không gây crash API (ProxyProvider.CreatedAt).
    • Hỗ trợ TTL Indexes và khả năng InsertMany cực nhanh.

2. Triển khai MongoDB Repository (Ví dụ: Proxy)

Trong api/internal/proxy/repository, thay vì dùng GORM, dự án dùng go.mongodb.org/mongo-driver.

func (r *Repository) GetOneCanRotate() (*proxy.Proxy, error) {
collection := r.Db.Collection(proxy.CollectionName)
filter := bson.M{
"is_active":           true,
"disable_auto_rotate": false,
"is_rotating":         false,
"next_rotate":         bson.M{"$lte": time.Now()},
}

options := options.FindOne().SetSort(bson.M{"last_used_at": 1})
var result proxy.Proxy
err := collection.FindOne(context.Background(), filter, options).Decode(&result)
return &result, err
}

Điều này giúp khả năng Queue Rotate Proxy trở nên mượt mà, hạn chế Table Lock thường thấy trên MySQL.


XXI. Chi tiết Kỹ thuật - Bulk Delete (Xóa Xếp Chồng)

Tính năng Bulk Delete được sử dụng rất nhiều ở cả 5 tab frontend nhằm dọn dẹp data hiệu quả.

1. Phía Frontend - Component BulkActions.vue

  • Component chuyên dùng để theo dõi selectedRowKeys.length.
  • Hiển thị băng rôn báo: "Đã chọn X mục".
  • Hai nút Delete và Refresh sẽ trigger events emit lên component cha DataTable.vue.
  • Cấu hình custom composable useBulkSelection<T> lưu state và binding UI dialog Native của Naive UI. Giúp hiển thị Loading spinner trên nút Xác nhận.

2. Phía Backend API - Xử lý Xóa Nhiều (proxy/handler/bulk_delete.go)

  • Payload: Mảng các IDs type string {"ids": ["mongo_hex_id1", "mongo_hex_id2"]}.
  • Parser primitive.ObjectIDFromHex(id) để cast sang MongoDB format.
  • Action: collection.DeleteMany(ctx, bson.M{"_id": bson.M{"$in": objectIDs}})

Đồng thời, đối với servers (MySQL) - API api/internal/server/handler/bulk_delete.go:

// GORM syntax cho Bulk Delete In Array
db.Where("id IN ?", ids).Delete(&Server{})

Hai công nghệ lưu trữ có 2 cách Bulk Delete khác nhau nhưng được che giấu phía sau 1 interface chung dành cho API Client (Frontend Axios).


XXII. Chi tiết API Export & File Demo

Module Proxy cho phép Export data ra Excel theo thời gian thực (real-time generated).

File: api/internal/proxy/handler/export.go
Library: github.com/xuri/excelize/v2

Flow Export:

  1. Lấy reqCtx có timeout (Vì export list >100.000 record cần thời gian xử lý dài).
  2. Gọi h.service.ExportProxy(reqCtx, req) lấy danh sách cấu trúc (Structs) đã filter từ DB.
  3. Tạo file excel in-memory:
    f := excelize.NewFile()
    // Gán headers: ID, IP, Port, Username, Rotate Time...
    // Tạo vòng lặp loop map dữ liệu
    f.SetCellValue(sheetName, cell, value)
    
  4. Tính toán giãn cột (Auto-fit Width) để data không bị đứt quãng.
  5. Set Headers http để force Download File:
    c.Set("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
    c.Set("Content-Disposition", "attachment; filename=proxies_export.xlsx")
    
  6. Stream File Data trực tiếp về qua socket f.Write(c).

Đây là phương thức Zero-Disk (Không cần write file tạm ra Server Disk), tối ưu bộ nhớ.


XXIII. Phân tích Các Module Frontend Chi Tiết

Sự nhất quán (Consistency) của hệ thống admin Vue.js được thể hiện rõ qua sự copy/paste layout các function ở store và view.

1. IndexView.vue (Cấu trúc chung)

Mọi tab đều có các thành phần template cố định:

<template>
  <div>
    <!-- Phần 1: Header + Breadcrumb Tooltip -->
    <PageHeader title="Quản lý ..." tooltip="..." />

    <!-- Phần 2: Filter Panel (Sử dụng NSelect, NInput, NDatePicker) -->
    <div class="mb-3 flex... gap-x-4">
      <!-- Các ô filter config debounce v-model gắn vào Store URL params -->
    </div>

    <!-- Phần 3: Bảng Dữ Liệu Container -->
    <PageBlock>
      <DataTable ... />
    </PageBlock>

    <!-- Phần 4: Teleported Modals -->
    <NModal v-model:show="store.stateModal.isShowCreateModal"> ... </NModal>
  </div>
</template>

2. Sự khác biệt giữa các Form Data Load

  • Với CreateModal: Fields luôn là form rỗng. onShow watch luôn gọi lại hàm resetForm() và clear validation errors.
  • Với UpdateModal: Truyền Property Hook id. Mỗi khi ID thay đổi -> Gọi fetchDataDetail() lấy dữ liệu từ DB, dùng Lodash _merge mixin vô formData Reactive State để form hiển thị giá trị.

3. Loading Status Matrix

Từng tab quản lý cẩn trọng state Fetching nhờ Pinia global context:

  • Khi đang fetch, toàn bộ Dropdown isDisabled=true & Button Search bị khóa loading để tránh user click liên tục tạo DDoS cục bộ.
  • Store phân chia state.isFetching (cho DataTable chính); state.isFetchingProviders / state.isFetchingPackages cho Select Dropdowns phụ.

XXIV. Import Đa Nền Tảng (Multi-Vendor Proxies)

Bài toán: Mỗi nhà cung cấp proxy có cấu trúc API trả về hoàn toàn khác nhau.

  • Proxifly: List Text IP:Port:User:Pass
  • ZingProxy: Trả về Array JSON với NodeId
  • KiotProxy: Trả về định dạng Object Map key.

Cách Giải Quyết OOP của Backend (Pattern Adaptor):
System tạo ra từng Handler tĩnh. importZing, importKiot, importProxifly.

Xử lý Auth Token Dẻo (Flexible Authentication Configuration):
Một điểm rất tinh tế trong Codebase (import_all_proxies.go) là tính năng fallback Token Auth theo Priority (Quyền ưu tiên):

  1. Request User (Frontend Gửi): Dùng token User tự nhập vào nếu có (Test mode).
  2. File Configuration: Load từ config.ProxyProviderTokens (Cache cục bộ từ System API lưu vào RAM).
  3. Environment: Fallback về .env configuration (Bảo chứng server-level).

Mảng này tích hợp thêm Function maskToken() cho Logging:

  • Mục đích: Không leak token nhạy cảm ra file log. Log Kibana/FluentD chỉ giữ lại định dạng an toàn "10_kys_first...10_kys_last". Giúp dev dễ check lỗi token chết mà không vi phạm Policy.

XXV. Các thành phần của Hệ thống Cron Mở Rộng

Ngoài Notification Telegram Cron và StartRotate Cron, thư mục api/internal/proxy/cron còn có thành phần rất thú vị:

  • change_active_cron.go: Cron quét định kỳ hệ thống để kiểm tra ExpiredAt của proxy packages và proxy provider. Tự động set IsActive = false (Tạm dừng) đối với Proxy nào đã hết hạn mua gói (Thường quét vào lúc 12:00 đêm).
  • Điều này khóa luồng Rotate, khóa việc assign Proxy vào Task, giúp giảm thiểu Bad Response 502/407 từ Proxy bên thứ ba khi Tool hết tiền gia hạn.

XXVI. Ghi chú bảo trì (Maintenance Checklist)

Để maintain Module Server - Proxy Management, các Kỹ sư phần mềm cần chú ý:

  1. MySQL Migration: Khi nâng cấp Model Server, hãy đảm bảo sử dụng Gorm AutoMigrate cẩn thận.
  2. MongoDB Consistency: Do Proxy không dùng khóa ngoại bảo vệ cứng (Do xài MongoDB với tham chiếu String), xoá Proxy_Packages sẽ sinh ra các Proxy bị mất Link "Package Name/ID" nhưng chưa được dọn dẹp. Cần có Cron CleanUp Mongo.
  3. CORS Timeout Webhook: IP các worker xoay Proxy phải được AllowList ở Firewall hoặc Cloudflare cho route /webhook/proxy-rotation-result.
  4. Log Rotation: Bảng Proxy IP Logs ghi nhận sự thay đổi IP liên tục 5 phút / lần cho mỗi Proxy, dễ bề phình to ổ cứng DB.
  5. UI Store State Caching: Cẩn thận khi Router.push từ tab này sang tab kia, Component tuy Destroy nhưng Pinia Store không Reset nếu dev quên gọi store.$reset(). May mắn là onUnmounted hook đã cover tốt được case gọi $reset.

Tóm lược

Module Server & Proxy Management thể hiện năng lực kiến trúc Distributed (Phân tán) cao độ của Team xây dựng app. Việc offload (chuyển tải) nhiệm vụ Xoay Proxy/Gửi Request cho các Node/Server "con" (Worker) giúp cho API của Admin Console (Master) luôn nhẹ, giữ UI VueJS mượt mà nhưng vẫn thao túng lượng lớn Network Request background hằng ngày.

XXVII. Mô hình Validation và Format Data của Frontend

Hệ thống cung cấp một cơ chế Ràng buộc toàn diện (Validation Rules) dựa trên naive-ui cho tất cả các Form Modal trong Module Server/Proxy để ngăn lỗi từ đầu vào.

1. File useFormData.ts (Quản Lý Server)

const formData = shallowReactive<Server.Create>({
  name: "",
  ip: "",
  is_active: true,
  limit_process: 10,
});
  • IP Address Validation: Thực tế hiện tại Server đang không có regex block IP cứng, giúp cấu hình được cả IP IPv6 lúng túng hoặc sub-domain tuỳ vào network (Ví dụ api-worker.domain.com:51000).

2. File useFormData.ts (Quản Lý Khách Hàng/Nhà Cung Cấp)

const rules: FormRules = {
  domain: [
    { required: true, message: "Tên miền không được để trống", trigger: ["blur", "input"] },
    {
      validator: (rule, value) => {
        if (!value) return true;
        // Tự động strip giao thức http:// hoặc https://
        const cleanedValue = value.replace(/^(https?:\/\/)/i, "");
        if (value !== cleanedValue) {
          formData.domain = cleanedValue;
          return true;
        }
        // Regex chuẩn RFC-1123 dùng cho Domain name
        const domainRegex = /^[a-zA-Z0-9][a-zA-Z0-9-]{0,61}[a-zA-Z0-9](?:\.[a-zA-Z]{2,})+$/;
        if (!domainRegex.test(cleanedValue)) {
          return new Error("Tên miền không hợp lệ");
        }
        return true;
      },
      trigger: ["blur"],
    },
  ],
};
  • Custom Validator này đảm bảo mọi Domain nhập vào DB luôn sạch, giúp cho tác vụ gọi API cào proxy phía backend dễ dàng dùng url.Parse() để process.

3. File useFormData.ts (Quản Lý Gói/Packages)

const formData = shallowReactive<Package.Create>({
  name: "",
  code: "",
  price: null,
  note: "",
  proxy_provider_id: null,
  active: true,
});
  • proxy_provider_id là Foreign Key mapping về MongoDB _id của bảng proxy_providers.
  • Trên Modal Create, Form Item Nhà cung cấp là NSelect map providerOptions (value: node.id). Không được để trống.

XXVIII. Đi Sâu Vào Flow Data Của Từng API Proxy Cụ Thể

1. API: POST /api/proxies/multiple

Sử dụng khi User import qua Modal nhập tay trên giao diện ImportDomainModal (thường là List IP Text String cực nhanh).
Cấu trúc xử lý Backend (Golang):

  • Tiếp nhận chuỗi Raw Text.
  • Cắt chuỗi bằng ký tự \n và Split theo delimiter (:, hoặc |).
  • Cast mảng thành chuẩn []Proxy và Insert song song bằng Bulk Operation (InsertMany) của mongo-driver.
  • Bỏ qua các line bị lỗi format (Tolerant parsing).

2. API: GET /api/servers/health-check/stats

Chạy một tiến trình Ping hoặc HTTP Request từ Node Manager tới tất cả Worker IP.
Mô hình trả về (Dummy in code nhưng đây là thiết kế chuẩn):

{
  "success": true,
  "data": {
    "server_123": { "status": "online", "latency": "23ms" },
    "server_456": { "status": "offline", "timeout": true }
  }
}

3. API Dọn Dẹp Cơ Sở Dữ Liệu Lỗi (DELETE /api/proxies/)

Đây là function DeleteAll(), không phải xóa Database, mà là xóa tất cả Proxy theo specific criteria.

  • Thường dùng trước khi update một Batch Proxies mới vào trong Gói (để ghi đè, làm mới những Proxy đã chết trong khi IP mới đã được mua).
  • Dùng bson.M{ "proxy_package_id": packageID } để chỉ định Scope cần dọn.

XXIX. Cơ Chế Báo Cáo Phân Tích Sự Cố (Failure Records) Của Server

Trong hệ thống Traffic liên tục gánh tải hàng triệu lượt search/click, việc Worker Network Issue là bình thường.
Các endpoints được thiết kế riêng cho việc gỡ lỗi:

  • GET /api/servers/failure-records: Liệt kê log của các Job không phản hồi từ Worker (Server down đột ngột hoặc mất kết nối).
  • GET /api/servers/failure-stats: Thống kê tần suất Lỗi trên tổng Task theo mỗi 15-phút. Từ đó Vẽ biểu đồ Real-time cho sysadmin xử lý Reboot worker từ xa.

(Note: Một số Handler này trong code source hiện trả về placeholder, nhưng kiến trúc đã chừa API cho tính năng này).


XXX. Những Thiết Kế UI Nâng Cao Đáng Chú Ý Khác

1. Transition Mode Between Tabs

Toàn bộ Quản lý hệ thống được gộp vào 1 Main Layout, bọc trong <RouterView>.

<RouterView v-slot="{ Component, route }">
  <Transition name="fade-transform" mode="out-in" appear>
    <component :is="Component" :key="route.name" class="flex-1" />
  </Transition>
</RouterView>

Thuộc tính mode="out-in" quy định: Tab cũ phải biến mất hoàn toàn xong Tab mới mới Fade vào. Điều này chống tình trạng giao diện nhảy giật khi 2 Data Table của Proxy và Server đồng loạt render hàng ngàn Node HTML cùng 1 DOM Tick.

2. Thiết Kế Styling Tabs (Branding)

Dùng Capsule shape Tabs: Đoạn SCSS sử dụng mã màu Teal backgroundColor: #0a4e4f; kèm shadow Black #000 0 0 4px đánh bật Menu Đang Hoạt Động (Active State) khỏi background #09484a0d.

3. Hiển thị Lệch Trang (Custom Pagination Message)

<p>
  Hiển thị từ {{ ((page - 1) * limit) + 1 }} đến {{ Math.min(page * limit, total) }} trên tổng {{
  total }}
</p>

Đoạn Message tính toán thủ công từ Response Meta Data thay vì dùng Message built-in của naive-ui để hỗ trợ tiếng Việt có tính cá nhân hóa tốt hơn.


XXXI. Lời Khuyên Mở Rộng Hệ Thống Định Tuyến (Routing & Scale)

Hệ thống quản lý hàng chục triệu Task, do đó Database MongoDB Proxy phải luôn được Index.
Cần đảm bảo Index MongoDB cho các field sau ở production:

  1. _id (Mặc định)
  2. is_active, is_rotating, disable_auto_rotate (Phục vụ cron GetManyCanRotate)
  3. next_rotate (Compound Index với các status, tăng tốc độ cron 10 lần).
  4. proxy_package_id (Phục vụ delete Bulk).
  5. ip (Phục vụ search Text).

Thách thức của Webhook Rotation:
Vì Webhook URL của Master (bên giao proxy) đưa cho mạng Worker gọi lại vào Callback endpoint WebhookUrl: pkg.Env.WebhookHost + "/webhook/proxy-rotation-result/" + id - Có thể tiềm ẩn rủi ro Security Webhook Forgery nếu worker không gửi kèm Signature. Giải pháp tương lai là chèn thêm X-Signature-Hmac cho payload của Worker Node.


XXXII. Tài Thiệu API Phụ Lục Toàn Cục

Phương ThứcTác Động Tới TableTrách Nhiệm Code (Mô hình MVC -> Fiber Handlers)Ghi Chú Bảo Mật
FindByIDserversTìm server bằng ID -> Trả ServerResponse DTO không chứa info nhạy cảmAPI Internal
GetDetailproxy_packagesLấy list Providers nhúng (Nested JSON) cùng lúc để bind vào Dropdown Edit FormRequire Role
ImportProxiesproxiesGọi API Zing / Webshare / Tinsoft... Map JSON schema tùy chỉnhCần Secret Keys
UpdateActiveMySQL/MongoDBLật State cờ ToggleFire and Forget
NewLogproxy_ip_logCập nhật Node Public IP để tracking các Blocked Domain (như Google/Facebook)Heavy Write

XXXIII. Chi Tiết Utility Composables Của Frontend

Bên cạnh useDataTable, thư mục composables của frontend còn chứa nhiều utilities cực kỳ quan trọng giúp các View trở nên gọn gàng.

1. useBulkSelection.ts (Global Utility)

Vị trí: admin/src/composables/useBulkSelection.ts
Đây là Generics Composable (<T>) quản lý state cho mảng các checkbox của Naive UI.

Luồng hoạt động:

  • Khai báo một Set<string | number> nội bộ tên là selectedRowKeys.
  • Cung cấp hành vi (Actions) handleBulkDelete, handleBulkRefresh.
  • Hiển thị Dialog (cảnh báo xác nhận) mỗi khi người dùng gọi các Action.
  • Auto clear (xóa mảng) selectedRowKeys.clear() tự động khi thực thi xong.
  • Trả về cờ hiệu isProcessing (boolean state) cho table bên ngoài để hiện thị spinner (như loading=$props.isProcessing).

Điều này đã thay thế hàng trăm dòng boilerplate code rải rác trong IndexView.vue của cả Servers, Proxies, Packages, Providers, và Backup Proxies.

2. useHelper.ts (Error Catcher)

Vị trí: admin/src/composables/utils.ts (Hành vi showMessageError)
Trung tâm map các loại lỗi từ HTTP Axios AxiosError sang Naive UI Message.

function showMessageError(error: any) {
  let msg = "Đã có lỗi xảy ra. Vui lòng thử lại!";

  // 1. Nếu backend format chuẩn JSON
  if (error?.response?.data?.message) {
    msg = error.response.data.message;
  }
  // 2. Fallback sang text lỗi thô
  else if (error?.message) {
    msg = error.message;
  }
  window.$message?.error(msg);
}

XXXIV. Vòng Đời Form Modal và Cleanup Logic

Mỗi Modal trong hệ thống sử dụng một thủ thuật v-model:show="isShow" để đồng bộ state tắt/mở kết hợp Lifecycle Hooks của Vue3.

1. The Reactivity Reset Trouble (Vấn Đề Reset State)

Tại sao Form Modal lại dễ bị lỗi lưu cache nhập liệu cũ?
Vue <NModal> của Naive UI chỉ render display: none (hoặc v-if) nhưng component con bên trong vẫn giữ nguyên trạng thái Reactive Objects. Nghĩa là: nếu bạn mở CreateModal (tạo nhà cung cấp), nhập "Tinsoft" xong bấm X (Tắt modal), lần sau mở lại chữ "Tinsoft" vẫn còn.

Cách giải quyết (watch(isShow))
Các File *Modal.vue (Ví dụ: CreateModal.vue) bắt buộc có đoạn mã Cleanup:

watch(isShow, newValue => {
  if (!newValue) {
    // Khi Modal bị đóng
    // 1. Reset manually fields (Nếu không dùng Object.assign)
    formData.name = "";
    formData.active = true;

    // 2. Clear đỏ Validation Naive Form
    formRef.value?.restoreValidation();
  }
});

2. Validation Trigger Modes

trigger: ['blur', 'input'] được set ở useFormData.ts:

  • blur: Người dùng click chuột ra ngoài ô input sẽ bắt đầu check. Thích hợp cho check độ dài rỗng (Required).
  • input: Khi đang gõ phím bắt đầu check (Ví dụ cho Regex check domain báo lỗi ngay từng nhịp phím).

XXXV. Các Mối Quan Hệ (Relations) ở Database MySQL và MongoDB

Dù không phải cùng chung 1 DB Engine, nhưng kiến trúc chia nhỏ Micro-level này cần một sự am hiểu ánh xạ khóa ngoại thủ công (Application Level).

Mối Quan Hệ Trong Module:

  1. Một Gói (Proxy Package) thuộc về Một Nhà Cung Cấp (Proxy Provider).

    • Lọc bằng field proxy_provider_id trên UI.
    • Thể hiện ở DTO: ProxyPackageResponse.ProxyProvider struct lồng ghép.
  2. Nhiều IP (Proxy) thuộc về Một Gói (Proxy Package).

    • Quản lý Proxy -> Import URL list -> Ánh xạ Proxy mới tạo vào proxy_package_id.

    • Vì nằm ở MongoDB, khi truy xuất danh sách Proxy (GetList()), Mongo Lookup Pipeline ($lookup) được dùng để pull thông tin Gói nhét vào biến proxy_package.

    • Pipeline sample GetList():

      {
        "$lookup": {
          "from": "proxy_packages",
          "localField": "proxy_package_id",
          "foreignField": "_id",
          "as": "proxy_package"
        }
      }
      
      
      // MongoDB array output phải được `$unwind` (bung mảng) thành object để match với struct Go.
      
  3. Mối Tương Tác: Proxy <-> Server:

    • Server MySQL có IP Tĩnh.
    • Proxy (MongoDB) có field ServerRotate *string. Ghi nhận IP Tĩnh của Server chịu trách nhiệm gửi Lệnh xoay của chính Proxy đó.
    • Mối quan hệ dạng N:1 lỏng lẻo. Database không hề có Constraint khoá ngoại nối vào nhau. Server sập -> CronRotate tự fail over tìm server khác nhờ cơ chế Loop Map Count.

XXXVI. Quản Lý Task Lỗi (Error Management của Module Proxy)

Module Proxy là một hệ thống không đáng tin cậy (Unreliable External Source). Các IP mua từ 3rd party (Ví dụ: KiotProxy) sẽ gặp tình trạng "chết IP", "Bad Gateway", "Xác thực Captcha quá nhiều lần" trên Google (khi kéo Traffic SEO).

Flow Ghi Nhận Captcha và Error Lên DB Proxy:

  1. Worker App (Node.js/Playwright)

    • Nhận task. Mở Browser chạy bằng Proxy http://usr:pwd@ip:port.
    • Nếu bị Cloudflare/Google ném trang Captcha chà bá -> Chụp ảnh ném vào Exception Log -> Worker gọi API về Master Master.
  2. API Endpoint Của Master (Nhận Kết Quả Error)

    • ProxyService.IncreaseError(objectID)
    • Cập nhật tài liệu proxy trên Mongo:
      update := bson.M{
          "$inc": bson.M{"error_count": 1},
          "$set": bson.M{
              "is_captcha": true,
              "is_error": true,
          },
      }
      
    • Lệnh Update sẽ làm tăng field error_count.
  3. UI Dashboard Phản Ứng Dữ Liệu:

    • Khi có is_error hoặc error_count cao, Proxy đó có thể được cảnh báo đỏ nếu làm tính năng Frontend Alert. UI admin có thể tracking các Proxy IP rác và tick nhiều dòng để Bulk Delete khỏi hệ thống, sau đó gọi "Upload URL mới" khôi phục số lượng IP cần thiết cho Gói.

XXXVII. Xử Lý Bất Biến (Idempotency) của API Import

Với chức năng "Tải file lên" (Bulk Import Modal Proxy IPs), người dùng có khuynh hướng nhập file .txt lặp lại nhiều lần.
Backend POST /api/proxies/multiple và POST /api/proxies/import phải tính phương án Check trùng lắp.

Giải pháp:

  • Do MongoDB collection proxies, IP có thể thay đổi nên khóa kiểm tra duy nhất phức tạp. Backend thường Query Array các Auth Token / Username / Hoặc RotateUrl của file xem đã tồn tại trong Database hay chưa.
  • Nhưng proxy xoay (Rotating Proxies) thì IP lúc nào cũng là 1 IP Cổng chuyển đổi (Cổng Gateway), còn IP Public luôn xoay.
  • Do đó Hệ thống lưu Port, RotateUrl và Proxy_package_id làm Identifier đối sánh.
  • Update Upsert (thêm nếu chưa có, ghi đè info nếu đã có):
    // Tuân thủ Upsert Model logic của Go-Mongo
    option := options.Update().SetUpsert(true)
    collection.UpdateOne(ctx, filter_tồn_tại, data, option)
    

XXXVIII. Những Vấn Đề Và Gợi Ý Tối Ưu Tương Lai (Technical Debt)

Dù codebase Server Management & Proxy rất hoàn thiện, dưới góc nhìn Kiến trúc, còn điểm có thể mở rộng:

  1. Vấn đề Locking Proxy: IsRotating hiện tại là Boolean Flag tại DB. Khi App Crash giữa chừng trong lúc Rotate, Cờ Rotating sẽ bị kẹt True vĩnh viễn (Deadlock proxy logic xoay).

    • Gợi ý Fix: Đổi cờ IsRotating thành RotatingLockedUntil (Timestamp). Ví dụ set (NOW + 30s). Nếu hết 30s mà cờ vẫn tồn tại thì Server mặc định coi như mở khóa (giống Redis Timeout Locks).
  2. Lưu Trữ Log Proxy Phình To: Cron change_active_cron mới chỉ tạm ngưng các proxy hết hạn mua trả phí. Nhưng chưa xóa hẳn (Hard Delete). Bảng Proxy IP Logs (proxy_ip_log) tracking public IP sẽ làm MongoDB Storage cạn kiệt sau vài tháng.

    • Gợi ý Fix: Tích hợp Collection TTL Index (Time-To-Live). Lệnh Mongo: db.proxy_ip_log.createIndex( { "created_at": 1 }, { expireAfterSeconds: 2592000 } ) (Tự drop log rác sau 30 ngày ngay tại tầng Driver DB, không cần Back-end Cron xử lý).
  3. Phân biệt Lựa Chọn Tối Ưu Phân Trang (Pagination Skip/Limit vs Cursor)

    • GET List có Limit/Page. Phụ thuộc Mongo Skip(). Với 500,000 proxies, trang số 5000 (Skip 100000) sẽ làm Mongo quét chậm lại (O(n)).
    • Gợi ý Fix: Cấu hình Index hoặc đổi sang Cursor Based Pagination (_id > last_id_of_previous_page). Tuy nhiên bù lại UI của Naive Data Table mất tính năng jump trang bấm số (1..5...89..100). Hiện tại Team đánh đổi UI Index Page (Skip) cho UX dễ xài vì số Record Proxy hiện tại chưa quá tải đến hàng chục triệu.

XXXIX. Hệ Thống Audit Log Trực Tiếp (Proxy IP Logs)

Vấn đề muôn thủa của các hệ thống định tuyến Proxy là "Chúng ta cần biết Proxy đã giữ IP nào vào thời điểm nào". Khi một người dùng report rằng Hệ thống SEO không được lên top vì Google trát cờ spam, Admin cần tra cứu xem IP đó sinh ra từ nhà mạng (Provider) nào, Proxy cụ thể là gói gì, và nằm trong múi giờ nào.

Cấu trúc bảng ProxyIPLog:
File thiết kế api/internal/proxy_ip_log/proxy_ip_log.go cung cấp collection lưu lịch sử với khối lượng khổng lồ.

type ProxyIpLog struct {
	ID        primitive.ObjectID `json:"id" bson:"_id"`
	ProxyId   string             `json:"proxy_id" bson:"proxy_id"`  // ID Proxy mẹ
	Ip        string             `json:"ip" bson:"ip"`              // IP Public
	Supplier  string             `json:"supplier" bson:"supplier"`  // Domain Provider (proxifly.dev, webshare.io...)
	Region    *string            `json:"region" bson:"region"`      // Mã quốc gia (VN)
	CreatedAt time.Time          `json:"created_at" bson:"created_at"`
	UpdatedAt time.Time          `json:"updated_at" bson:"updated_at"`
}

1. Kích hoạt Logging Trong StartRotate()

Mỗi khi Cronjob StartRotateV2() nhận lệnh webhook báo rằng IP đã xoay đổi thành công (Khác với IP Public cũ), nó sẽ trigger proxyIpLogService.NewLog(proxy_id, new_ip).

  • Điều kiện cần: Không write log nếu như provider xoay hụt và trả về đúng địa chỉ IP cũ (Tiết kiệm Disk Storage).

2. Truy xuất giao diện (Proxy IP Log Detail)

Admin Panel có khả năng cung cấp nút "Xem lịch sử Lọc" ở Data Table của Proxy. Route liên kết: /api/proxy-ip-logs/.
Cả một Controller riêng (handler.go của module proxy_ip_log) hoạt động song song mà không dính tới Server chính nhằm bảo đảm hiệu suất:

func (h *Handler) GetList(c *fiber.Ctx) error {
	var params dto.GetListProxyIpLog
    // ... Phân trang dựa theo "proxy_id"
    result, _ := h.service.GetListProxyIpLog(reqCtx, params)
    return c.JSON(result)
}

XL. Kiến Trúc Modular của Ứng Dụng (Golang Dependency Injection)

Để tài liệu kỹ thuật hoàn chỉnh, không thể không nhắc đến cách Team WinAd sắp xếp mã nguồn Golang của hệ thống Giga Master theo cơ chế Domain-Driven Design (DDD) lai với Clean Architecture.

1. Mô tả Phân chia Module (Module Bounding)

Thay vì code toàn bộ route ở một file main.go hay router.go, mỗi nhóm nghiệp vụ (như Server, Proxy, Backup Proxy) sống độc lập trong api/internal/<tên_nghiệp_vụ>/.

Bên trong mỗi folder sẽ luôn có 6 thành phần:

  • dto (Data Transfer Objects): Chứa mọi Request, Response Structs.
  • handler (Bắt Request Fiber HTTP): Gọi các function Service, return JSON theo chuẩn messages.Success.
  • repository (Thao tác DB Model): Viết query SQL/MongoDB, không xử lý business logic.
  • service (Logic Core): Orchestrate giữa Repository này với Repository khác.
  • cron (Tính năng Backup): Một số Domain sẽ có Cron đính kèm nếu tự động hoá.
  • <module>.go (Struct Config): Model mapping GORM hoặc BSON.

2. Sự phụ thuộc được quản lý bởi sarulabs/di (Dependency Injection)

Framework Server không tự khởi tạo hàm NewService(). Bằng cách dùng Container của thư viện dependency injection:

// Từng Repos sẽ được nạp trong bootstrap/injection.go
builder.Add(di.Def{
    Name: "proxy-repository",
    Build: func(ctn di.Container) (interface{}, error) {
        db := ctn.Get("mongodb").(*mongo.Database)
        redisCache := ctn.Get("redis").(*redis.Client)
        return proxyRepo.NewRepository(db, redisCache), nil
    },
})

Điều này khiến cho:

  • Unit Test cực kỳ dễ thực hiện cho api/internal/server. (Chỉ việc đẩy MockDB Repository).
  • Service Module này thoải mái gọi Module kia ví dụ Server Service có quyền gọi Log Service mà không sợ Vòng lặp kẹt (Circular Dependency) trong Go (import cycle not allowed).

XLI. Giải Pháp Đóng Package Trong Module (import_all_proxies)

Khi viết tính năng ImportAllProxies, team đã lựa chọn thiết kế Eventual Consistency.
Khi 1 Job Import (Gồm cả API lấy data từ Kiot, Zing, M2Proxy) được chạy, nó tạo ra 4 Go-Routines độc lập bằng sync.WaitGroup.

// Chạy import song song
go h.importZing(ctx, req.Zing, &wg, &mu, results...)
go h.importKiotProxy(ctx, req, &wg, &mu, results...)
go h.importM2Proxy(ctx, req, &wg, &mu, results...)
go h.importProxyXoay(ctx, req, &wg, &mu, results...)

Tính Năng Vượt Trội:

  • Nổi bật: Từng routine có 1 providerCtx, cancel := context.WithTimeout(ctx, 2*time.Minute). Nếu M2Proxy Die/ Sập server mất kết nối, thì hàm importM2Proxy tự hủy bộ chọn và return Error message lên map errors.
  • Trong khi đó, 3 provider Zing, Kiot, ProxyXoay vẫn Import THÀNH CÔNG và nạp IP Server bình thường.
  • Không có bất cứ 1 Provider thứ ba nào đủ quyền khóa chết toàn bộ hệ thống (Hệ thống Kháng Lỗi / Fault Tolerance).
  • Sử dụng mu.Lock() (Mutex) từ struct chung để truyền dữ liệu Thread-safe vào biến totalProxies và mảng errors. Chống Race Condition trong Go.
Modified at 2026-03-23 05:18:41
Previous
5. Quản lý tài khoản (Account Management)
Next
7. Quản lý tài khoản Google (Google Account Management)
Built with