Jex’s Note

Golang - Job Queue

介紹

Job Queue 是一個工作的等待區,只要有工作就往 Queue 裡面塞,背景有隻程式會去 Queue 裡面找工作做, 最主要的目的是除了讓使用者的體驗更好之外,也可以讓 Web app server 的工作單純一點,將複雜的工作交給專門執行 job queue 的主機, 例如圖片縮圖, 寄信.. etc.

goworker

介紹

Goworker 是 golang 的一套 job queue 的 package,它可以幫你達成這些事,它是使用 resque 的資料格式(resque 有固定的資料格式), resque 是一套 Ruby 開發的 job queue,也有被其他的語言開發成該語言的版本,你可以把它當作是 golang 版的 resque, 最主要的好處是你後端語言可以用 php, ruby etc. 你想的語言寫,把它丟到 redis 裡的 job queue, 然候 goworker 再去拿, 並針對不同的 task 寫出不同對應的程式

Worker

package main

import (
    "fmt"
    "time"

    "github.com/benmanns/goworker"
)

func myFunc(queue string, args ...interface{}) error {
    fmt.Printf("From %s, %v\n", queue, args)
    return nil
}

func init() {
    goworker.Register("MyClass", myFunc)
}

func main() {
    if err := goworker.Work(); err != nil {
        fmt.Println("Error:", err)
    }
    fmt.Printf("Started on %v", time.Now().Format("2006-01-02 15:04:05"))
}

Run :

go run main.go -queues=MyClass

增加一筆 job 讓 worker 執行

你也可以用其他語言 insert 一筆 job

package main

import (
    "encoding/json"
    "log"
    "time"

    "github.com/garyburd/redigo/redis"
)

var redisPool redis.Pool

func init() {
    redisPool = redis.Pool{
        MaxIdle:     3,
        MaxActive:   0, // When zero, there is no limit on the number of connections in the pool.
        IdleTimeout: 30 * time.Second,
        Dial: func() (redis.Conn, error) {
            conn, err := redis.Dial("tcp", "127.0.0.1:6379")
            if err != nil {
                log.Fatal(err.Error())
            }
            return conn, err
        },
    }
}

func main() {
    redisConn := redisPool.Get()
    x := map[string]interface{}{
        "foo": []string{"a", "b"},
        "bar": "foo",
        "baz": 10.4,
    }
    resque := map[string]interface{}{
        "class": "MyClass",
        "args":  []interface{}{x},
    }
    b, _ := json.Marshal(resque)
    redisConn.Do("RPUSH", "resque:queue:MyClass", string(b[:]))
}

Run :

go run qq.go

結果 :

worker 就會 print 那筆 job 的資料

Comments