我认为我的Go服务器正在影响我的Mongo服务器。

huangapple go评论100阅读模式
英文:

I think my Go server is killing my Mongo servers

问题

长话短说,我在三个AWS区域有很多服务器。为了减少服务器数量,我将这些服务器从Node.js重写为Go语言。令我惊喜的是,一个Go服务器可以处理10个Node服务器的工作量,而且CPU利用率更低,ELB延迟更小。这太棒了,哈哈。然而,我觉得它们可能太快了,哈哈。我们有一个(是的,我知道很糟糕)用于记录数据的单个MongoDB服务器。每个请求进来都以特定的方式记录并发送到这个服务器。自从添加了2个Go服务器后,MongoDB服务器就开始崩溃。

TRACEBACK

2016-11-09T03:06:41.240-0500 I JOURNAL  [journal writer] warning couldn't write to / rename file /data/data/db/journal/prealloc.2: Couldn't open directory '/data/data/db/journal' for flushing: errno:24 Too many open files
2016-11-09T03:06:41.240-0500 I JOURNAL  [journal writer] warning exception opening journal file couldn't open file /data/data/db/journal/j._213 for writing errno:9 Bad file descriptor
2016-11-09T03:06:41.240-0500 I JOURNAL  [journal writer] error exception in dur::journal couldn't open file /data/data/db/journal/j._213 for writing errno:9 Bad file descriptor
2016-11-09T03:06:41.242-0500 F JOURNAL  [journal writer] dbexception in journalWriterThread causing immediate shutdown: 13516 couldn't open file /data/data/db/journal/j._213 for writing errno:9 Bad file descriptor
2016-11-09T03:06:41.242-0500 I -        [journal writer] Invariant failure false src/mongo/db/storage/mmap_v1/dur_journal_writer.cpp 258
2016-11-09T03:06:41.246-0500 I JOURNAL  [durability] warning couldn't write to / rename file /data/data/db/journal/prealloc.2: couldn't open file /data/data/db/journal/prealloc.2 for writing errno:9 Bad file descriptor
2016-11-09T03:06:41.246-0500 F JOURNAL  [durability] dbexception in durThread causing immediate shutdown: 13516 couldn't open file /data/data/db/journal/j._213 for writing errno:9 Bad file descriptor
2016-11-09T03:06:41.246-0500 I -        [durability] Invariant failure false src/mongo/db/storage/mmap_v1/dur.cpp 862
2016-11-09T03:06:41.246-0500 I CONTROL  [journal writer]
 0xf51949 0xef1671 0xed6192 0xd17613 0xf9f9b4 0x7fd09697d184 0x7fd09544337d
