工作用Go: 异步任务怎么写6 | Asynq: 专业异步任务框架

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介: 工作用Go: 异步任务怎么写6 | Asynq: 专业异步任务框架

go01.jpeg

本文为 工作用Go: 异步任务怎么写 系列的第6


如果只是 异步一下, 上面讲解的内容也基本够用了; 如果有重度异步任务使用, 就得考虑专业的异步任务队列框架了, Go 中可以选择 Async


Asynq Features


整体架构图

image.pngimage.png

实际使用

使用的 demo 就不贴了, asynq 的文档很详细, 说一下具体实践中遇到的 2个 case:


  • 使用 web UI: 处于安全考虑, 设置了 ReadOnly
h :=asynqmon.New(asynqmon.Options{
RootPath:     "/monitoring", // RootPath specifies the root for asynqmon appRedisConnOpt: tasks.GetRedis(),
ReadOnly:     true, // admin web can't operation})
r :=mux.NewRouter()
r.PathPrefix(h.RootPath()).Handler(h)
srv :=&http.Server{
Handler: r,
Addr:    ":8080",
}


PS: 使用 web UI 由于涉及到使用新的端口, 而应用部署已经上 k8s 了, 如何顺利访问就需要一系列运维操作, 留个坑, 以后有机会再填


  • 测试环境OK, 线上报错: recoverer: could not move task to archive: INTERNAL_ERROR: redis eval error: ERR 'asynq:{}:t:' and 'asynq:{}:active' not in the same slot


对比发现, 是测试和线上使用的不同类型的 redis 实例导致的, 搜索云服务的帮助文档:

Redis实例类型差异

对比项

单机/主备

Proxy集群

Cluster集群

兼容Redis版本

兼容社区Redis 3.0、4.0、5.0。

Redis 6.0兼容社区KeyDB(当前只支持主备实例)。

可在购买实例时选择版本号。

兼容社区3.0、4.0和5.0版本。

兼容开源社区4.0/5.0版本。

可在购买集群实例时选择版本号。

特性支持

  • 支持event notify。
  • 支持pipeline。
  • 支持pipeline、mset、mget。
  • 支持scan、keys、slowlog。
  • 支持发布订阅。
  • 支持event notify。
  • 支持brpop、blpop、brpoplpush。
  • 支持发布订阅。

特性限制

单机不支持持久化。

  • lua脚本受限使用,所有的key必须在同一个slot,否则会报错,建议使用hashtag技术。
  • 多个key的命令中,所有key必须属于同一个slot,否则会报错,建议使用hashtag技术。
  • 不支持event notify用法。
  • lua脚本受限使用,所有的key必须在同一个slot,建议使用hashtag技术。
  • 需要客户端SDK支持redis cluster协议,需要能够处理"-MOVED"响应。
  • 使用pipeline、mset/mget模式时,所有key必须属于同一个slot,否则报错,建议使用hashtag技术。
  • 使用event notify时,需要建立与每个redis-server的连接,分别处理每个连接上的事件。
  • 执行scan、keys等遍历类或者全局类命令时,需要对每个redis-server分别执行该命令。

客户端协议

使用传统Redis客户端即可。

使用传统Redis客户端即可,不需要支持Redis Cluster协议。

需要客户端支持Redis Cluster协议。

命令限制

单机和主备实例不支持的Redis命令,请参考表 Redis4.0单机和主备禁用命令表 Redis 5.0单机和主备禁用命令

Proxy集群实例不支持的Redis命令,请参考表 Redis3.0 Proxy集群实例禁用命令表8表8

Cluster集群不支持的Redis命令,请参考表 Redis4.0 Cluster集群禁用命令表 Redis5.0 Cluster集群禁用命令

副本数

单机实例为单副本,只有一个节点。

主备实例为双副本,目前Redis 3.0、Redis 6.0主备不支持自定义副本数,默认为一主一从的架构。在创建Redis 4.0、5.0主备实例时,支持自定义副本数,形成一主多从的架构。

每个集群分片都为双副本,但不支持为分片新增副本,每个分片是一主一从的架构。

每个集群分片默认为双副本,支持自定义副本数,可以是一主多从的架构。在创建实例时,也可以定义为单副本,单副本表示实例只有主节点,无法保障数据高可靠。


集群架构实例的命令限制: 如需在集群架构实例中执行下述受限制的命令,请使用hash tag确保命令所要操作的key都分布在1个hash slot中


但是查看 asqnq 源码: 以 enqueue 操作为例, lua 操作中的部分 key 无法通过外部添加 hash tag

// github.com/hibiken/asynq/internal/rdb/rdb.go// enqueueCmd enqueues a given task message.//// Input:// KEYS[1] -> asynq:{<qname>}:t:<task_id>// KEYS[2] -> asynq:{<qname>}:pending// --// ARGV[1] -> task message data// ARGV[2] -> task ID// ARGV[3] -> current unix time in nsec//// Output:// Returns 1 if successfully enqueued// Returns 0 if task ID already existsvarenqueueCmd=redis.NewScript(`if redis.call("EXISTS", KEYS[1]) == 1 thenreturn 0endredis.call("HSET", KEYS[1],"msg", ARGV[1],"state", "pending","pending_since", ARGV[3])redis.call("LPUSH", KEYS[2], ARGV[2])return 1`)


最终, 通过使用线上另一台主从版redis解决问题


写在最后


到这里, 工作用Go: 异步任务怎么写 就暂时告一段落了, 这个过程中:


  • 一些计算机基础概念的理解: 同步与异步, 异步与任务编排, 协程与异步, 协程与生命周期
  • 一些 Go 语言的基础知识以及基础不牢地动山摇的坑: 野生Goroutine, panic&recover
  • 可观测的实践之一: trace
  • 专业的异步任务框架 Asynq 以及踩坑记


一起拥抱变化, 直面问题和挑战, 不断精进, 我们下个话题再见👋🏻.

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
2月前
|
中间件 Go 数据库
Go开发者必读:Gin框架的实战技巧与最佳实践
在当今快速发展的互联网时代,Web开发的需求日益增长。Go语言以其简洁、高效、并发性强的特点,成为了开发者们的首选。而在Go语言的众多Web框架中,Gin无疑是其中的佼佼者。本文将深入探讨Gin框架的特性、优势以及如何利用Gin构建高性能的Web应用。
|
4月前
|
JSON JavaScript Go
Go 语言学习指南:变量、循环、函数、数据类型、Web 框架等全面解析
掌握 Go 语言的常见概念,如变量、循环、条件语句、函数、数据类型等等。深入了解 Go 基础知识的好起点是查阅 Go 官方文档
454 2
|
20天前
|
JSON 缓存 物联网
推荐一款go语言的开源物联网框架-opengw
推荐一款go语言的开源物联网框架-opengw
30 4
|
1月前
|
开发框架 JSON Go
Go语言Web开发基础与框架探索
【2月更文挑战第21天】本文将带领读者深入了解Go语言在Web开发领域的基础知识和常用框架。通过介绍Go语言的Web开发特点、核心库的使用,以及流行框架如Gin、Echo等的基本用法和优势,帮助读者快速上手Go语言Web开发,提升开发效率。
|
1月前
|
关系型数据库 MySQL 数据库连接
实战演练:使用Go语言和ORM框架与数据库进行交互
【2月更文挑战第13天】本文将通过一个实战演练,展示如何使用Go语言和ORM(对象关系映射)框架与数据库进行交互。我们将选择一个流行的ORM框架,如GORM,来完成这个任务。通过实际编码,我们将演示如何连接数据库、执行CRUD操作、处理错误和异常,并展示ORM框架如何简化数据库操作过程。
|
1月前
|
SQL 关系型数据库 MySQL
Go语言中的ORM框架介绍
【2月更文挑战第13天】本文将介绍ORM(对象关系映射)框架在Go语言中的应用。ORM框架能够简化数据库操作,将数据库表映射为Go结构体,并提供了一系列方法来执行CRUD(创建、读取、更新、删除)操作。我们将探讨几个流行的Go语言ORM框架,包括GORM、SQLBoiler和Squirrel,并比较它们的特性和用法。
|
2月前
|
XML JSON Java
RPC框架之Thrift—实现Go和Java远程过程调用
RPC框架之Thrift—实现Go和Java远程过程调用
46 1
|
3月前
|
关系型数据库 MySQL Go
go语言使用Gin框架链接数据库
go语言使用Gin框架链接数据库
41 0
|
3月前
|
存储 中间件 Go
7天用Go从零实现Web框架Gee教程
7天用Go从零实现Web框架Gee教程
51 0
|
4月前
|
JSON 中间件 Go
Go 框架 iris 文档(二)
Go 框架 iris 文档(二)
81 0

热门文章

最新文章