我在go程序中對api進行大量Web調用,並將結果存儲在數據庫中(使用mgo)。 api調用是在單獨的例程中完成的。在其他例程中,我將信息從數據庫中提取出來並進行處理,然後再更新數據庫。當數據放回時,將設置一個標誌,以便知道該數據已經過後處理,因此當程序要求數據庫提供另一個條目以便後處理時,數據庫將返回一個標誌爲complete
的標誌設置爲。當標誌設置爲true時,關閉例行程序:wg.done()
。go(golang)對例程的mongodb查詢會產生巨大的堆棧跟蹤(使用mgo)
一切都很好,我有很多的打印輸出的告訴我的程序是怎樣了,但朝其運行結束時,我得到一個包含很多相同的一個巨大的堆棧跟蹤:
夠程56731 [sleep]:time.Sleep(0x12a05f200) /usr/local/Cellar/go/1.5/libexec/src/runtime/time.go:59+ 0xf9 gopkg.in/mgo%2ev2.(*mongoServer).pinger (0xc82601b420,0x1) /Users/alex/go/src/gopkg.in/mgo.v2/server.go:295+ 0x1b4由 創建gopkg.in/mgo%2ev2.newServer /Users/alex/go/src/gopkg.in/mgo.v2/server.go:88 + 0x162
夠程56698 [睡眠]:time.Sleep(0x12a05f200) /usr/local/Cellar/go/1.5/libexec/src/runtime/time.go:59 + 0xf9 gopkg.in/mgo%2ev2(。 * mongoServer).pinger(0xc82601bce0,0x1) /Users/alex/go/src/gopkg.in/mgo.v2/server.go:295+ 0x1b4由 創建gopkg.in/mgo%2ev2.newServer /Users /alex/go/src/gopkg.in/mgo.v2/server.go:88 + 0x162
夠程56699 [睡眠]:time.Sleep(0x1dcd6500) /usr/local/Cellar/go/1.5/ libexec/src/runtime/time.go:59 + 0xf9 gopkg.in/mgo%2ev2.(*mongoCluster).syncServersLoop(0xc8256425a0) /Users/alex/go/src/gopkg.in/mgo.v2/cluster 。去:353 + 0x2b1創建由 gopkg.in/mgo%2ev2.newCluster /Users/alex/go/src/gopkg.in/mgo.v2/cluster.go:73 +量0x1A0
夠程56738 [睡眠]:time.Sleep(0x12a05f200) /usr/local/Cellar/go/1.5/libexec/src/runtime/time.go:59+ 0xf9 gopkg.in/mgo%2ev2.(*mongoServer).pinger(0xc82606fa40) ,0x1) /Users/alex/go/src/gopkg.in/mgo.v2/server.go:295+ 0x1b4由 創建gopkg.in/mgo%2ev2.newServer /Users/alex/go/src/gopkg.in/mgo.v2/server.go:88+0x162
有一件事是所有thos e下面,這是堆棧跟蹤上面唯一不同的輸出(上面只是一個例子,我的終端不能回滾到開頭有這麼多)
goroutine 57201 [ IO等待]:net.runtime_pollWait(0xedb6f0,0x72, 0xc82000a2c0) /usr/local/Cellar/go/1.5/libexec/src/runtime/netpoll.go:157+ 0x60 net。(* pollDesc).Wait( 0xc827b0e5a0,0x72,0x0,0x0) /usr/local/Cellar/go/1.5/libexec/src/net/fd_poll_runtime.go:73+ 0x3a net。(* pollDesc).WaitRead(0xc827b0e5a0,0x0,0x0) /usr/local/Cellar/go/1.5/libexec/src/net/fd_poll_runtime.go:78+ 0x36 net。(* netFD).Read(0xc827b0e540,0x c828d61000,0x1000,0x1000,0x0, 0x754050,0xc82000a2c0) /usr/local/Cellar/go/1.5/libexec/src/net/fd_unix。(* conn).Read(0xc8260eac38,0xc828d61000,0x1000,0x1000,0x0,0x0, 0x0)/usr/local/Cellar/go/1.5/libexec/src/net/net.go(232)0x23a net。(* conn) :172 + 0xe4 淨/ http.noteEOFReader.Read(0x7960c0,0xc8260eac38,0xc82751fd38, 0xc828d61000,0x1000的,0x1000的,0xc82644dc20,爲0x0,爲0x0) /usr/local/Cellar/go/1.5/libexec/src/net/ http/transport.go:1370 + 0x67 net/http。(* noteEOFReader).Read(0xc826116e60,0xc828d61000,0x1000, 0x1000,0xc827d1a770,0x0,0x0):126 + 0xd0 bufio。(* Reader).fill 0xc82644d4a0) /usr/local/Cellar/go/1.5/libexec/src/bufio/bufio.go:97 + 0x1e9 BUFIO。(*閱讀器).Peek(0xc82644d4a0,爲0x1,爲0x0,爲0x0,爲0x0,爲0x0,爲0x0 ) /usr/local/Cellar/go/1.5/libexec/sr (* persistConn).readLoop(0xc82751fce0) /usr/local/Cellar/go/1.5/libexec/src/net/http/transport.go:876 + 0xf7 通過網/ HTTP創建的。(*運輸).dialConn /usr/local/Cellar/go/1.5/libexec/src/net/http/transport.go:685 + 0xc78
我努力弄清楚它告訴我什麼,是否鎖定寫入數據庫,例程是否關閉以及是否超時,我不知道。 我使用去1.5順便說一句。
如何解釋上述任何幫助將是偉大的。
與數據庫會談代碼如下:
func (l *Ledger) addRaceToDatabase(race Race) { //true if added,
false if existed
session, err := mgo.Dial("127.0.0.1")
if err != nil {
panic(err)
}
defer session.Close()
session.SetMode(mgo.Monotonic, true)
c := session.DB("collection").C("races")
// Index
index := mgo.Index{
Key: []string{"id"},
Unique: true,
DropDups: true,
Background: true,
Sparse: true,
}
err = c.EnsureIndex(index)
if err != nil {
panic(err)
}
result := Race{}
//if the race exists, don't add it to the database
err = c.Find(bson.M{"id": race.ID}).One(&result)
if err != nil {
//if there is an error there wasn't an entry so add this to the database
err = c.Insert(race)
if err != nil {
panic(err)
}
} else {
//if it does find an entry, it will print it
fmt.Println("FOUND: ", result.ID)
}
}
你需要上傳你的數據庫代碼,以幫助調試這個效率 - 特別是圍繞你如何使用goroutines。 – elithrar
編輯問題以包含與數據庫通信的代碼。 Thx – amlwwalker