----- BEGIN BACKTRACE -----
{"backtrace":[{"b":"400000","o":"B51949"},{"b":"400000","o":"AF1671"},{"b":"400000","o":"AD6192"},{"b":"400000","o":"917613"},{"b":"400000","o":"B9F9B4"},{"b":"7FD096975000","o":"8184"},{"b":"7FD095349000","o":"FA37D"}],"processInfo":{ "mongodbVersion" : "3.0.3", "gitVersion" : "b40106b36eecd1b4407eb1ad1af6bc60593c6105", "uname" : { "sysname" : "Linux", "release" : "3.13.0-54-generic", "version" : "#91-Ubuntu SMP Tue May 26 19:15:08 UTC 2015", "machine" : "x86_64" }, "somap" : [ { "elfType" : 2, "b" : "400000", "buildId" : "F56F80CB96B4DBFC070BEB0ADAC7D6B274BFC6B1" }, { "b" : "7FFF14FD0000", "elfType" : 3, "buildId" : "1C0D0A18FF043EED9EE11DB5E5E90A3F74729341" }, { "b" : "7FD096975000", "path" : "/lib/x86_64-linux-gnu/libpthread.so.0", "elfType" : 3, "buildId" : "31E9F21AE8C10396171F1E13DA15780986FA696C" }, { "b" : "7FD096716000", "path" : "/lib/x86_64-linux-gnu/libssl.so.1.0.0", "elfType" : 3, "buildId" : "74864DB9D5F69D39A67E4755012FB6573C469B3D" }, { "b" : "7FD09633A000", "path" : "/lib/x86_64-linux-gnu/libcrypto.so.1.0.0", "elfType" : 3, "buildId" : "AAE7CFF8351B730830BDBCE0DCABBE06574B7144" }, { "b" : "7FD096132000", "path" : "/lib/x86_64-linux-gnu/librt.so.1", "elfType" : 3, "buildId" : "E2A6DD5048A0A051FD61043BDB69D8CC68192AB7" }, { "b" : "7FD095F2E000", "path" : "/lib/x86_64-linux-gnu/libdl.so.2", "elfType" : 3, "buildId" : "DA9B8C234D0FE9FD8CAAC8970A7EC1B6C8F6623F" }, { "b" : "7FD095C2A000", "path" : "/usr/lib/x86_64-linux-gnu/libstdc++.so.6", "elfType" : 3, "buildId" : "76190E922AF7457D078F75C9B15FA184E83EB506" }, { "b" : "7FD095924000", "path" : "/lib/x86_64-linux-gnu/libm.so.6", "elfType" : 3, "buildId" : "D144258E614900B255A31F3FD2283A878670D5BC" }, { "b" : "7FD09570E000", "path" : "/lib/x86_64-linux-gnu/libgcc_s.so.1", "elfType" : 3, "buildId" : "36311B4457710AE5578C4BF00791DED7359DBB92" }, { "b" : "7FD095349000", "path" : "/lib/x86_64-linux-gnu/libc.so.6", "elfType" : 3, "buildId" : "CF699A15CAAE64F50311FC4655B86DC39A479789" }, { "b" : "7FD096B93000", "path" : "/lib64/ld-linux-x86-64.so.2", "elfType" : 3, "buildId" : "D0F537904076D73F29E4A37341F8A449E2EF6CD0" } ] }}
 mongod(_ZN5mongo15printStackTraceERSo+0x29) [0xf51949]
 mongod(_ZN5mongo10logContextEPKc+0xE1) [0xef1671]
 mongod(_ZN5mongo15invariantFailedEPKcS1_j+0xB2) [0xed6192]
 mongod(_ZN5mongo3dur13JournalWriter20_journalWriterThreadEv+0x953) [0xd17613]
 mongod(+0xB9F9B4) [0xf9f9b4]
 libpthread.so.0(+0x8184) [0x7fd09697d184]
 libc.so.6(clone+0x6D) [0x7fd09544337d]

为了解决这个问题,我增加了该机器上的ulimit值。然而,我认为也可以从程序的角度进行一些处理。

这是我的mongo包

package mongo

import (
	"time"

	"gopkg.in/mgo.v2"
)

var (
	// TagDB ...
	TagDB DataStore
	// LogDB ...
	LogDB DataStore
)

func init() {
	TagDB.ConnectToTagserver()
	LogDB.ConnectToLogServer()
}

// DataStore 包含指向mgo会话的指针
type DataStore struct {
	Session *mgo.Session
}

// ConnectToTagserver 是一个连接到tagserver数据库的辅助方法
func (ds *DataStore) ConnectToTagserver() {
	mongoDBDialInfo := &mgo.DialInfo{
		Addrs:    []string{"some_IP"},
		Timeout:  60 * time.Second,
		Database: "tagserver",
	}
	sess, err := mgo.DialWithInfo(mongoDBDialInfo)
	if err != nil {
		panic(err)
	}
	sess.SetMode(mgo.Monotonic, true)
	TagDB.Session = sess
}

// ConnectToLogServer 是一个连接到日志服务器的辅助方法
func (ds *DataStore) ConnectToLogServer() {
	mongoDBDialInfo := &mgo.DialInfo{
		Addrs:    []string{"some_IP"},
		Timeout:  60 * time.Second,
		Database: "nginx_logs",
	}
	sess, err := mgo.DialWithInfo(mongoDBDialInfo)
	if err != nil {
		println(1)
		panic(err)
	}
	sess.SetMode(mgo.Monotonic, true)
	LogDB.Session = sess
}

// Close 是一个确保会话正确终止的辅助方法
func (ds *DataStore) Close() {
	ds.Session.Close()
}

这是使用该包的文件

package models

