golang基于redis lua封装的优先级去重队列

前言:

前两天由于某几个厂商的api出问题,导致后台任务大量堆积,又因为我这边任务流系统会重试超时任务,所以导致队列中有大量的重复任务。这时候我们要临时解决两个事情,一件事情,让一些高质量的任务优先执行; 另一件事情, 要有去重。 rabbitmq不能很好的针对这类情况去重、分优先级。

这时候我又想到了我最爱的redis… 去重? list + set 就可以解决, 优先级,zset + zrange + zrem 也可以解决… 但问题这几个命令非原子,那么怎么让他们原子? 写模块 or redis lua script . 首先在 redis 4.x 写了个简单的module,但写完了发现一件颇为重要的事情,我们线上的是3.2 …. 然后又花了点时间改成redis lua的版本。项目本身的功能实现很简单,复杂的是创意 !!!

项目名: redis_unique_queue, 项目地址,https://github.com/rfyiamcool/redis_unique_queue

该文章后续会有更新, 原文地址, http://xiaorui.cc/?p=4828

主要功能介绍:

使用redis lua script 封装的去重及优先级队列方法, 达到了组合命令的原子性和节省来往的io请求的目的.

去重队列:

不仅能保证FIFO, 而且去重.

优先级去重队列:

按照优先级获取任务, 并且去重.

使用方法:

# xiaorui.cc

# PriorityQueue

NewPriorityQueue(priority int, unique bool, r *redis.Pool)

Push(q string, body string, pri int) (int, error)

Pop(q string) (resp string, err error)

# UniqueQueue

NewUniqueQueue(r *redis.Pool) *UniqueQueue

UniquePush(q string, body string) (int, error)

UniquePop(q string) (resp string, err error)

more..

下面是优先级去重队列的例子:

package main

// xiaorui.cc

import (
	"fmt"

	"github.com/rfyiamcool/redis_unique_queue"
)

func main() {
	fmt.Println("start")
	redis_client_config := unique_queue.RedisConfType{
		RedisPw:          "",
		RedisHost:        "127.0.0.1:6379",
		RedisDb:          0,
		RedisMaxActive:   100,
		RedisMaxIdle:     100,
		RedisIdleTimeOut: 1000,
	}
	redis_client := unique_queue.NewRedisPool(redis_client_config)

	qname := "xiaorui.cc"
	body := "message from xiaorui.cc"

	u := unique_queue.NewPriorityQueue(3, true, redis_client)
	// 3: 3个优先级,从1-3级
	// true: 开启unique set

	u.Push(qname, body, 2)
	// 2, 优先级

	fmt.Println(u.Pop(qname))
}

单单使用 去重队列的例子:

package main

import (
	"fmt"

	"github.com/rfyiamcool/redis_unique_queue"
)

func main() {
	fmt.Println("start")
	redis_client_config := unique_queue.RedisConfType{
		RedisPw:          "",
		RedisHost:        "127.0.0.1:6379",
		RedisDb:          0,
		RedisMaxActive:   100,
		RedisMaxIdle:     100,
		RedisIdleTimeOut: 1000,
	}
	redis_client := unique_queue.NewRedisPool(redis_client_config)


	qname := "xiaorui.cc"
	u := unique_queue.NewUniqueQueue(redis_client)
	for i := 0; i < 100; i++ {
		u.UniquePush(qname, "body...")
	}

	fmt.Println(u.Length(qname))

	for i := 0; i < 100; i++ {
		u.UniquePop(qname)
	}

	fmt.Println(u.Length(qname))


	fmt.Println("end")
}

需要改进地址也是很多, 比如 加入批量操作, 对于redis连接池引入方法改进等.

END.

原文发布于微信公众号 - Golang语言社区(Golangweb)

原文发表时间:2018-02-15

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏大前端开发

微信小程序之内嵌网页(webview)

微信小程序提供了新的开放能力!它终于开放了在小程序中内嵌HTML页面的功能!从微信小程序基础库1.6.4开始,我们就可以在小程序内放置一个<web-view>组...

4283
来自专栏软件测试经验与教训

ADB命令集锦

在测试APP时,我们常常会用到adb命令来协助测试,那么adb命令到底是什么?有什么用?怎么用?

2545
来自专栏余生开发

cypress e2e 测试神器 安装使用及语法

cypress 我们直接去Cypress的官网,根据教程我们先进入我们项目的根目录,执行npm install cypress --save-dev,在安装完成...

2653
来自专栏一“技”之长

获取iOS应用的URL Schemes 原

3、打开iTunes,查看应用程序,选中相应的应用程序点击右键,选择在Finder中显示,然后解压ipa文件,得到一个文件夹。

1003
来自专栏DeveWork

WordPress自定义url 中的“author” 别名

默认的话,WordPress 链接到文章“作者”的别名(slug name)是如 devework.com/author/name 那样的,通过下面的代码,可以...

2389
来自专栏我与狸奴不出门

基于CentOS搭建微信小程序--响应错误502

在腾讯云开发者实验室的搭建微信小程序中  ,遇到了在完成实验二会话部署失败后,实验一http访问测试也显示失败并且表示响应错误-错误码:502。(域名是可以正常...

3053
来自专栏腾讯云服务器团队的专栏

如何利用SCF实现定时开关机的功能

随着腾讯云的企业用户越来越多,而企业的场景也是多样化的,一方面作为云服务商需要不断地完善产品能力以满足更多业务需求,另一方面作为云用户其实也是可以利用已有的一些...

5.7K15
来自专栏北京马哥教育

Python微信后台开发--环境搭建与接入指南

0x00 背景及介绍 申请一个微信公众平台订阅号,将后台接入到服务器上,验证服务器地址的有效性,实现简单的业务逻辑,根据用户发送不同类型的消息做出不同的反应。 ...

4566
来自专栏PHP在线

如何通过预加载器提升网页加载速度

预加载器(Pre-loader)可以说是提高浏览器性能最重要的举措。Mozilla 官方发布数据,通过预加载器技术网页的加载性能提升了19%,Chrome测试了...

33110
来自专栏编程微刊

Git安装及密钥的生成并上传本地文件到GitHub上

2204

扫码关注云+社区

领取腾讯云代金券