jjzjj

mongodb - GoLang MongoDB 连接泄漏

coder 2023-07-01 原文

您好

这是一个代码示例,每秒从 MongoDB 执行检索。 我的问题是每次检索都会打开额外的连接(根据 MongoDB 日志)

代码:

package main

import (
  "os"
  "fmt"
  "gopkg.in/mgo.v2"
  "time"
  "gopkg.in/mgo.v2/bson"
  )

const (
    host1       = "localhost"
    port1       = "27017"
    dbName      = "test_db"
    collectionName  = "TEST_COLLECTION"
)
type Data struct {
    InternalId   bson.ObjectId `bson:"_id" json:"_id,omitempty"`
    Key1         string
    Key2         string
    Key3         int64
}


func main() {

   fmt.Println("Starting mongo worker ... ")
   finished := make(chan bool)
   go DoWorkerJob(finished)
   <-finished
}


func DoWorkerJob(finished chan bool) {

  session, err := GetSession()
  defer     session.Close()

  if err != nil {
        panic(err)
        os.Exit(1)
   }


 for {
    fmt.Println("Retrieving data ...")
    collection := GetCollection(*session,collectionName)

    allData, err := GetAllRows(collection)
    if err != nil {
        panic(err)
        continue
    }

    if allData != nil {

        fmt.Println("Total retrieved: ", len(allData), " documents.")
    }


    time.Sleep(time.Duration(1000) * time.Millisecond)
  }

   finished <- true
}


 func GetAllRows(collection *mgo.Collection) ([]Data, error) {
   var results []Data

   err := collection.Find(nil).All(&results)
   if err != nil {
       panic(err)
       return nil, err
   }
   return results, nil
 }

func GetSession() (*mgo.Session, error) {
  fmt.Println("Creating session ...")
  MongoDBHosts1 := host1 + ":" + port1

  mongoDBDialInfo := &mgo.DialInfo{
      Addrs:    []string{MongoDBHosts1},
      Timeout:  5 * time.Second,
      Database: dbName,
  }

  mongoSession, err := mgo.DialWithInfo(mongoDBDialInfo)

  if err != nil {
      panic(err)
      return nil, err
  }

  mongoSession.SetSocketTimeout(5 * time.Second)
  mongoSession.SetMode(mgo.Monotonic, true)

  session := mongoSession.New()

  fmt.Println("Session created!")
  return session, nil
 }


func GetCollection(session mgo.Session, queueName string) (*mgo.Collection) 
{

  fmt.Println("Creating collection ...")
  collection := session.Copy().DB(dbName).C(queueName)
  fmt.Println("Collection created!")
  return collection

 }

程序输出:

Starting mongo worker ... 
Creating session ...
Session created!
Retrieving data ...
Creating collection ...
Collection created!
Total retrieved:  3  documents.
Retrieving data ...
Creating collection ...
Collection created!
Total retrieved:  3  documents.
Retrieving data ...
Creating collection ...
Collection created!
Total retrieved:  3  documents.
Retrieving data ...

MongoDB 日志:

2017-08-03T11:24:53.600+0300 I NETWORK  [initandlisten] waiting for connections on port 27017
2017-08-03T11:25:38.785+0300 I NETWORK  [initandlisten] connection accepted from 127.0.0.1:54591 #1 (1 connection now open)
2017-08-03T11:25:41.952+0300 I NETWORK  [initandlisten] connection accepted from 127.0.0.1:54592 #2 (2 connections now open)
2017-08-03T11:25:45.260+0300 I NETWORK  [initandlisten] connection accepted from 127.0.0.1:54593 #3 (3 connections now open)
2017-08-03T11:26:19.327+0300 I NETWORK  [initandlisten] connection accepted from 127.0.0.1:54594 #4 (4 connections now open)
2017-08-03T11:26:38.797+0300 I NETWORK  [initandlisten] connection accepted from 127.0.0.1:54595 #5 (5 connections now open)
2017-08-03T11:26:41.964+0300 I NETWORK  [initandlisten] connection accepted from 127.0.0.1:54596 #6 (6 connections now open)
2017-08-03T11:26:45.269+0300 I NETWORK  [initandlisten] connection accepted from 127.0.0.1:54597 #7 (7 connections now open)
2017-08-03T11:27:19.338+0300 I NETWORK  [initandlisten] connection accepted from 127.0.0.1:54599 #8 (8 connections now open)
2017-08-03T11:38:37.106+0300 I NETWORK  [initandlisten] connection accepted from 127.0.0.1:54836 #9 (9 connections now open)

我在这里做错了什么? Mongo 中的连接数达到数千,最终将其杀死......

最佳答案

每次复制 session 时,都应该将其关闭。

重写您的 GetCollectionGetAllRows,使用一个函数,例如:

func FetchData(session mgo.Session, queueName string) ([]Data, error) {
  fmt.Println("Creating collection ...")
  sess := session.Copy()
  collection := sess.DB(dbName).C(queueName)
  fmt.Println("Collection created!")

  defer  sess.Close() 

   var results []Data

   err := collection.Find(nil).All(&results)
   if err != nil {
       panic(err)
       return nil, err
   }
   return results, nil
}

注意线

 defer  sess.Close() 

关于mongodb - GoLang MongoDB 连接泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45479236/