import (
	"errors"
	"fmt"
	"strconv"
	"time"

	"gopkg.in/mgo.v2/bson"

	"./mongo"
)

// RawRequests ...
type RawRequests struct {
	TagServer   string            `json:"tag_server"`
	Server      string            `json:"server"`
	Slug        string            `json:"slug"`
	Zone        string            `json:"zone"`
	Size        string            `json:"size"`
	Network     string            `json:"network"`
	TagHash     string            `json:"tag_hash"`
	Extra       string            `json:"extra"`
	Logged      time.Time         `json:"logged"`
	Date        string            `json:"date"`
	Hour        int               `json:"hour"`
	QueryParams map[string]string `json:"query_params"`
}

// RawTagRequests ...
type RawTagRequests struct {
	TagServer   string            `json:"tag_server"`
	Server      string            `json:"server"`
	Slug        string            `json:"slug"`
	Zone        string            `json:"zone"`
	Size        string            `json:"size"`
	Network     string            `json:"network"`
	TagHash     string            `json:"tag_hash"`
	Extra       string            `json:"extra"`
	Logged      time.Time         `json:"logged"`
	Date        string            `json:"date"`
	Hour        int               `json:"hour"`
	QueryParams map[string]string `json:"query_params"`
	ChainNext   string            `json:"chain_next"`
}

// LogRequest ...
func LogRequest(tagServer string, server string, slug string, zone string, size string, network string, extra string, tagHash string, queryParams map[string]string) error {
	dbsession := mongo.LogDB.Session.Copy()
	defer dbsession.Close()
	logCollection := dbsession.DB("nginx_logs").C("raw_requests")
	d := time.Now()
	hour, _, _ := d.Clock()
	year, month, day, _ := formatDate(d.Year(), int(d.Month()), d.Day())
	date := fmt.Sprintf("%s-%s-%s", year, month, day)
	return logCollection.Insert(bson.M{"tag_server": tagServer, "server": server, "slug": slug, "zone": zone, "size": size, "network": network, "tag_hash": tagHash, "extra": extra, "logged": time.Now(), "date": date, "hour": hour, "query_params": queryParams})
}

// LogTagRequests ...
func LogTagRequests(tagServer string, server string, slug string, zone string, size string, network string, extra string, tagHash string, queryParams map[string]string, chainHash string) error {
	dbsession := mongo.LogDB.Session.Copy()
	defer dbsession.Close()
	logCollection := dbsession.DB("nginx_logs").C("raw_tag_requests")
	d := time.Now()
	hour, _, _ := d.Clock()
	year, month, day, _ := formatDate(d.Year(), int(d.Month()), d.Day())
	date := fmt.Sprintf("%s-%s-%s", year, month, day)
	return logCollection.Insert(bson.M{"tag_server": tagServer, "server": server, "slug": slug, "zone": zone, "size": size, "network": network, "tag_hash": tagHash, "extra": extra, "logged": time.Now(), "date": date, "hour": hour, "query_params": queryParams, "chain_hash": chainHash})
}

func formatDate(year int, month int, day int) (y string, m string, d string, err error) {
	var tmonth, tday, tyear string
	tyear = strconv.Itoa(year)
	// convert the month and year and replace with the correct number of digits
	if month < 10 {
		tmonth = "0" + strconv.Itoa(int(month))
	} else {
		tmonth = strconv.Itoa(int(month))
	}
	if day < 10 {
		tday = "0" + strconv.Itoa(int(day))
	} else {
		tday = strconv.Itoa(int(day))
	}
	if len(tmonth) == 2 && len(tday) == 2 && len(tyear) == 4 {
		return tyear, tmonth, tday, nil
	}
	return tyear, tmonth, tday, errors.New("One of the values passed in does not meet the time format requirement month-day-year --> 1991-01-15")
}

最后,在我的路由中,我只需调用go LogRequest(tagServer, host, site, channel, adSize, network, tagExtra, tagHash, queryParams)方法。

英文:

So long story short, I have many servers across 3 AWS regions. In an effort to reduce servers, which are written in Node, I've rewritten them in Go. To my delight and surprise 1 Go server can handle what 10 Node servers handle with lower CPU utilization and less ELB latency. This is AWESOME lol. However, I think maybe that they are too fast lol. We have a single (yes I know very bad) MongoDB server used to log data. Every request that comes in is logged in a particular way and sent to this server. Since adding just 2 Go servers that MongoDB server has started to crash.

