程序代码片段是这样的:
maxPage := *flagMaxPage
if maxPage > 0 {
jobs := make(chan int, maxPage)
results := make(chan []map[string]string, maxPage)
// 招聘10个工人,让他们工作(待命),每个工人会从jobs管道里获得任务,工人干活,把结果放到results管道
for w := 1; w <= 10; w++ {
go doWork(jobs, results)
}
//分配任务
for j := 1; j <= maxPage; j++ {
jobs <- j
}
close(jobs)
//db connect
db, err := mysqlUtil.CreateReadDb()
defer db.Close()
if err != nil {
log.Fatal("connect db err ", err)
fmt.Println("connect db err ", err)
}
//处理结果
for j := 1; j <= maxPage; j++ {
data := <-results
//这里做查询和入库操作
doDb(db, data)
fmt.Println(len(data))
}
close(results)
fmt.Println("all done...")
}
doDb函数如下:
func doDb(db *sql.DB,data []map[string]string) {
if data != nil {
for _, v := range data {
if v == nil {
continue
}
if v["title"] == "" {
continue
}
if v["url"] == "" {
continue
}
//写入数据库
sqlStr := `select * from film where title_md5 ='` + Md5(v["title"]) + `'`
rows, err := db.Query(sqlStr)
if err != nil {
fmt.Println("query err1 ", err)
continue
}
existData, err := mysqlUtil.GetRow(rows)
if err != nil {
fmt.Println("query err2 ", err)
continue
}
//如果为空,就插入数据
if len(existData) == 0 {
score := v["score"]
scoreVal, err := strconv.ParseFloat(score, 64)
if err != nil {
fmt.Println("insert data parse score error ", err)
continue
}
f1 := decimal.NewFromFloat(scoreVal)
f2 := decimal.NewFromFloat(100)
aaa := f1.Mul(f2).IntPart()
insertScore := strconv.Itoa(int(aaa))
titleMd5 := Md5(v["title"])
sqlInsert := `insert into film(title, img, uptime, url, score, title_md5) values ('` + v["title"] + `', '` + v["img"] + `', '` + v["uptime"] +
`','` + v["url"] + `','` + insertScore + `','` + titleMd5 + `')`
db.Query(sqlInsert)
}
}
}
}
测试了一下,大概跑20个协程,doDb这个函数的第二个参数一次最多15条数据,在执行到16个协程的结果后,就会在fmt.Println("query err1 ", err)这个地方报大量 :
query err1 dial tcp: lookup xxxx.com: no such host
在包这个错误的时候,我手动执行
nslookup xxxx.com
解析是正常的。请问一下,这是为啥呢?doDb这个函数是一个一个处理result的,一共才20*15条记录,为啥会出现这种问题呢?
在https://stackoverflow.com/que...。 在mac里执行ulimit -u 发现只有256,当操作300条数据的时候,大于这个值,所以会出现上面的问题。执行ulimit -n 1000,再次操作300条数据,就不会出现这种问题了。