新手不懂提问,在中文网中的一个 高并发demo中,定义了一个worker chan ,然后服务器curl访问了几次后就无法访问了。新手找来找去发现不了问题。下面是我的代码。有大佬可以解答下吗?
---
**db.go**
```golang
package main
// 返回db实例
import (
"database/sql"
_ "github.com/go-sql-driver/mysql"
"log"
"sync"
)
type Database struct {
database *sql.DB
}
var dbinstance Database
var once sync.Once
// 返回数据库实例
func GetDB() *sql.DB {
once.Do(func() {
log.Println("mysql init")
var e error
dbinstance.database, e = sql.Open("mysql", "aaa@aaa@123tcp(localhost:3306)/box")
if e != nil {
log.Println("open sql err: ", e.Error())
}
})
return dbinstance.database
}
```
---
**job.go**
```golang
package main
// 定义job接口
import "database/sql"
type job interface {
Do(db *sql.DB)
}
```
---
** worker.go **
```golang
package main
// 打工人
import "log"
// 打工人的工作和推出状态
type Worker struct {
jobs chan job
quit chan bool
}
func NewWorker() Worker{
return Worker{make(chan job), make(chan bool)}
}
var database = GetDB()
// 打工人开始工作,从chanel接受job
func (w Worker) Run( wp chan chan job ) {
log.Println("worker start run ")
go func() {
for {
wp <- w.jobs
select {
case job := <- w.jobs:
job.Do(database)
// 这里的stop无效,为什么?
w.Stop()
case q := <- w.quit :
if q {
log.Println("worker stop ")
return
}
}
}
}()
}
// 发送停止工作状态
func (w Worker) Stop(){
log.Println("stop start")
go func() {
w.quit <- false
}()
log.Println("stop end")
}
```
---
** workerpool.go**
```golang
package main
// 打工人的.....池
import "log"
// 定义很多打工人、要有多少个人、有多少个工作
type workerpool struct {
workers chan chan job
workernum int
jobqueue chan job
}
// 创建workerpool
func NewWorkerPool(workernum int) *workerpool{
return &workerpool{
workers: make(chan chan job, workernum),
workernum: workernum,
jobqueue: make(chan job)}
}
// 根据workernum生成worker
func (wp workerpool) init(){
log.Println("workerpool init ")
for i := 0; i < wp.workernum;i++{
worker := NewWorker()
worker.Run(wp.workers)
}
}
// 工人池开始工作
func (wp workerpool) Run (){
log.Println("workerpool start run ")
go func() {
for {
select {
case job := <- wp.jobqueue:
log.Println("worker start working ")
worker := <- wp.workers
worker <- job
}
}
}()
}
```
---
** main.go **
```golang
package main
import (
"database/sql"
"encoding/json"
"fmt"
_ "github.com/go-sql-driver/mysql"
"log"
"net/http"
"runtime"
"time"
)
type netInfo struct {
SNCode string
Option string
Status chan string
}
// 实现DO接口,接受从http发送来的数据(netInfo),来做查询或插入操作
func (n *netInfo) Do(db *sql.DB) {
log.Println("doing sth")
db.Ping()
if n.Option == "query" {
log.Println("doing query")
row := db.QueryRow("select SNCode from boxInfo where SNCode = ?", n.SNCode)
var res string
err := row.Scan(&res)
if err != nil{
log.Println("query err: ", err.Error())
n.Status <- "false"
} else {
log.Println("query res: "+ res + " len: ", len(res))
n.Status <- "true"
}
}else if n.Option == "save" {
log.Println("doing save")
_, e := db.Exec("insert into boxInfo(SNCode) values (?)", n.SNCode)
if e != nil {
log.Println("insert err: ", e.Error())
n.Status <- "false"
//time.Sleep(10 * time.Microsecond)
} else {
n.Status <- "true"
// time.Sleep(10 * time.Microsecond)
}
}
n.Status <- "false"
time.Sleep(10 * time.Microsecond)
}
// 根据cpu核心数量来定义最多有多少个打工人
var wp = NewWorkerPool(runtime.NumCPU())
func main() {
http.HandleFunc("/", save_info_from_http)
log.Println("start")
db := GetDB()
db.Ping()
// workerpool初始化
wp.init()
wp.Run()
// 这边是为了看wp中还有多少个worker,
// 在测试的时候用服务器 curl 一次少一个,还不会自动恢复
// 电脑是六个核心的,也就是访问六次后 就一直被阻塞了。curl一直卡住
go func() {
for {
log.Println(len(wp.workers))
time.Sleep(time.Second * 3)
}
}()
err := http.ListenAndServe(":8000", nil)
if err != nil {
log.Fatal("ListenAndServe: ", err.Error())
}
}
// http访问('/') 调用的函数
func save_info_from_http(w http.ResponseWriter, r *http.Request){
// 解析http的body数据
var netinfo netInfo
e := json.NewDecoder(r.Body).Decode(&netinfo)
if e != nil{
fmt.Println("json err:", e.Error())
}
// Status用于http返回状态,设置为 true或false
netinfo.Status = make(chan string)
// 给打工人发工作
wp.jobqueue <- &netinfo
// 接受返回状态
status := <- netinfo.Status
time.Sleep(time.Microsecond)
fmt.Fprintf(w,status)
}
```
.
.
.
.
.
.
.
.
上面是我的代码,想请问下,非缓冲的chanel使用了上限后就没法在访问了。在我的电脑上是六个,也就是curl访问六次后就一直无法返回数据,服务端的日志也没有接受到信息。请论坛大佬解答下
有疑问加站长微信联系(非本文作者)