TRACEBACK

2016-11-09T03:06:41.240-0500 I JOURNAL  [journal writer] warning couldn&#39;t write to / rename file /data/data/db/journal/prealloc.2: Couldn&#39;t open directory &#39;/data/data/db/journal&#39; for flushing: errno:24 Too many open files
2016-11-09T03:06:41.240-0500 I JOURNAL  [journal writer] warning exception opening journal file couldn&#39;t open file /data/data/db/journal/j._213 for writing errno:9 Bad file descriptor
2016-11-09T03:06:41.240-0500 I JOURNAL  [journal writer] error exception in dur::journal couldn&#39;t open file /data/data/db/journal/j._213 for writing errno:9 Bad file descriptor
2016-11-09T03:06:41.242-0500 F JOURNAL  [journal writer] dbexception in journalWriterThread causing immediate shutdown: 13516 couldn&#39;t open file /data/data/db/journal/j._213 for writing errno:9 Bad file descriptor
2016-11-09T03:06:41.242-0500 I -        [journal writer] Invariant failure false src/mongo/db/storage/mmap_v1/dur_journal_writer.cpp 258
2016-11-09T03:06:41.246-0500 I JOURNAL  [durability] warning couldn&#39;t write to / rename file /data/data/db/journal/prealloc.2: couldn&#39;t open file /data/data/db/journal/prealloc.2 for writing errno:9 Bad file descriptor
2016-11-09T03:06:41.246-0500 F JOURNAL  [durability] dbexception in durThread causing immediate shutdown: 13516 couldn&#39;t open file /data/data/db/journal/j._213 for writing errno:9 Bad file descriptor
2016-11-09T03:06:41.246-0500 I -        [durability] Invariant failure false src/mongo/db/storage/mmap_v1/dur.cpp 862
2016-11-09T03:06:41.246-0500 I CONTROL  [journal writer]
0xf51949 0xef1671 0xed6192 0xd17613 0xf9f9b4 0x7fd09697d184 0x7fd09544337d
----- BEGIN BACKTRACE -----
{&quot;backtrace&quot;:[{&quot;b&quot;:&quot;400000&quot;,&quot;o&quot;:&quot;B51949&quot;},{&quot;b&quot;:&quot;400000&quot;,&quot;o&quot;:&quot;AF1671&quot;},{&quot;b&quot;:&quot;400000&quot;,&quot;o&quot;:&quot;AD6192&quot;},{&quot;b&quot;:&quot;400000&quot;,&quot;o&quot;:&quot;917613&quot;},{&quot;b&quot;:&quot;400000&quot;,&quot;o&quot;:&quot;B9F9B4&quot;},{&quot;b&quot;:&quot;7FD096975000&quot;,&quot;o&quot;:&quot;8184&quot;},{&quot;b&quot;:&quot;7FD095349000&quot;,&quot;o&quot;:&quot;FA37D&quot;}],&quot;processInfo&quot;:{ &quot;mongodbVersion&quot; : &quot;3.0.3&quot;, &quot;gitVersion&quot; : &quot;b40106b36eecd1b4407eb1ad1af6bc60593c6105&quot;, &quot;uname&quot; : { &quot;sysname&quot; : &quot;Linux&quot;, &quot;release&quot; : &quot;3.13.0-54-generic&quot;, &quot;version&quot; : &quot;#91-Ubuntu SMP Tue May 26 19:15:08 UTC 2015&quot;, &quot;machine&quot; : &quot;x86_64&quot; }, &quot;somap&quot; : [ { &quot;elfType&quot; : 2, &quot;b&quot; : &quot;400000&quot;, &quot;buildId&quot; : &quot;F56F80CB96B4DBFC070BEB0ADAC7D6B274BFC6B1&quot; }, { &quot;b&quot; : &quot;7FFF14FD0000&quot;, &quot;elfType&quot; : 3, &quot;buildId&quot; : &quot;1C0D0A18FF043EED9EE11DB5E5E90A3F74729341&quot; }, { &quot;b&quot; : &quot;7FD096975000&quot;, &quot;path&quot; : &quot;/lib/x86_64-linux-gnu/libpthread.so.0&quot;, &quot;elfType&quot; : 3, &quot;buildId&quot; : &quot;31E9F21AE8C10396171F1E13DA15780986FA696C&quot; }, { &quot;b&quot; : &quot;7FD096716000&quot;, &quot;path&quot; : &quot;/lib/x86_64-linux-gnu/libssl.so.1.0.0&quot;, &quot;elfType&quot; : 3, &quot;buildId&quot; : &quot;74864DB9D5F69D39A67E4755012FB6573C469B3D&quot; }, { &quot;b&quot; : &quot;7FD09633A000&quot;, &quot;path&quot; : &quot;/lib/x86_64-linux-gnu/libcrypto.so.1.0.0&quot;, &quot;elfType&quot; : 3, &quot;buildId&quot; : &quot;AAE7CFF8351B730830BDBCE0DCABBE06574B7144&quot; }, { &quot;b&quot; : &quot;7FD096132000&quot;, &quot;path&quot; : &quot;/lib/x86_64-linux-gnu/librt.so.1&quot;, &quot;elfType&quot; : 3, &quot;buildId&quot; : &quot;E2A6DD5048A0A051FD61043BDB69D8CC68192AB7&quot; }, { &quot;b&quot; : &quot;7FD095F2E000&quot;, &quot;path&quot; : &quot;/lib/x86_64-linux-gnu/libdl.so.2&quot;, &quot;elfType&quot; : 3, &quot;buildId&quot; : &quot;DA9B8C234D0FE9FD8CAAC8970A7EC1B6C8F6623F&quot; }, { &quot;b&quot; : &quot;7FD095C2A000&quot;, &quot;path&quot; : &quot;/usr/lib/x86_64-linux-gnu/libstdc++.so.6&quot;, &quot;elfType&quot; : 3, &quot;buildId&quot; : &quot;76190E922AF7457D078F75C9B15FA184E83EB506&quot; }, { &quot;b&quot; : &quot;7FD095924000&quot;, &quot;path&quot; : &quot;/lib/x86_64-linux-gnu/libm.so.6&quot;, &quot;elfType&quot; : 3, &quot;buildId&quot; : &quot;D144258E614900B255A31F3FD2283A878670D5BC&quot; }, { &quot;b&quot; : &quot;7FD09570E000&quot;, &quot;path&quot; : &quot;/lib/x86_64-linux-gnu/libgcc_s.so.1&quot;, &quot;elfType&quot; : 3, &quot;buildId&quot; : &quot;36311B4457710AE5578C4BF00791DED7359DBB92&quot; }, { &quot;b&quot; : &quot;7FD095349000&quot;, &quot;path&quot; : &quot;/lib/x86_64-linux-gnu/libc.so.6&quot;, &quot;elfType&quot; : 3, &quot;buildId&quot; : &quot;CF699A15CAAE64F50311FC4655B86DC39A479789&quot; }, { &quot;b&quot; : &quot;7FD096B93000&quot;, &quot;path&quot; : &quot;/lib64/ld-linux-x86-64.so.2&quot;, &quot;elfType&quot; : 3, &quot;buildId&quot; : &quot;D0F537904076D73F29E4A37341F8A449E2EF6CD0&quot; } ] }}
mongod(_ZN5mongo15printStackTraceERSo+0x29) [0xf51949]
mongod(_ZN5mongo10logContextEPKc+0xE1) [0xef1671]
mongod(_ZN5mongo15invariantFailedEPKcS1_j+0xB2) [0xed6192]
mongod(_ZN5mongo3dur13JournalWriter20_journalWriterThreadEv+0x953) [0xd17613]
mongod(+0xB9F9B4) [0xf9f9b4]
libpthread.so.0(+0x8184) [0x7fd09697d184]
libc.so.6(clone+0x6D) [0x7fd09544337d]

In an efforts to fix this I increased the ulimit on that machine. However I think something can also be done from the programmic side.

Here is my mongo package

package mongo
import (
&quot;time&quot;
&quot;gopkg.in/mgo.v2&quot;
)
var (
// TagDB ...
TagDB DataStore
// LogDB ...
LogDB DataStore
)
func init() {
TagDB.ConnectToTagserver()
LogDB.ConnectToLogServer()
}
// DataStore containing a pointer to a mgo session
type DataStore struct {
Session *mgo.Session
}
// ConnectToTagserver is a helper method that connections to pubgears&#39; tagserver
// database
func (ds *DataStore) ConnectToTagserver() {
mongoDBDialInfo := &amp;mgo.DialInfo{
Addrs:    []string{&quot;some_IP&quot;},
Timeout:  60 * time.Second,
Database: &quot;tagserver&quot;,
}
sess, err := mgo.DialWithInfo(mongoDBDialInfo)
if err != nil {
panic(err)
}
sess.SetMode(mgo.Monotonic, true)
TagDB.Session = sess
}
// database SERVER IN QUESTION
func (ds *DataStore) ConnectToLogServer() {
mongoDBDialInfo := &amp;mgo.DialInfo{
Addrs:    []string{&quot;some_IP&quot;}, 
Timeout:  60 * time.Second,
Database: &quot;nginx_logs&quot;,
}
sess, err := mgo.DialWithInfo(mongoDBDialInfo)
if err != nil {
println(1)
panic(err)
}
sess.SetMode(mgo.Monotonic, true)
LogDB.Session = sess
}
// Close is a helper method that ensures the session is properly terminated
func (ds *DataStore) Close() {
ds.Session.Close()
}

Here is the file that used that package

package models
import (
&quot;errors&quot;
&quot;fmt&quot;
&quot;strconv&quot;
&quot;time&quot;
&quot;gopkg.in/mgo.v2/bson&quot;
&quot;./mongo&quot;
)
// RawRequests ...
type RawRequests struct {
TagServer   string            `json:&quot;tag_server&quot;`
Server      string            `json:&quot;server&quot;`
Slug        string            `json:&quot;slug&quot;`
Zone        string            `json:&quot;zone&quot;`
Size        string            `json:&quot;size&quot;`
Network     string            `json:&quot;network&quot;`
TagHash     string            `json:&quot;tag_hash&quot;`
Extra       string            `json:&quot;extra&quot;`
Logged      time.Time         `json:&quot;logged&quot;`
Date        string            `json:&quot;date&quot;`
Hour        int               `json:&quot;hour&quot;`
QueryParams map[string]string `json:&quot;query_params&quot;`
}
// RawTagRequests ...
type RawTagRequests struct {
TagServer   string            `json:&quot;tag_server&quot;`
Server      string            `json:&quot;server&quot;`
Slug        string            `json:&quot;slug&quot;`
Zone        string            `json:&quot;zone&quot;`
Size        string            `json:&quot;size&quot;`
Network     string            `json:&quot;network&quot;`
TagHash     string            `json:&quot;tag_hash&quot;`
Extra       string            `json:&quot;extra&quot;`
Logged      time.Time         `json:&quot;logged&quot;`
Date        string            `json:&quot;date&quot;`
Hour        int               `json:&quot;hour&quot;`
QueryParams map[string]string `json:&quot;query_params&quot;`
ChainNext   string            `json:&quot;chain_next&quot;`
}
// LogRequest ...
func LogRequest(tagServer string, server string, slug string, zone string, size string, network string, extra string, tagHash string, queryParams map[string]string) error {
dbsession := mongo.LogDB.Session.Copy()
defer dbsession.Close()
logCollection := dbsession.DB(&quot;nginx_logs&quot;).C(&quot;raw_requests&quot;)
d := time.Now()
hour, _, _ := d.Clock()
year, month, day, _ := formatDate(d.Year(), int(d.Month()), d.Day())
date := fmt.Sprintf(&quot;%s-%s-%s&quot;, year, month, day)
return logCollection.Insert(bson.M{&quot;tag_server&quot;: tagServer, &quot;server&quot;: server, &quot;slug&quot;: slug, &quot;zone&quot;: zone, &quot;size&quot;: size, &quot;network&quot;: network, &quot;tag_hash&quot;: tagHash, &quot;extra&quot;: extra, &quot;logged&quot;: time.Now(), &quot;date&quot;: date, &quot;hour&quot;: hour, &quot;query_params&quot;: queryParams})
}
// LogTagRequests ...
func LogTagRequests(tagServer string, server string, slug string, zone string, size string, network string, extra string, tagHash string, queryParams map[string]string, chainHash string) error {
dbsession := mongo.LogDB.Session.Copy()
defer dbsession.Close()
logCollection := dbsession.DB(&quot;nginx_logs&quot;).C(&quot;raw_tag_requests&quot;)
d := time.Now()
hour, _, _ := d.Clock()
year, month, day, _ := formatDate(d.Year(), int(d.Month()), d.Day())
date := fmt.Sprintf(&quot;%s-%s-%s&quot;, year, month, day)
return logCollection.Insert(bson.M{&quot;tag_server&quot;: tagServer, &quot;server&quot;: server, &quot;slug&quot;: slug, &quot;zone&quot;: zone, &quot;size&quot;: size, &quot;network&quot;: network, &quot;tag_hash&quot;: tagHash, &quot;extra&quot;: extra, &quot;logged&quot;: time.Now(), &quot;date&quot;: date, &quot;hour&quot;: hour, &quot;query_params&quot;: queryParams, &quot;chain_hash&quot;: chainHash})
}
func formatDate(year int, month int, day int) (y string, m string, d string, err error) {
var tmonth, tday, tyear string
tyear = strconv.Itoa(year)
// convert the month and year and replace with the correct number of digits
if month &lt; 10 {
tmonth = &quot;0&quot; + strconv.Itoa(int(month))
} else {
tmonth = strconv.Itoa(int(month))
}
if day &lt; 10 {
tday = &quot;0&quot; + strconv.Itoa(int(day))
} else {
tday = strconv.Itoa(int(day))
}
if len(tmonth) == 2 &amp;&amp; len(tday) == 2 &amp;&amp; len(tyear) == 4 {
return tyear, tmonth, tday, nil
}
return tyear, tmonth, tday, errors.New(&quot;One of the values passed in does not meet the time format requirement month-day-year --&gt; 1991-01-15&quot;)
}

Lastly within my route, I simply call my method go LogRequest(tagServer, host, site, channel, adSize, network, tagExtra, tagHash, queryParams)

答案1

得分: 1

  1. 在每个请求-响应周期中,您应该只使用一次copy。在每次调用models时使用它会导致消耗大量的套接字。每个模型调用都会打开一个套接字,并在退出例程时使用defer关闭它。尝试在同一个请求-响应周期内多次调用数据库时重用已复制的会话。

  2. 从日志和代码片段来看,除非在每个请求-响应周期中只调用一次模型例程来执行CRUD操作,否则需要注意第1点。

  3. copy使用一个新的套接字打开连接,保留父会话的身份验证凭据,而clone使用与父会话相同的套接字(在使用克隆会话时,父/子中的一个必须等待套接字,直到另一个完成为止)。因此,为了并行处理对服务器的多个请求,最好在每个请求处理程序中使用copy。(https://godoc.org/gopkg.in/mgo.v2#Session.Clone)

  4. 在增加机器上的ulimit之后,请确保立即反映出来- http://lzone.de/blog/Apply-changes-to-limits.conf-immediately

英文:
  1. You should use copy only once per request-response cycle. Using it in each call to models will result in consuming a lot of sockets. Each model call is opening a socket and closing it(using defer) while exiting the routine. Try to reuse a copied session across multiple calls to your db in the same request-response cycle.
  2. From the logs and the code snippet, it looks like that you should take care of 1 until unless in each request-response cycle you are calling your model routines to perform CRUD only once.
  3. Copy uses a new socket to open connection preserving the auth credentials from the parent session while clone uses the same socket as the parent session(while using the cloned session one of the parent/child will have to wait on the socket until the other one is done with it). Hence, to process multiple requests to your server in parallel its better to use copy per request handler.(https://godoc.org/gopkg.in/mgo.v2#Session.Clone)
  4. After increasing the ulimit on a machine do make sure it gets reflected immediately - http://lzone.de/blog/Apply-changes-to-limits.conf-immediately.

huangapple
  • 本文由 发表于 2016年11月10日 00:17:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/40511495.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定