go延时队列
package main
import (
"errors"
"flag"
"fmt"
log "github.com/cihub/seelog"
"github.com/garyburd/redigo/redis"
"github.com/robfig/cron"
"runtime"
"strings"
"sync"
"time"
)
var ch chan int = make(chan int)
//声明一些全局变量
var (
pool *redis.Pool
redisServer = flag.String("h", "10.100.68.50:6379", "")
// redisServer = flag.String("h", "pre-mds-sa.bhptzj.0001.sae1.cache.amazonaws.com:6379", "")
redisPassword = flag.String("p", "", "")
redisDbName = flag.String("db", "1", "")
)
/**
* [timerLog description]
* @param {[type]} logFileName string [description]
* @param {[type]} logLevel string [Warning Debug Error Info]
* @param {[type]} logContent string [description]
* @return {[type]} [description]
*/
func timerLog(logLevel string, logContent string) {
config := `
<seelog>
<outputs formatid="testSeeLog">
<filter levels="debug,error,info">
<file path="./error.log" />
</filter>
</outputs>
<formats>
<format id="testSeeLog" format="%Date/%Time [%LEV] %Msg%n"/>
</formats>
</seelog>
`
defer log.Flush()
logger, _ := log.LoggerFromConfigAsBytes([]byte(config))
log.ReplaceLogger(logger)
if logLevel == "error" {
log.Error(logContent)
} else if logLevel == "debug" {
log.Error(logContent)
} else {
log.Info(logContent)
}
}
/**
* 初始化一个pool
*/
func newPool(server, password string) *redis.Pool {
return &redis.Pool{
MaxIdle: 3,
MaxActive: 5,
IdleTimeout: 240 * time.Second,
Dial: func() (redis.Conn, error) {
c, err := redis.Dial("tcp", server)
if err != nil {
fmt.Println("conn error:%s",err.Error())
timerLog("error", server+" conn error :"+err.Error())
return nil, err
}
if password != "" {
if _, err := c.Do("AUTH", password); err != nil {
c.Close()
fmt.Println("pass auth error :%s",err.Error())
timerLog("error", server+" pass auth error :"+err.Error())
return nil, err
}
}
if _, err := c.Do("SELECT", *redisDbName); err != nil {
fmt.Println("db exists error :%s",err.Error())
timerLog("error", server+" db exists error :"+err.Error())
c.Close()
return nil, err
}
return c, err
},
TestOnBorrow: func(c redis.Conn, t time.Time) error {
if time.Since(t) < time.Minute {
return nil
}
_, err := c.Do("PING")
return err
},
}
}
var ErrValueFormatError = errors.New("bucket: value format is error,may be topic,id")
var ErrValueTypeError = errors.New("bucket: value type is error,may be number")
var lock sync.Mutex
func timerProcess(key string) (string, error) {
lock.Lock()
pool = newPool(*redisServer, *redisPassword)
conn := pool.Get()
defer func() {
pool.Close()
conn.Close()
lock.Unlock()
}()
// conn.Do("select",*redisDbName)
t := time.Now().Unix()
rs, errGet := redis.Values(conn.Do("ZREVRANGEBYSCORE", key, t, 0))
if errGet != nil {
timerLog("error", key+":"+errGet.Error())
return key, errGet
}
for _, v := range rs {
value := string(v.([]byte))
topicAndId := strings.Split(value, ",")
var topic string
var queueId string
if len(topicAndId) == 2 {
topic = topicAndId[0]
queueId = topicAndId[1]
_, errSet := conn.Do("rpush", topic, queueId)
if errSet != nil {
timerLog("error", key+"-"+value+":"+errSet.Error())
} else {
_, errDel := conn.Do("zrem", key, value)
if errDel != nil {
timerLog("error", key+"-"+value+":"+errDel.Error())
}
}
} else {
timerLog("error", key+"-"+value+":"+ErrValueFormatError.Error())
}
}
ch <- 1
return "success", nil
}
var dbLock sync.Mutex
func main() {
flag.Parse()
// fmt.Println("begin")
runtime.GOMAXPROCS(runtime.NumCPU())
/**
Seconds | Yes | 0-59 | * / , -
Minutes | Yes | 0-59 | * / , -
Hours | Yes | 0-23 | * / , -
Day of month | Yes | 1-31 | * / , - ?
Month | Yes | 1-12 or JAN-DEC | * / , -
Day of week | Yes | 0-6 or SUN-SAT | * / , - ?
**/
c := cron.New()
spec := "*/1 * * * * *"
c.AddFunc(spec, func() {
dbLock.Lock()
pool = newPool(*redisServer, *redisPassword)
conn := pool.Get()
defer func() {
pool.Close()
conn.Close()
dbLock.Unlock()
}()
// conn.Do("SELECT",*redisDbName)
keys, errGet := redis.Values(conn.Do("keys", "DELAY_BUCKET_*"))
// fmt.Print(keys)
if errGet != nil {
timerLog("error", "get keys error:"+errGet.Error())
panic("get keys error:" + errGet.Error())
c.Stop()
}
for _, k := range keys {
key := string(k.([]byte))
// fmt.Println(key)
go timerProcess(key)
}
for i := 0; i < len(keys); i++ {
fmt.Println(i)
<-ch
}
})
c.Start()
select {}
}
go延时队列的更多相关文章
- 10 DelayQueue 延时队列类——Live555源码阅读(一)基本组件类
这是Live555源码阅读的第一部分,包括了时间类,延时队列类,处理程序描述类,哈希表类这四个大类. 本文由乌合之众 lym瞎编,欢迎转载 www.cnblogs.com/oloroso/ 本文由乌合 ...
- 9 DelayQueueEntry 延时队列节点类——Live555源码阅读(一)基本组件类
这是Live555源码阅读的第一部分,包括了时间类,延时队列类,处理程序描述类,哈希表类这四个大类. 本文由乌合之众 lym瞎编,欢迎转载 http://www.cnblogs.com/oloroso ...
- 8 延时队列相关类——Live555源码阅读(一)基本组件类
这是Live555源码阅读的第一部分,包括了时间类,延时队列类,处理程序描述类,哈希表类这四个大类. 本文由乌合之众 lym瞎编,欢迎转载 http://www.cnblogs.com/oloroso ...
- 简析LIVE555中的延时队列
http://www.cnblogs.com/nightwatcher/archive/2011/04/10/2011158.html 最近在看LIVE555的源码,感觉其中的延时队列写的不错,于是就 ...
- Redis学习笔记之延时队列
目录 一.业务场景 二.Redis延时队列 一.业务场景 所谓延时队列就是延时的消息队列,下面说一下一些业务场景比较好理解 1.1 实践场景 订单支付失败,每隔一段时间提醒用户 用户并发量的情况,可以 ...
- 了解一下Redis队列【缓兵之计-延时队列】
https://www.cnblogs.com/wt645631686/p/8454021.html 我们平时习惯于使用 Rabbitmq 和 Kafka 作为消息队列中间件,来给应用程序之间增加 异 ...
- Redis简单延时队列
Redis实现简单延队列, 利用zset有序的数据结构, score设置为延时的时间戳. 实现思路: 1.使用命令 [zrangebyscore keyName socreMin socreMax] ...
- RabbitMQ学习之延时队列
原帖参考:http://www.cnblogs.com/telwanggs/p/7124687.html?utm_source=itdadao&utm_medium=referral http ...
- RabbitMQ进阶使用-延时队列的配置(Spring Boot)
依赖 MAVEN配置pom.xml <dependency> <groupId>org.springframework.boot</groupId> <art ...
- java实现rabbitMQ延时队列详解以及spring-rabbit整合教程
在实际的业务中我们会遇见生产者产生的消息,不立即消费,而是延时一段时间在消费.RabbitMQ本身没有直接支持延迟队列功能,但是我们可以根据其特性Per-Queue Message TTL和 Dead ...
随机推荐
- Shell 变量、脚本参数
定义变量:可将脚本或者多个命令定义成一个变量. ()格式n(){脚本命令}. 脚本常用参数 命令:seq –w 0 23 #以01开头往上的. 命令:echo –ne #输出n换行,e扩展. 命令:b ...
- oracle 老用户数据导入新建用户
$sqlplus/nolog #使用PLSQL进入oracleSQL>conn/as sysdba #进入sysdba权限CREATE DIRECTORY datadir1 AS ' ...
- 第十届蓝桥杯2019年C/C++ 大学A组省赛试题
2019年蓝桥杯第十届软件类省赛 C/C++ 大 学 A 组 试题 A: 平方和 本题总分:5 分 [问题描述] 小明对数位中含有 2.0.1.9 的数字很感兴趣,在 1 到 40 中这样的数包括 1 ...
- Lintcode376-Binary Tree Path Sum-Easy
376. Binary Tree Path Sum Given a binary tree, find all paths that sum of the nodes in the path equa ...
- SpringMVC 搭建
1. 新建一个项目 Paste_Image.png 我们用eclipse新建项目,选择Dynamic Web Project(动态的Web项目). 点击Next Paste_Image.png ...
- Pandas 基础(7) - Group By 分组的相关知识
首先, 引入这节需要的 csv 文件 (已上传) import pandas as pd city_df = pd.read_csv('/Users/rachel/Sites/pandas/py/pa ...
- spring cloud 版本号与 boot版本之间的对应关系(版本不对,会导致pom无法引入)
版本号规则 Spring Cloud并没有熟悉的数字版本号,而是对应一个开发代号. 开发代号看似没有什么规律,但实际上首字母是有顺序的,比如:Dalston版本,我们可以简称 D 版本,对应的 Edg ...
- linux软件管理之源码包管理
源码包管理tarball ====================================================================================tar ...
- port 执行命令的封装和参数详解
下面代码摘自rebar_utils.erl -module(tt7). %-export([start/0]). -compile(export_all). -define(FAIL, abort() ...
- WebApi 全局使用filter
先上代码: public static class WebApiConfig { public static void Register(HttpConfiguration config) { // ...