有关mongodb - GoLang MongoDB 连接泄漏的更多相关文章

  1. ruby-on-rails - Ruby net/ldap 模块中的内存泄漏 - 2

    作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代

  2. ruby - 续集在添加关联时访问many_to_many连接表 - 2

    我正在使用Sequel构建一个愿望list系统。我有一个wishlists和itemstable和一个items_wishlists连接表(该名称是续集选择的名称)。items_wishlists表还有一个用于facebookid的额外列(因此我可以存储opengraph操作),这是一个NOTNULL列。我还有Wishlist和Item具有续集many_to_many关联的模型已建立。Wishlist类也有:selectmany_to_many关联的选项设置为select:[:items.*,:items_wishlists__facebook_action_id].有没有一种方法可以

  3. ruby - 无法在 60 秒内获得稳定的 Firefox 连接 (127.0.0.1 :7055) - 2

    我使用的是Firefox版本36.0.1和Selenium-Webdrivergem版本2.45.0。我能够创建Firefox实例,但无法使用脚本继续进行进一步的操作无法在60秒内获得稳定的Firefox连接(127.0.0.1:7055)错误。有人能帮帮我吗? 最佳答案 我遇到了同样的问题。降级到firefoxv33后一切正常。您可以找到旧版本here 关于ruby-无法在60秒内获得稳定的Firefox连接(127.0.0.1:7055),我们在StackOverflow上找到一个类

  4. ruby - 我的 Ruby IRC 机器人没有连接到 IRC 服务器。我究竟做错了什么? - 2

    require"socket"server="irc.rizon.net"port="6667"nick="RubyIRCBot"channel="#0x40"s=TCPSocket.open(server,port)s.print("USERTesting",0)s.print("NICK#{nick}",0)s.print("JOIN#{channel}",0)这个IRC机器人没有连接到IRC服务器,我做错了什么? 最佳答案 失败并显示此消息::irc.shakeababy.net461*USER:Notenoughparame

  5. 键删除后 ruby​​ 哈希内存泄漏 - 2

    你好,我无法成功如何在散列中删除key后释放内存。当我从哈希中删除键时,内存不会释放,也不会在手动调用GC.start后释放。当从Hash中删除键并且这些对象在某处泄漏时,这是预期的行为还是GC不释放内存?如何在Ruby中删除Hash中的键并在内存中取消分配它?例子:irb(main):001:0>`ps-orss=-p#{Process.pid}`.to_i=>4748irb(main):002:0>a={}=>{}irb(main):003:0>1000000.times{|i|a[i]="test#{i}"}=>1000000irb(main):004:0>`ps-orss=-p

  6. ruby-on-rails - 连接字符串时如何在 <%=%> block 内输出 html_safe? - 2

    考虑一下:现在这些情况:#output:http://domain.com/?foo=1&bar=2#output:http://domain.com/?foo=1&bar=2#output:http://domain.com/?foo=1&bar=2#output:http://domain.com/?foo=1&bar=2我需要用其他字符串输出URL。我如何保证&符号不会被转义?由于我无法控制的原因,我无法发送&。求助!把我的头发拉到这里:\编辑:为了澄清,我实际上有一个像这样的数组:@images=[{:id=>"fooid",:url=>"http://

  7. ruby - Faye WebSocket,关闭处理程序被触发后重新连接到套接字 - 2

    我有一个super简单的脚本,它几乎包含了FayeWebSocketGitHub页面上用于处理关闭连接的内容:ws=Faye::WebSocket::Client.new(url,nil,:headers=>headers)ws.on:opendo|event|p[:open]#sendpingcommand#sendtestcommand#ws.send({command:'test'}.to_json)endws.on:messagedo|event|#hereistheentrypointfordatacomingfromtheserver.pJSON.parse(event.d

  8. ruby-on-rails - 什么会导致与 APNS 的连接间歇性断开连接? - 2

    我有一个ruby​​脚本可以打开与Apple推送服务器的连接并发送所有待处理的通知。我看不出任何原因,但当Apple断开我的脚本时,我遇到了管道损坏错误。我已经编写了我的脚本来适应这种情况,但我宁愿只是找出它发生的原因,这样我就可以在第一时间避免它。它不会始终根据特定通知断开连接。它不会以特定的字节传输大小断开连接。一切似乎都是零星的。您可以在单个连接上发送的数据传输或有效负载计数是否有某些限制?看到人们的解决方案始终保持一个连接打开,我认为这不是问题所在。我看到连接在3次通知后断开,我看到它在14次通知后断开。我从未见过它能超过14点。有没有人遇到过这种类型的问题?如何处理?

  9. ruby - 如何断开现有的 ruby​​ 续集与数据库的连接? - 2

    我的意思是之前建立的那个DB=Sequel.sqlite('my_blog.db')或DB=Sequel.connect('postgres://user:password@localhost/my_db')或DB=Sequel.postgres('my_db',:user=>'user',:password=>'password',:host=>'localhost')等等。Sequel::Database类没有名为“disconnect”的公共(public)实例方法,尽管它有一个“connect”。也许有人已经遇到过这个问题。我将不胜感激。 最佳答案

  10. ruby-on-rails - 遗留数据库的 ActiveRecord 连接表 - 2

    我有一个遗留数据库,我正在努力让ActiveRecord使用它。我遇到了连接表的问题。我有以下内容:classTvShow然后我有一个名为tvshowlinkepisode的表,它有2个字段:idShow、idEpisode所以我有2个表和它们之间的连接(多对多关系),但是连接使用非标准外键。我的第一个想法是创建一个名为TvShowEpisodeLink的模型,但没有主键。我的想法是,由于外键是非标准的,我可以使用set_foreign_key并进行一些控制。最后,我想说一些类似TvShow.find(:last).episodes或Episode.find(:last).tv_sho

随机推荐