golang 高并发任务处理方案

这个主要用golang 的chan 和routine属性做的,比很多语言方便多了,可以参考参考,​

​

//任务的请求
type MtaskRequest struct {
    Ceshi int
    // [redacted]
}

//job队列+work池
var (
    MaxWorker = os.Getenv("MAX_WORKERS")
    MaxQueue  = os.Getenv("MAX_QUEUE")
)

// Job represents the job to be run
type Job struct {
    MtaskRequest MtaskRequest
}

// A buffered channel that we can send work requests on.

// var JobQueue chan Job ---这样申明会卡主,没有初始化
var JobQueue = make(chan Job)

// Worker represents the worker that executes the job
type Worker struct {
    WorkerPool chan chan Job
    JobChannel chan Job
    quit       chan bool
}

func NewWorker(workerPool chan chan Job) Worker {
    return Worker{
        WorkerPool: workerPool,
        JobChannel: make(chan Job),
        quit:       make(chan bool)}
}

// Stop signals the worker to stop listening for work requests.
func (w Worker) Stop() {
    go func() {
        w.quit <- true
    }()
}

type Dispatcher struct {
    // A pool of workers channels that are registered with the dispatcher
    WorkerPool chan chan Job
    maxWorkers int
}

func NewDispatcher(maxWorkers int) *Dispatcher {
    pool := make(chan chan Job, maxWorkers)
    return &Dispatcher{WorkerPool: pool, maxWorkers: maxWorkers}
}

// Start method starts the run loop for the worker, listening for a quit channel in
// case we need to stop it
func (w Worker) Start() {
    go func() {
        for {
            // register the current worker into the worker queue.
            w.WorkerPool <- w.JobChannel
            select {
            case <-w.JobChannel:
                time.Sleep(5 * time.Second)
                // we have received a work request.
                fmt.Println("调起worker")
            case <-w.quit:
                // we have received a signal to stop
                return
                //不能写default
            }
        }
    }()
}

func (d *Dispatcher) Run() {
    //启动一定数量的worker
    fmt.Println("启动一定数量的worker")
    for i := 0; i < d.maxWorkers; i++ {
        worker := NewWorker(d.WorkerPool)
        worker.Start()
    }

    go d.dispatch()
}

//分派任务
func (d *Dispatcher) dispatch() {
    for {
        select {
        case job := <-JobQueue: //接收一个job请求
            fmt.Println("JobQueue 收到请求")

            go func(job Job) {
                // try to obtain a worker job channel that is available.
                // this will block until a worker is idle
                jobChannel := <-d.WorkerPool
                // dispatch the job to the worker job channel
                jobChannel <- job
            }(job)
        }
    }
}

//接收到红包数据
func (this *TaskRedbao) UserGetRedbao(red_id, uid, shop_id, rand_arr, Amoney string) error {
    fmt.Println("收到 接收到红包数据 http请求")
    mtaskRequest := MtaskRequest{67}
    work := Job{MtaskRequest: mtaskRequest}

    JobQueue <- work
    return nil
}

​

参考文章 http://marcio.io/2015/07/handling-1-million-requests-per-minute-with-golang/

你可能感兴趣的:(golang 高并发任务处理方案)