2018/06/27 21:21:12 http: panic serving 10.105.107.106:41488: runtime error: invalid memory address or nil pointer dereference goroutine 1238 [running]: net/http.(conn).serve.func1(0xc420195a40) /usr/local/go/src/net/http/server.go:1726 +0xd0 panic(0x701840, 0x91fd70) /usr/local/go/src/runtime/panic.go:502 +0x229 database/sql.(Stmt).ExecContext(0x0, 0x7a82a0, 0xc4200160d0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0) /usr/local/go/src/database/sql/sql.go:2224 +0x4a database/sql.(Stmt).Exec(0x0, 0x0, 0x0, 0x0, 0x7efe6b4862a8, 0xc4201ce600, 0x0, 0xc42017e555) /usr/local/go/src/database/sql/sql.go:2253 +0x65 main.mpp(0x7a7fe0, 0xc4203421c0, 0xc420332500) /root/golang_mysql_proxy_pool/pool.go:151 +0x12e1 net/http.HandlerFunc.ServeHTTP(0x77e138, 0x7a7fe0, 0xc4203421c0, 0xc420332500) /usr/local/go/src/net/http/server.go:1947 +0x44 net/http.(ServeMux).ServeHTTP(0x92c0a0, 0x7a7fe0, 0xc4203421c0, 0xc420332500) /usr/local/go/src/net/http/server.go:2337 +0x130 net/http.serverHandler.ServeHTTP(0xc420097110, 0x7a7fe0, 0xc4203421c0, 0xc420332500) /usr/local/go/src/net/http/server.go:2694 +0xbc net/http.(conn).serve(0xc420195a40, 0x7a8260, 0xc4201d0800) /usr/local/go/src/net/http/server.go:1830 +0x651 created by net/http.(Server).Serve /usr/local/go/src/net/http/server.go:2795 +0x27b
求大神runtime error: invalid memory address or nil pointer dereference
vincent_zzh33 · 2018-06-27 21:25:19 · 954 次点击package main
import ( "database/sql" "fmt" "github.com/go-sql-driver/mysql" "github.com/lib/pq" _ "github.com/ziutek/mymysql/godrv" "log" "net/http" // "strings" "encoding/json" // "os" "regexp" "runtime" "strconv" "time" )
// /** var config = readConfig()
// fmt.Println(config) // var max_pool = strconv.ParseInt(string(config["max_pool_size"]), 10, 0) // **/
var MAX_POOL_SIZE = 10 var MySQLPool chan sql.DB func getPool() sql.DB { config := readConfig() parallelnum, := strconv.ParseInt(config["parallel_num"], 10, 0) runtime.GOMAXPROCS(int(parallel_num))
dbAdapter := config["db_adapter"]
dbhost := config["dbhost"]
dbport := config["dbport"]
dbuser := config["dbuser"]
dbpwd := config["dbpwd"]
dbname := config["dbname"]
// fmt.Println(config)
// fmt.Println(config["bind"])
if MySQLPool == nil {
MySQLPool = make(chan *sql.DB, MAX_POOL_SIZE)
}
if len(MySQLPool) == 0 { //if no DB conn, we make the pool
max_pool, _ := strconv.ParseInt(config["max_pool_size"], 10, 0)
// fmt.Println(max_pool)
go func() {
for i := 0; i < int(max_pool); i++ {
fmt.Println("crean DB conn....")
// mysqlc, err := sql.Open("mymysql", "tcp:127.0.0.1:3306*test/root/")
if dbAdapter == "mysql" {
//mysql conn
mysqlc, err := sql.Open("mymysql", "tcp:"+dbhost+":"+dbport+"*"+dbname+"/"+dbuser+"/"+dbpwd)
if err != nil {
panic(err)
}
putPool(mysqlc)
} else if dbAdapter == "pgsql" {
//pgsql conn
// mysqlc, err := sql.Open("postgres", "user=postgres_user password=password host=172.16.2.29 dbname=my_postgres_db sslmode=disable")
postgrec, err := sql.Open("postgres", "user="+dbuser+" password="+dbpwd+" host="+dbhost+" port="+dbport+" dbname="+dbname+" sslmode=disable")
if err != nil {
panic(err)
}
putPool(postgrec)
}
}
}()
}
return <-MySQLPool //parallel return DB conn use pool
}
func putPool(conn sql.DB) { // fmt.Println("crean DB conn....") if MySQLPool == nil { MySQLPool = make(chan sql.DB, MAX_POOL_SIZE) } if len(MySQLPool) == MAX_POOL_SIZE { conn.Close() return } MySQLPool <- conn }
func mpp(w http.ResponseWriter, r http.Request) { if r.Method == "POST" { /*
* the json return back
* code 0 is for success
* 1 is for wrong query
* 2 is for wrong get data
* status success or fail
* rows query data
**/
var back = make(map[string]interface{}) //return json
back["code"] = 0
back["status"] = "success"
back["rows"] = ""
var errCode = 0
uukey := r.FormValue("uukey")
if uukey != config["uukey"] {
back["code"] = 3
back["status"] = "fail"
// log.Fatal("uukey not the same")
errCode = 1
}
cache := r.FormValue("cache") //cache enable
ccKey := r.FormValue("cache_key") //cache key
ccTime := r.FormValue("cctime") //cache time
if errCode == 0 { //check secure uukey
query := r.FormValue("query")
fmt.Println("query is: ", query)
// os.Exit(3)
//get cache info
if query == "cc_info" { //get all cache info
// ccInfo()
cc_info := ccInfo()
fmt.Fprintf(w, cc_info)
return
} else if config["cache"] == "1" && query == "cc_get" { //get cache by key
// ccGet(ccKey)
fmt.Fprintf(w, ccGet(ccKey))
return
}
//get DB data
dbx := getPool() //get the DB conn from pool when we want to use
//regular check sql insert/update/delete
querySelect := 1
matchedI, _ := regexp.MatchString("insert.*", query)
matchedD, _ := regexp.MatchString("delete.*", query)
matchedU, _ := regexp.MatchString("update.*", query)
// fmt.Println("regular query: ", matched)
//if not select query
if matchedI || matchedD || matchedU {
// fmt.Println("not select query")
stmt, _ := dbx.Prepare(query)
res, _ := stmt.Exec()
// fmt.Println("res: ", res)
// return res.RowsAffected()
affect, _ := res.RowsAffected()
// fmt.Println("affect: ", affect)
back["rows"] = int(affect)
// back["rows"] = 1
querySelect = 0
// return
} else {
// var rows interface{}
// rows, errQuery := dbx.Query(query)
rows, errQuery := dbx.Query(query)
// rows, affRows, errQuery := dbx.Query(query)
// fmt.Println("rows: ", rows)
// fmt.Println("affRows: ", affRows)
// fmt.Println("affRows: ", rows.RowsAffected())
if errQuery != nil {
back["code"] = 1
back["status"] = "fail"
// log.Fatal(err)
fmt.Println(errQuery)
errCode = 1
}
if errQuery == nil {
// var email string
colNames, err := rows.Columns()
checkErr(err)
readCols := make([]interface{}, len(colNames))
writeCols := make([][]byte, len(colNames))
// writeCols := make([]byte, len(colNames))
// writeCols := make([]interface{}, len(colNames))
for i, _ := range writeCols {
readCols[i] = &writeCols[i]
}
result := make([]map[string]interface{}, 0)
// fmt.Println("len res:", len(result))
// fmt.Println(result)
// fmt.Println(colNames)
for rows.Next() {
if err := rows.Scan(readCols...); err != nil {
log.Fatal(err)
back["code"] = 2
back["status"] = "fail"
}
// fmt.Println(writeCols)
var tmpStr string
tmpMap := make(map[string]interface{})
for i, raw := range writeCols {
// var tmpStr string
if raw == nil {
// result[i] = "\\N"
} else {
tmpStr += string(raw)
tmpMap[colNames[i]] = string(raw)
}
}
result = append(result, tmpMap)
}
if err := rows.Err(); err != nil {
log.Fatal(err)
}
// fmt.Println(result)
// back["rows"] = resStr
back["rows"] = result
}
// defer putPool(dbx) //put the DB conn into pool after finish used
}
defer putPool(dbx) //put the DB conn into pool after finish used
//just query DB
jsback, _ := json.Marshal(back)
//if set cache
if string(config["cache"]) == "1" && cache == "1" && ccKey != "" && querySelect == 1 {
startTime := strconv.FormatInt(time.Now().Unix(), 10)
ccJsback := string(jsback) + string(config["cache_split"]) +
string(startTime) + ":" + ccTime
//store cache
// ccSet(ccKey, string(jsback))
ccSet(ccKey, string(ccJsback))
}
// jsback, _ := json.Marshal(result)
fmt.Fprintf(w, string(jsback))
// defer putPool(dbx)
}
}
}
报错是这行 mysqlc, err := sql.Open("mymysql", "tcp:"+dbhost+":"+dbport+"*"+dbname+"/"+dbuser+"/"+dbpwd)