任务队列 P133
通过将待执行任务的相关信息放入队列里面,并在之后对队列进行处理,可以推迟执行那些耗时对操作,这种将工作交给任务处理器来执行对做法被称为任务队列 (task queue) 。 P133
先进先出队列 P133
可以 Redis
的列表结构存储任务的相关信息,并使用 RPUSH
将待执行任务的相关信息推入列表右端,使用阻塞版本的弹出命令 BLPOP
从队列中弹出待执行任务的相关信息(因为任务处理器除了执行任务不需要执行其他工作)。 P134
发送任务
// 将任务参数推入指定任务对应的列表右端
func SendTask(conn redis.Conn, queueName string, param string) (bool, error) {
count, err := redis.Int(conn.Do("RPUSH", queueName, param))
if err != nil {
return false, nil
}
// 只有成功推入 1 个才算成功发送
return count == 1, nil
}
执行任务
// 不断从任务对应的列表中获取任务参数,并执行任务
func RunTask(conn redis.Conn, queueName string, taskHandler func(param string)) {
for ; ; {
result, err := redis.Strings(conn.Do("BLPOP", queueName, 10))
// 如果成功获取任务信息,则执行任务
if err != nil && len(result) == 2 {
taskHandler(result[1])
}
}
}
以上代码是任务队列与 Redis
交互的通用版本,使用方式简单,只需要将入参信息序列化成字符串传入即可发送一个任务,提供一个处理任务的方法回调即可执行任务。
任务优先级 P136
在此基础上可以讲原有的先进先出任务队列改为具有优先级的任务队列,即高优先级的任务需要在低优先级的任务之前执行。 BLPOP
将弹出第一个非空列表的第一个元素,所以我们只需要将所有任务队列名数组按照优先级降序排序,让任务队列名数组作为 BLPOP
的入参即可实现上述功能(当然这种如果高优先级任务的生成速率大于消费速率,那么低优先级的任务就永远不会执行)。 P136
优先执行高优先级任务
// 不断从任务对应的列表中获取任务参数,并执行任务
// que