结合实际业务,整了一个 Go 的异步任务框架

2020-04-15 16:38:58 +08:00
 gansteed

链接在 https://github.com/jiajunhuang/gotasks


日常开发中,会发现很多异步任务会变的又大又长,其实其中很多任务是可以拆成 n 个子任务的,所以就整了这个框架,用法很简单,首先把任务分成 n 个子任务(不分用一个自然也是 ok 的),注册进去。接下来生产者 Enqueue 任务, 消费者消费任务。

注册的子任务会串成一个链,他们共用一个 map 来存储参数,因此第一个子任务可以修改参数并且返回,第二个子任务拿到的就是修改后的参数。

package main

import (
	"time"

	"github.com/jiajunhuang/gotasks"
)

const (
	uniqueJobName = "a-unique-job-name"
	redisURL      = "redis://127.0.0.1:6379/0"
	queueName     = "job-queue-name"
)

func worker() {
	gotasks.Run(queueName)
}

func main() {
	go worker()

	// register tasks
	handler1 := func(args gotasks.ArgsMap) (gotasks.ArgsMap, error) {
		time.Sleep(time.Duration(1) * time.Second)
		return args, nil
	}
	handler2 := func(args gotasks.ArgsMap) (gotasks.ArgsMap, error) {
		time.Sleep(time.Duration(1) * time.Second)
		return args, nil
	}
	gotasks.Register(uniqueJobName, handler1, handler2)

	// set broker
	gotasks.UseRedisBroker(redisURL, 100)

	// enqueue
	gotasks.Enqueue(queueName, uniqueJobName, gotasks.MapToArgsMap(map[string]interface{}{})) // or gotasks.StructToArgsMap
}
3286 次点击
所在节点    分享创造
8 条回复
lasuar
2020-04-15 17:22:29 +08:00
看的我有点蒙,uniqueJobName 和 queueName 的区别是什么?另外直接用 redis 的 pubsub 不行吗?你这个不也是用的 redis 吗,套娃?
gansteed
2020-04-15 17:34:16 +08:00
@lasuar 如果没有 queueName,那么意味着所有的任务都会放到一个队列里; queue 就是分流。举个例子:如果是学校的管理系统(假设是一个单体应用)。处理书籍的异步任务和处理学生信息的异步任务肯定不希望放在同一个队列里进行消费。这样也不利于多队列并发消费。可以用 pub/sub,我更喜欢用 lpush/brpop
lasuar
2020-04-15 19:21:17 +08:00
ok ;你都说了 lpush 。那可以直接用 redis 的 lpush 和 brpop 啊,就是把 list 当队列用。看到这里我得出的结论就是 gotasks 的主要内容就是把 lpush 和 brpop 封装了一下,以及 list 的管理,so==
gansteed
2020-04-15 20:12:25 +08:00
@lasuar 额,你可以看看 python-rq 的实现。如果一定要这么说的话,Web 框架岂不是就封装了一个

GET / HTTP/1.1
Host: blabla

的报文?
lasuar
2020-04-15 20:20:35 +08:00
@gansteed 我和我的朋友们确实这么看 web 框架的,使用 web 框架是因为更多的时 web 框架封装了已很多插件化的东西,简单好用,就类似脚手架;不过 web 框架的实现也有一些亮点的东西,比如不同的 web 框架内部使用的 IO 模型不一样,有的是 select 有的是 epoll ;我并不是完全否定你的作品,只是在我看来目前哈这个项目的确没什么技术亮点(请原谅我的直接),你可以添加一些亮点进去,更容易得到 star 和认可
Aether
2020-04-16 16:03:14 +08:00
感觉可能有用,先码了。

先说,我是一个小白。

我个人其实特别想要一个极其简单的,类似 Python Celery (但部署不要那么复杂)的任务序列,可以有节奏地控制,把任务付诸实施(比如忽然来了 1000 个任务,我可以限定每分钟执行 100 个,避免对外部 API/内部资源的挤压消耗,直到自然耗尽。可能再有就是保证队列不会丢)。而我只需要 addTask(object/param) 就完了。

目前我看到的 Go 体系下任务序列都很繁杂(相对我能理解的能力而言),覆盖的各种独特性太多,或者实施比较麻烦,不能一目了然,看了 demo 就能用。缺少 Python 那种简洁的感受。
gansteed
2020-04-16 20:23:49 +08:00
@Aether +1,我也不喜欢很复杂的
OakScript
2020-04-17 19:33:08 +08:00
各种 goworker 不要太多啊,同样轮子没有特色,个人练个手就好

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/662722

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX