Script cron loop profile_ids sẽ vỡ ở 50+ tài khoản — duplicate launch, browser mồ côi, không retry. Pattern queue + worker pool với profile leasing giải quyết vấn đề này. Recipe dùng Redis; có thể thay bằng SQS, RabbitMQ, hoặc PostgreSQL SKIP LOCKED.
Kiến trúc
API / dashboard → LPUSH mlx:jobs Worker pool → BRPOP → lease profile → start → CDP job → stop → webhook CMDB → profile_id, tier, lease_until, ban_status
Schema job (JSON)
{
"job_id": "uuid",
"profile_id": "mlx-profile-uuid",
"task": "sync_orders",
"payload": {"shop_id": "acme_vn"},
"attempt": 1,
"max_attempts": 3,
"callback_url": "https://ops.example/hooks/mlx"
}
Lease profile (chống double launch)
import redis
r = redis.Redis(decode_responses=True)
LEASE_TTL = 900 # 15 phút
def try_lease(profile_id: str, worker_id: str) -> bool:
key = f"mlx:lease:{profile_id}"
return r.set(key, worker_id, nx=True, ex=LEASE_TTL)
def release_lease(profile_id: str, worker_id: str) -> None:
key = f"mlx:lease:{profile_id}"
if r.get(key) == worker_id:
r.delete(key)
Vòng worker (asyncio)
async def run_job(job: dict):
profile_id = job["profile_id"]
if not try_lease(profile_id, WORKER_ID):
raise RetryLater("profile đang leased")
async with SEM:
# start profile → CDP → execute_task → stop → release_lease
...
Chi tiết đầy đủ: bản tiếng Anh.
Quy tắc vận hành
- Một profile mỗi job — không parallel CDP trên cùng UUID
- Lease TTL > thời gian job tối đa — gia hạn lease cho job dài
- Dead letter queue — sau
max_attempts, chuyển sangmlx:dlq - Rate limit — semaphore khớp cap gói Multilogin
- Metrics — latency job, start fail, ban rate theo profile
Webhook receiver
Worker POST kết quả về callback_url. Receiver cần verify HMAC và dedupe job_id: webhook receiver recipe (EN).
Liên quan
Disclosure: MLX-MMO liên kết với Multilogin. Xác minh endpoint API với tài liệu chính thức. 70+ guides EN.