设为首页 收藏本站
查看: 2298|回复: 0

[经验分享] 使用Redis做任务队列(Golang)

[复制链接]

尚未签到

发表于 2015-11-12 15:07:09 | 显示全部楼层 |阅读模式
在上篇用纯go在本机模拟了下分布式队列的东西。这里补上Redis队列部份。

用Redis做队列有下面三个问题需解决:



1. 队列构建

     使用Redis的RPUSH/LPOP来解决



2. 参数传递/解析

   客户端将JOSN参数存入Redis,Server端取出后解析还原。



3. 连接池

        redigo支持Redis连接池
  下面代码就是具体解决实现:
  

//Redis做后台任务队列
//author: Xiong Chuan Liang
//date: 2015-3-25
package main
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"time"
"github.com/garyburd/redigo/redis"
)
func main() {
r, err := newRedisPool("", "")
if err != nil {
fmt.Println(err)
return
}
//将job放入队列
r.Enqueue()
//依次取出两个Job
r.GetJob()
r.GetJob()
}
type RedisPool struct {
pool *redis.Pool
}
func newRedisPool(server, password string) (*RedisPool, error) {
if server == "" {
server = ":6379"
}
pool := &redis.Pool{
MaxIdle:     3,
IdleTimeout: 240 * time.Second,
Dial: func() (redis.Conn, error) {
c, err := redis.Dial("tcp", server)
if err != nil {
return nil, err
}
if password != "" {
if _, err := c.Do("AUTH", password); err != nil {
c.Close()
return nil, err
}
}
return c, err
},
TestOnBorrow: func(c redis.Conn, t time.Time) error {
_, err := c.Do("PING")
return err
},
}
return &RedisPool{pool}, nil
}
type Job struct {
Class string        `json:"Class"`
Args  []interface{} `json:"Args"`
}
//模拟客户端
func (r *RedisPool) Enqueue() error {
c := r.pool.Get()
defer c.Close()
j := &Job{}
j.Class = "mail"
j.Args = append(j.Args, "xcl_168@aliyun.com", "", "body", 2, true)
j2 := &Job{}
j2.Class = "Log"
j2.Args = append(j2.Args, "ccc.log", "ddd.log", []int{222, 333})
for _, v := range []*Job{j, j2} {
b, err := json.Marshal(v)
if err != nil {
return err
}
_, err = c.Do("rpush", "queue", b)
if err != nil {
return err
}
}
fmt.Println("[Enqueue()] succeed!")
return nil
}
//模拟Job Server
func (r *RedisPool) GetJob() error {
count, err := r.QueuedJobCount()
if err != nil || count == 0 {
return errors.New("暂无Job.")
}
fmt.Println("[GetJob()] Jobs count:", count)
c := r.pool.Get()
defer c.Close()
for i := 0; i < int(count); i++ {
reply, err := c.Do(&quot;LPOP&quot;, &quot;queue&quot;)
if err != nil {
return err
}
var j Job
decoder := json.NewDecoder(bytes.NewReader(reply.([]byte)))
if err := decoder.Decode(&j); err != nil {
return err
}
fmt.Println(&quot;[GetJob()] &quot;, j.Class, &quot; : &quot;, j.Args)
}
return nil
}
func (r *RedisPool) QueuedJobCount() (int, error) {
c := r.pool.Get()
defer c.Close()
lenqueue, err := c.Do(&quot;llen&quot;, &quot;queue&quot;)
if err != nil {
return 0, err
}
count, ok := lenqueue.(int64)
if !ok {
return 0, errors.New(&quot;类型转换错误!&quot;)
}
return int(count), nil
}
/*
运行结果:
[Enqueue()] succeed!
[GetJob()] Jobs count: 2
[GetJob()]  mail  :  [xcl_168@aliyun.com  body 2 true]
[GetJob()]  Log  :  [ccc.log ddd.log [222 333]]
[iyunv@xclos src]#
*/    可以看到Go已能取得参数。都是些最基础的东西。


  
  MAIL: xcl_168@aliyun.com
  BLOG: http://blog.iyunv.com
  


  


  


  



版权声明:本文为博主原创文章,未经博主允许不得转载。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-138419-1-1.html 上篇帖子: Redis的Java客户端Jedis的八种调用方式(事务、管道、分布式…)介绍 下篇帖子: redis多实例
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表