百万并发实现 1 Million Concurrency
// 实现百万并发
package main
import (
"fmt"
"time"
"runtime"
)
type Score struct {
Num int
}
func (s *Score) Do() {
fmt.Println("num:", s.Num)
time.Sleep(1 * 1 * time.Second)
}
// job
type Job interface {
Do()
}
// worker
type Worker struct {
JobQueue chan Job
}
func NewWorker() Worker {
return Worker{JobQueue: make(chan Job)}
}
func (w Worker) Run(wq chan chan Job) {
go func() {
for {
wq <- w.JobQueue
select {
case job := <-w.JobQueue:
job.Do()
}
}
}()
}
// workerpool
type WorkerPool struct {
workerlen int
JobQueue chan Job
WorkerQueue chan chan Job
}
func NewWorkerPool(workerlen int) *WorkerPool {
return &WorkerPool{
workerlen: workerlen,
JobQueue: make(chan Job),
WorkerQueue: make(chan chan Job, workerlen),
}
}
func (wp *WorkerPool) Run() {
fmt.Println("init worker")
for i := 0; i < wp.workerlen; i++ {
worker := NewWorker()
worker.Run(wp.WorkerQueue)
}
go func() {
for {
select {
case job := <- wp.JobQueue:
worker := <- wp.WorkerQueue
worker <- job
}
}
}()
}
func main() {
num := 100 * 100 * 20
// debug.SetMaxThreads(num + 1000) // 设置最大线程数
p := NewWorkerPool(num)
p.Run()
datanum := 100 * 100 * 100 * 100
go func() {
for i := 1; i <= datanum; i++ {
sc := &Score{Num: i}
p.JobQueue <- sc
}
}()
for {
fmt.Println("runtime.NumGoroutine(): ", runtime.NumGoroutine())
time.Sleep(2 * time.Second)
}
}
参考文献 http://marcio.io/2015/07/handling-1-million-requests-per-minute-with-golang/