概述与快速开始
1 什么是 Asynq
Asynq 是由 Go 社区(@hibiken)开发的分布式任务队列库,基于 Redis 实现持久化存储,旨在以简单、可靠的 API 提供高可用的异步任务处理能力。其核心定位是让 Go 应用能够轻松地将耗时操作从主请求路径中剥离,交由后台 Worker 异步执行。
典型适用场景
| 场景 | 示例 |
|---|---|
| 消息通知 | 邮件、短信、推送通知的异步发送 |
| 媒体处理 | 图片缩放/裁剪、视频转码、音频处理 |
| 数据导出 | 大数据量的报表生成与文件导出 |
| 外部 API 调用 | 第三方服务回调、结果轮询 |
| AI / LLM 推理 | 模型调用、文本生成等高延迟计算 |
| 定时任务 | 日报生成、数据清理、定时同步 |
| 批量写入 | 日志聚合、指标上报、批量 DB 写入 |
与其他队列方案对比
| 维度 | Asynq | RabbitMQ | Kafka | Redis 裸用 |
|---|---|---|---|---|
| 部署复杂度 | 低(仅需 Redis) | 中(Erlang 环境) | 高(Zookeeper/KRaft) | 低 |
| 消息可靠性 | 至少一次 + 重试 | 至少一次 / 精确一次 | 至少一次 | 需自行实现 |
| 延迟任务 | 内置 | 需要插件 | 不原生支持 | BRPOPLPUSH 变通 |
| 优先级队列 | 内置(多队列权重) | 内置 | 不原生支持 | 需自行设计 |
| 去重 | 内置(Unique) | 需业务实现 | 需业务实现 | 需业务实现 |
| Go 亲和度 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐ |
| Web UI | 内置(asynqmon) | 内置(Management) | 第三方工具 | 无 |
| 吞吐量 | 中高(受限于 Redis) | 中高 | 极高 | 高 |
2 环境要求
| 组件 | 最低版本 | 说明 |
|---|---|---|
| Go | 1.22+(v0.26.0 起为 1.24+) | Asynq 跟随 Go 官方支持的最近两个主版本 |
| Redis | 4.0+ | 大量依赖 Lua 脚本实现原子操作;Redis 5.0+ 推荐 |
| OS | Linux / macOS / Windows | 跨平台支持 |
# 安装 Asynq
go get github.com/hibiken/asynq
# 快速启动 Redis(Docker)
docker run --name redis -d -p 6379:6379 redis:73 最小可运行示例
3.1 定义任务
任务由类型标识(字符串)和 Payload(字节负载)组成:
package tasks
import (
"context"
"encoding/json"
"fmt"
"log"
"github.com/hibiken/asynq"
)
// 任务类型常量(推荐 "domain:action" 命名格式)
const TypeEmailDelivery = "email:deliver"
// Payload 结构体
type EmailPayload struct {
UserID int `json:"user_id"`
TemplateID string `json:"template_id"`
}
// 创建任务(Client 端调用)
func NewEmailTask(userID int, tmplID string) (*asynq.Task, error) {
payload, err := json.Marshal(EmailPayload{UserID: userID, TemplateID: tmplID})
if err != nil {
return nil, err
}
return asynq.NewTask(TypeEmailDelivery, payload), nil
}
// 任务处理器(Worker 端实现)
func HandleEmailTask(ctx context.Context, t *asynq.Task) error {
var p EmailPayload
if err := json.Unmarshal(t.Payload(), &p); err != nil {
return fmt.Errorf("json.Unmarshal failed: %v: %w", err, asynq.SkipRetry)
}
log.Printf("Sending email to user_id=%d, template=%s", p.UserID, p.TemplateID)
// TODO: 实际发送邮件逻辑
return nil
}3.2 入队任务(Client)
func main() {
client := asynq.NewClient(asynq.RedisClientOpt{Addr: "localhost:6379"})
defer client.Close()
task, err := tasks.NewEmailTask(42, "welcome")
if err != nil {
log.Fatal(err)
}
info, err := client.Enqueue(task)
if err != nil {
log.Fatal(err)
}
log.Printf("enqueued: id=%s queue=%s", info.ID, info.Queue)
}3.3 启动 Worker(Server)
func main() {
srv := asynq.NewServer(
asynq.RedisClientOpt{Addr: "localhost:6379"},
asynq.Config{Concurrency: 10},
)
mux := asynq.NewServeMux()
mux.HandleFunc(tasks.TypeEmailDelivery, tasks.HandleEmailTask)
if err := srv.Run(mux); err != nil {
log.Fatal(err)
}
}3.4 延迟任务与定时任务
// 延迟 10 分钟
client.Enqueue(task, asynq.ProcessIn(10*time.Minute))
// 指定具体执行时间
client.Enqueue(task, asynq.ProcessAt(time.Date(2026, 7, 18, 9, 0, 0, 0, time.Local)))4 文档导航
本手册按专题拆分为以下章节:
| 章节 | 内容 |
|---|---|
| 00-概述与快速开始 | 概述、环境要求、最小示例(本文) |
| 01-核心概念与架构 | 核心概念、内部组件、任务生命周期 |
| 02-任务创建与入队 | Task 创建、Enqueue、全部入队选项、批量入队 |
| 03-Server配置详解 | Config 全部字段、队列权重、严格优先级 |
| 04-任务处理与中间件 | Handler/ServeMux/Middleware/BaseContext |
| 05-重试与错误处理 | 重试机制、SkipRetry、ErrorHandler、自定义重试策略 |
| 06-周期性任务 | Scheduler、PeriodicTaskManager、Cron 表达式 |
| 07-高级特性 | 任务聚合、ResultWriter、唯一任务、消息持久化 |
| 08-并发控制与限流 | 并发配置、分布式信号量、按任务类型限流 |
| 09-Redis配置与高可用 | 单机/Sentinel/Cluster、TLS、ACL |
| 10-监控与运维 | Web UI、CLI、Prometheus、Inspector API |
| 11-测试指南 | Handler 单元测试、集成测试模式 |
| 12-最佳实践与陷阱 | 最佳实践清单、常见陷阱、生产检查清单 |
5 符号约定
| 符号 | 含义 |
|---|---|
| 🚨 | 陷阱 / Pitfall |
| 💡 | 最佳实践 / Best practice |
| 🔬 | 深入原理 / Deep-dive into internals |
| ⚡ | 性能提示 / Performance note |