Go Queue là một thư viện hàng đợi tác vụ (task queue) hiệu suất cao và linh hoạt được thiết kế cho các ứng dụng Go. Thư viện cung cấp một giải pháp toàn diện cho việc xử lý tác vụ bất đồng bộ với khả năng mở rộng và tích hợp dễ dàng.
- Xử lý đồng thời: Hỗ trợ đa worker để xử lý nhiều tác vụ song song
- Tối ưu hóa bộ nhớ: Sử dụng memory pool và connection pooling hiệu quả
- Polling thông minh: Khoảng thời gian polling có thể cấu hình
- Multi-adapter: Hỗ trợ cả Memory và Redis adapters
- Dependency Injection: Tích hợp hoàn toàn với hệ thống DI
- Provider Pattern: Dễ dàng mở rộng và tùy chỉnh
- Scheduled Tasks: Lên lịch tác vụ để thực hiện vào thời điểm cụ thể
- Retry Logic: Cơ chế retry thông minh với backoff
- Priority Queues: Hỗ trợ ưu tiên hàng đợi
- Dead Letter Queue: Xử lý tác vụ thất bại
- Graceful Shutdown: Dừng server một cách an toàn
- Error Handling: Xử lý lỗi toàn diện với logging chi tiết
- Context Support: Hỗ trợ đầy đủ Go context cho cancellation
- Monitoring: Metrics và health checks tích hợp
- Configuration: Cấu hình linh hoạt qua YAML
graph TB
subgraph "Application Layer"
CLIENT[Client<br/>🔄 Enqueue Tasks<br/>⏰ Schedule Tasks<br/>🎯 Context Support]
SERVER[Server<br/>👥 Worker Pool<br/>🔧 Handler Registry<br/>⚡ Processing Engine]
end
subgraph "Core Management Layer"
MANAGER[Manager<br/>🏭 Service Factory<br/>⚙️ Configuration<br/>🔌 Adapter Selection]
PROVIDER[Service Provider<br/>🚀 Lifecycle Management<br/>📦 DI Integration<br/>📋 Scheduled Tasks]
end
subgraph "Storage Adapters"
MEMORY[Memory Adapter<br/>💾 In-memory Storage<br/>⚡ Ultra Fast<br/>🔧 Development Mode]
REDIS[Redis Adapter<br/>💽 Persistent Storage<br/>🌐 Distributed<br/>🏢 Production Ready]
end
subgraph "External Dependencies"
SCHEDULER[Scheduler<br/>⏲️ Delayed Tasks<br/>📅 Cron Jobs<br/>🔄 Recurring Tasks]
DI[DI Container<br/>🔗 Dependency Injection<br/>🎯 Service Resolution<br/>♻️ Lifecycle Management]
end
CLIENT --> MANAGER
SERVER --> MANAGER
MANAGER --> MEMORY
MANAGER --> REDIS
PROVIDER --> MANAGER
PROVIDER --> DI
SERVER --> SCHEDULER
style CLIENT fill:#e8f5e8
style SERVER fill:#fff3e0
style MANAGER fill:#f3e5f5
style PROVIDER fill:#e1f5fe
style MEMORY fill:#fce4ec
style REDIS fill:#f1f8e9
style SCHEDULER fill:#f3e5f5
style DI fill:#e8f5e8
- Service Provider khởi tạo và cấu hình tất cả các components
- Client gửi tasks thông qua Manager
- Manager chọn adapter phù hợp (Memory/Redis) dựa trên cấu hình
- Server với worker pool liên tục dequeue và xử lý tasks
- Scheduler quản lý delayed/scheduled tasks
- DI Container quản lý lifecycle và dependencies của tất cả services
go get go.fork.vn/queuepackage main
import (
"go.fork.vn/di"
"go.fork.vn/config"
"go.fork.vn/redis"
"go.fork.vn/scheduler"
"go.fork.vn/queue"
)
func main() {
app := di.New()
// Đăng ký các providers cần thiết
app.Register(config.NewServiceProvider()) // Required cho cấu hình
app.Register(redis.NewServiceProvider()) // Required cho Redis adapter
app.Register(scheduler.NewServiceProvider()) // Required cho delayed tasks
app.Register(queue.NewServiceProvider())
// Boot ứng dụng - tự động cấu hình từ file config
app.Boot()
// Giữ ứng dụng chạy để worker có thể xử lý tác vụ
select {}
}# config/app.yaml
queue:
adapter:
default: "redis" # hoặc "memory"
memory:
prefix: "queue:"
redis:
prefix: "queue:"
provider_key: "default" # Sử dụng Redis provider với key "default"
server:
concurrency: 10
polling_interval: 1000 # milliseconds
default_queue: "default"
strict_priority: true
queues: ["critical", "high", "default", "low"]
shutdown_timeout: 30 # seconds
log_level: 1
retry_limit: 3
client:
default_options:
queue: "default"
max_retry: 3
timeout: 30 # minutes
# Cấu hình Redis trong redis section
redis:
default: # Redis provider key được reference từ queue config
host: "localhost"
port: 6379
password: ""
db: 0
cluster:
enabled: false
hosts: ["localhost:7000", "localhost:7001"]
scheduler:
auto_start: true
distributed_lock:
enabled: true # Cho môi trường distributed// Lấy queue manager từ container
container := app.Container()
manager := container.MustMake("queue").(queue.Manager)
// Lấy client từ manager
client := manager.Client()
// Thêm tác vụ ngay lập tức với options
payload := map[string]interface{}{
"user_id": 123,
"email": "user@example.com",
"action": "welcome",
}
taskInfo, err := client.Enqueue("email:welcome", payload,
queue.WithQueue("emails"), // Chỉ định queue
queue.WithMaxRetry(5), // Tối đa 5 lần retry
queue.WithTimeout(2*time.Minute), // Timeout sau 2 phút
queue.WithTaskID("welcome-123"), // Custom task ID
)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Đã thêm tác vụ: %s vào queue: %s\n", taskInfo.ID, taskInfo.Queue)
// Thêm tác vụ delayed (chạy sau 5 phút)
taskInfo, err = client.EnqueueIn("reminder:task", 5*time.Minute, payload,
queue.WithQueue("notifications"),
)
if err != nil {
log.Fatal(err)
}
// Thêm tác vụ scheduled (chạy vào thời điểm cụ thể)
processAt := time.Date(2025, 6, 1, 9, 0, 0, 0, time.Local)
taskInfo, err = client.EnqueueAt("report:generate", processAt, payload,
queue.WithQueue("reports"),
queue.WithMaxRetry(3),
)
if err != nil {
log.Fatal(err)
}// Lấy queue manager từ container và tạo server
manager := container.MustMake("queue").(queue.Manager)
server := manager.Server()
// Đăng ký handler cho email tasks
server.RegisterHandler("email:welcome", func(ctx context.Context, task *queue.Task) error {
var payload map[string]interface{}
if err := task.Unmarshal(&payload); err != nil {
return fmt.Errorf("failed to unmarshal payload: %w", err)
}
userID := int(payload["user_id"].(float64))
email := payload["email"].(string)
log.Printf("Gửi email chào mừng đến %s (ID: %d)", email, userID)
// Xử lý logic gửi email ở đây...
// Có thể return error để trigger retry mechanism
if !sendWelcomeEmail(email) {
return fmt.Errorf("failed to send email to %s", email)
}
return nil
})
// Đăng ký handlers cho các loại tác vụ khác với error handling
server.RegisterHandler("reminder:task", func(ctx context.Context, task *queue.Task) error {
log.Printf("Processing reminder task: %s", task.ID)
// Check context timeout
select {
case <-ctx.Done():
return ctx.Err()
default:
// Process reminder logic
return processReminder(task)
}
})
server.RegisterHandler("report:generate", func(ctx context.Context, task *queue.Task) error {
log.Printf("Generating report: %s", task.ID)
return generateReport(task)
})
// Đăng ký nhiều handlers cùng một lúc
server.RegisterHandlers(map[string]queue.HandlerFunc{
"notification:push": handlePushNotification,
"order:process": handleOrderProcessing,
"data:cleanup": handleDataCleanup,
})
// Server tự động start khi ứng dụng boot
// Nhưng bạn cũng có thể control thủ công:
// err := server.Start()
// if err != nil {
// log.Fatal(err)
// }
// Graceful shutdown
// defer server.Stop()Queue Provider hiện đã tích hợp hoàn chỉnh với Scheduler Provider để xử lý các tác vụ phức tạp:
// Lấy scheduler từ manager
scheduler := manager.Scheduler()
// Schedule tasks mà sẽ enqueue jobs vào queue
scheduler.Every(5).Minutes().Do(func() {
// Task định kỳ mỗi 5 phút
client.Enqueue("maintenance:cleanup", map[string]interface{}{
"type": "temporary_files",
"timestamp": time.Now(),
}, queue.WithQueue("maintenance"))
})
// Daily report generation
scheduler.Every(1).Days().At("09:00").Do(func() {
client.Enqueue("report:daily", map[string]interface{}{
"date": time.Now().Format("2006-01-02"),
"type": "sales_summary",
}, queue.WithQueue("reports"))
})
// Weekly backup với cron expression
scheduler.Cron("0 2 * * 0").Do(func() { // Chủ nhật 2:00 AM
client.Enqueue("backup:weekly", map[string]interface{}{
"week": time.Now().Format("2006-W02"),
}, queue.WithQueue("maintenance"))
})
// Distributed scheduling (chỉ chạy trên 1 instance trong cluster)
scheduler.Every(10).Minutes().Tag("distributed").Do(func() {
client.Enqueue("monitor:health_check", nil, queue.WithQueue("monitoring"))
})Queue Provider v0.0.3 cung cấp nhiều options linh hoạt:
// Tất cả options có thể dùng khi enqueue
taskInfo, err := client.Enqueue("image:resize", payload,
queue.WithQueue("media"), // Chỉ định queue
queue.WithMaxRetry(5), // Số lần retry tối đa
queue.WithTimeout(10*time.Minute), // Timeout cho task
queue.WithTaskID("resize-user-123-photo"), // Custom task ID
queue.WithDelay(30*time.Second), // Delay trước khi xử lý
queue.WithDeadline(time.Now().Add(1*time.Hour)), // Deadline tuyệt đối
)
if err != nil {
log.Fatal(err)
}
// Batch enqueue cho hiệu suất cao
tasks := []map[string]interface{}{
{"user_id": 1, "action": "welcome"},
{"user_id": 2, "action": "welcome"},
{"user_id": 3, "action": "welcome"},
}
for i, task := range tasks {
client.Enqueue("email:welcome", task,
queue.WithQueue("emails"),
queue.WithTaskID(fmt.Sprintf("welcome-%d", i)),
queue.WithMaxRetry(3),
)
}
// Process trong ưu tiên queues
highPriorityTask, _ := client.Enqueue("order:urgent", orderData,
queue.WithQueue("critical"),
queue.WithMaxRetry(5),
queue.WithTimeout(30*time.Second),
)
lowPriorityTask, _ := client.Enqueue("analytics:update", analyticsData,
queue.WithQueue("low"),
queue.WithMaxRetry(1),
queue.WithTimeout(5*time.Minute),
)// Memory adapter tự động được sử dụng khi cấu hình default là "memory"
// Hoặc có thể khởi tạo trực tiếp:
package main
import (
"go.fork.vn/di"
"go.fork.vn/queue"
"go.fork.vn/config"
"go.fork.vn/redis"
)
func main() {
app := di.New()
app.Register(config.NewServiceProvider())
app.Register(redis.NewServiceProvider()) // Required cho Redis adapter
app.Register(queue.NewServiceProvider())
// Cấu hình sử dụng memory adapter trong config/app.yaml:
// queue:
// adapter:
// default: "memory"
// memory:
// prefix: "test_queue:"
app.Boot()
// Memory adapter không cần Redis và phù hợp cho:
// - Unit testing
// - Development environment
// - Prototype/demo applications
container := app.Container()
client := container.MustMake("queue.client").(queue.Client)
// Sử dụng giống hệt như Redis adapter
client.Enqueue("test:task", "test payload")
}Queue Provider hiện đã tích hợp hoàn chỉnh với Redis Provider để centralize Redis configuration và cung cấp advanced Redis features:
// Redis configuration được quản lý bởi Redis Provider
// config/app.yaml
redis:
default: # Redis instance key
host: "localhost"
port: 6379
password: ""
db: 0
max_retries: 3
dial_timeout: 5
read_timeout: 3
write_timeout: 3
pool_size: 10
queue:
adapter:
default: "redis"
redis:
prefix: "queue:"
provider_key: "default" # Reference Redis provider key
// Sử dụng advanced Redis features
package main
import (
"context"
"time"
"go.fork.vn/di"
"go.fork.vn/config"
"go.fork.vn/redis"
"go.fork.vn/queue"
"go.fork.vn/queue/adapter"
)
func main() {
app := di.New()
app.Register(config.NewServiceProvider())
app.Register(redis.NewServiceProvider())
app.Register(queue.NewServiceProvider())
app.Boot()
container := app.Container()
manager := container.MustMake("queue").(queue.Manager)
// Lấy Redis queue adapter để sử dụng advanced features
redisAdapter := manager.RedisAdapter()
// Type assertion để access Redis-specific methods
if redisQueue, ok := redisAdapter.(adapter.QueueRedisAdapter); ok {
ctx := context.Background()
// Priority queue operations
err := redisQueue.EnqueueWithPriority(ctx, "tasks", &task, 10) // Priority 10
if err != nil {
log.Fatal(err)
}
// Dequeue from priority queue
var priorityTask queue.Task
err = redisQueue.DequeueFromPriority(ctx, "tasks", &priorityTask)
if err != nil {
log.Printf("No priority tasks available: %v", err)
}
// TTL support
err = redisQueue.EnqueueWithTTL(ctx, "temporary", &task, 1*time.Hour)
if err != nil {
log.Fatal(err)
}
// Batch operations với pipeline
tasks := []*queue.Task{&task1, &task2, &task3}
err = redisQueue.EnqueueWithPipeline(ctx, "batch", tasks)
if err != nil {
log.Fatal(err)
}
// Multi-dequeue
results, err := redisQueue.MultiDequeue(ctx, "batch", 5) // Lấy tối đa 5 tasks
if err != nil {
log.Fatal(err)
}
log.Printf("Dequeued %d tasks", len(results))
// Queue monitoring
info, err := redisQueue.GetQueueInfo(ctx, "tasks")
if err != nil {
log.Fatal(err)
}
log.Printf("Queue info: %+v", info)
// Health check
if err := redisQueue.Ping(ctx); err != nil {
log.Printf("Redis connection issue: %v", err)
}
// Development/testing utilities
if err := redisQueue.FlushQueues(ctx, []string{"test", "debug"}); err != nil {
log.Printf("Failed to flush queues: %v", err)
}
}
}Queue Provider v0.0.3 có hệ thống xử lý lỗi tiên tiến:
// Failed jobs được tự động retry với exponential backoff
server.RegisterHandler("risky:task", func(ctx context.Context, task *queue.Task) error {
// Giả lập task có thể fail
if rand.Float32() < 0.3 { // 30% chance fail
return fmt.Errorf("simulated failure")
}
log.Printf("Task %s completed successfully", task.ID)
return nil
})
// Tasks sẽ được retry tối đa theo cấu hình (mặc định 3 lần)
// Delay giữa các lần retry tăng theo exponential backoff:
// - Retry 1: 1 minute
// - Retry 2: 4 minutes
// - Retry 3: 9 minutes
// Sau khi vượt quá retry limit, task sẽ được chuyển vào Dead Letter Queue
// Dead Letter Queue có thể được monitor và xử lý thủ công
// Hệ thống maintenance tự động:
// - Cleanup dead letter tasks cũ hơn 7 ngày (chạy mỗi giờ)
// - Retry failed tasks đủ điều kiện (chạy mỗi 5 phút)
// - Xử lý delayed tasks đã đến hạn (chạy mỗi 30 giây)// TaskInfo cung cấp thông tin chi tiết về task
taskInfo, err := client.Enqueue("debug:task", payload)
if err == nil {
log.Printf("Task created: %s", taskInfo.String())
// Output: Task ID: abc-123, Name: debug:task, Queue: default,
// State: pending, Created: 2025-05-28T10:30:00Z
}
// Server logging tự động theo dõi:
// - Task processing time
// - Worker performance
// - Retry attempts
// - Failed task reasons
// - Queue sizes
// Có thể tùy chỉnh log level trong config:
// queue:
// server:
// log_level: 2 # 0=SILENT, 1=ERROR, 2=INFO, 3=DEBUG// Cấu hình production-ready
// config/production.yaml
/*
queue:
adapter:
default: "redis"
redis:
prefix: "myapp_queue:"
provider_key: "default" # Reference Redis provider key
server:
concurrency: 50 # Điều chỉnh theo CPU cores
polling_interval: 500 # Giảm cho high-throughput
strict_priority: true # Đảm bảo critical tasks được ưu tiên
queues: ["critical", "high", "default", "low", "bulk"]
shutdown_timeout: 60 # Đủ thời gian cho graceful shutdown
retry_limit: 5 # Tăng retry cho production
client:
default_options:
queue: "default"
max_retry: 3
timeout: 15 # 15 phút timeout mặc định
# Redis cấu hình riêng biệt trong Redis provider
redis:
default:
host: "redis-cluster.internal"
port: 6379
password: "${REDIS_PASSWORD}"
db: 0
cluster:
enabled: true
hosts:
- "redis-1.internal:6379"
- "redis-2.internal:6379"
- "redis-3.internal:6379"
scheduler:
auto_start: true
distributed_lock:
enabled: true # Bắt buộc cho production cluster
options:
key_prefix: "myapp_scheduler:"
lock_duration: 120 # 2 phút
max_retries: 5
retry_delay: 500
*/
// Graceful shutdown handling
func setupGracefulShutdown(server queue.Server) {
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
go func() {
<-c
log.Println("Shutting down gracefully...")
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
if err := server.Stop(); err != nil {
log.Printf("Error during shutdown: %v", err)
}
log.Println("Shutdown complete")
os.Exit(0)
}()
}Để tìm hiểu sâu hơn về Go Queue, hãy tham khảo tài liệu chi tiết:
- Tổng quan - Giới thiệu và hướng dẫn bắt đầu nhanh
- Kiến trúc hệ thống - Kiến trúc chi tiết và các design patterns
- Cấu hình - Hướng dẫn cấu hình đầy đủ
- Client API - API để thêm tasks vào queue
- Server & Workers - Thiết lập server và xử lý tasks
- Service Provider - Tích hợp với DI container
- Manager - Quản lý components và adapters
- Task Management - Quản lý tasks và options nâng cao
go get go.fork.vn/queue# config/app.yaml
queue:
adapter:
default: "redis"
server:
concurrency: 10
queues: ["critical", "default", "low"]package main
import (
"go.fork.vn/di"
"go.fork.vn/config"
"go.fork.vn/redis"
"go.fork.vn/scheduler"
"go.fork.vn/queue"
)
func main() {
app := di.New()
// Đăng ký providers
app.Register(config.NewServiceProvider())
app.Register(redis.NewServiceProvider())
app.Register(scheduler.NewServiceProvider())
app.Register(queue.NewServiceProvider())
app.Boot()
// Đăng ký handlers
setupHandlers(app)
// Giữ ứng dụng chạy
select {}
}
func setupHandlers(app *di.Application) {
server := app.Container().MustMake("queue.server").(queue.Server)
server.RegisterHandler("email:send", func(ctx context.Context, task *queue.Task) error {
// Xử lý gửi email
return nil
})
}client := app.Container().MustMake("queue.client").(queue.Client)
// Thêm task ngay lập tức
client.Enqueue("email:send", map[string]interface{}{
"to": "user@example.com",
"subject": "Welcome!",
})
// Thêm task delayed
client.EnqueueIn("reminder", 1*time.Hour, reminderData)- Multi-threading: Hỗ trợ đến 1000+ workers đồng thời
- Memory Pool: Tối ưu hóa memory allocation với 99.5% hit rate
- Connection Pool: Quản lý Redis connections hiệu quả
- Batch Processing: Xử lý hàng loạt tasks với throughput cao
- Priority Queues: 4 mức độ ưu tiên (critical, high, default, low)
- Delayed Tasks: Lên lịch tasks với độ chính xác millisecond
- Retry Logic: Exponential backoff với jitter để tránh thundering herd
- Dead Letter Queue: Tự động xử lý failed tasks
- Task Dependencies: Support task chains và workflows
- Health Checks: Monitoring endpoints cho Kubernetes/Docker
- Metrics: Tích hợp Prometheus metrics
- Graceful Shutdown: Zero-downtime deployments
- Circuit Breaker: Tự động recovery khi Redis connection fail
- Distributed Locks: Safe trong môi trường multi-instance
- Hot Reload: Thay đổi handlers mà không restart
- Debug Mode: Chi tiết task execution traces
- Testing Support: Built-in test utilities và mocks
- Type Safety: Strongly typed interfaces với generics
- IDE Integration: Full IntelliSense support
Chúng tôi hoan nghênh mọi đóng góp! Hãy xem CONTRIBUTING.md để biết thêm chi tiết.
# Clone repository
git clone https://github.com/go-fork/queue.git
cd queue
# Cài đặt dependencies
go mod download
# Chạy tests
make test
# Chạy examples
go run examples/basic/main.goBenchmarkEnqueue-8 1000000 1.2 μs/op 0 allocs/op
BenchmarkDequeue-8 500000 2.1 μs/op 1 allocs/op
BenchmarkWorkerPool-8 2000000 0.8 μs/op 0 allocs/op
BenchmarkRedisAdapter-8 300000 4.5 μs/op 2 allocs/op
BenchmarkMemoryAdapter-8 5000000 0.3 μs/op 0 allocs/op
- WebUI Dashboard cho monitoring
- GraphQL API endpoints
- Workflow Engine cho complex task chains
- Built-in rate limiting
- Kafka adapter support
- Multi-tenant queues
- A/B testing framework
- Auto-scaling workers
Q: Go Queue có khác gì với Celery không? A: Go Queue được thiết kế native cho Go với type safety, performance cao hơn và tích hợp DI framework.
Q: Có thể sử dụng Go Queue mà không cần Redis không? A: Có, sử dụng Memory adapter cho development hoặc single-instance deployments.
Q: Performance như thế nào so với các solutions khác? A: Go Queue có thể xử lý 10,000+ tasks/second với latency < 1ms trên hardware thông thường.
Dự án này được phát hành dưới MIT License.
- Go DI Framework - Dependency Injection framework
- Go Config - Configuration management
- Go Redis - Redis client và provider
- Go Scheduler - Job scheduling
- Tài liệu API - GoDoc documentation
- Examples Repository - Code examples và tutorials
Made with ❤️ by the Go Fork team