我认为在Golang中管理数据库连接池时遇到严重问题。我使用Gorilla网络工具包构建了RESTful
API,当只有很少的请求被发送到服务器时,该工具非常有用。但是现在我开始使用loader.io网站执行负载测试。对于冗长的帖子,我深表歉意,但我想为您提供完整的介绍。
在继续之前,这里是运行API和MySQL的服务器上的一些信息:专用主机Linux 8GB RAM Go版本1.1.1使用go-sql-driver
MySQL 5.1的数据库连接
使用loader.io,我可以每15秒发送1000个GET请求,而不会出现问题。但是,当我发送1000个POST请求/
15秒时,我收到很多错误,所有错误都是错误1040,数据库连接过多。许多人在线上报告了类似问题。请注意,目前我仅对一个特定的POST请求进行测试。对于此发布请求,我确保了以下内容(许多在线其他人也建议这样做)
我确保我没有使用短暂的函数打开和关闭* sql.DB。因此,正如您在下面的代码中看到的那样,我只为连接池创建了全局变量,尽管我愿意在这里提出建议,因为我不喜欢使用全局变量。
我确保尽可能使用db.Exec,并且在预期结果时仅使用db.Query和db.QueryRow。
由于上述方法无法解决我的问题,因此我尝试设置db.SetMaxIdleConns(1000),该问题解决了1000次POST请求/
15秒的问题。意味着不再有1040错误。然后,我将负载增加到2000个POST请求/
15秒,然后再次开始出现错误1040。我试图增加db.SetMaxIdleConns()中的值,但这没有任何区别。
在这里,我通过运行SHOW STATUS WHERE variable_name
=’Threads_connected’
从MySQL数据库获得有关连接数量的一些连接统计信息;
对于1000个POST请求/ 15秒:观察到的#threads_connected〜= 100对于2000个POST请求/
15秒:观察到的#threads_connected〜= 600
我还在my.cnf中增加了MySQL的最大连接数,但这没什么不同。你有什么建议?代码看起来不错吗?如果是,则可能是连接受到限制。
您将在下面找到代码的简化版本。
var db *sql.DB
func main() {
db = DbConnect()
db.SetMaxIdleConns(1000)
http.Handle("/", r)
err := http.ListenAndServe(fmt.Sprintf("%s:%s", API_HOST, API_PORT), nil)
if err != nil {
fmt.Println(err)
}
}
func DbConnect() *sql.DB {
db, err := sql.Open("mysql", connectionString)
if err != nil {
fmt.Printf("Connection error: %s\n", err.Error())
return nil
}
return db
}
func PostBounce(w http.ResponseWriter, r *http.Request) {
userId, err := AuthRequest(r)
//error checking
//ready requesy body and use json.Unmarshal
bounceId, err := CreateBounce(userId, b)
//return HTTP status code here
}
func AuthRequest(r *http.Request) (id int, err error) {
//parse header and get username and password
query := "SELECT Id FROM Users WHERE Username=? AND Password=PASSWORD(?)"
err = db.QueryRow(query, username, password).Scan(&id)
//error checking and return
}
func CreateBounce(userId int, bounce NewBounce) (bounceId int64, err error) {
//initialize some variables
query := "INSERT INTO Bounces (.....) VALUES (?, ?, ?, ?, ?, ?, ?, ?)"
result, err := db.Exec(query, ......)
//error checking
bounceId,_ = result.LastInsertId()
//return
}
Go database/sql
不会阻止您创建与数据库的无限数量的连接。如果池中有一个空闲连接,则将使用该连接,否则将创建一个新连接。
因此,在负载下,您的请求处理程序sql.DB可能找不到任何空闲连接,因此在需要时会创建一个新连接。这有点麻烦-尽可能重用空闲连接,并在需要时创建新连接-
最终达到Db的最大连接数。而且,不幸的是,在Go
1.1中,没有一种简便的方法(例如SetMaxOpenConns)来限制打开的连接。
升级到更高版本的Golang。在Go
1.2+中,您将获得SetMaxOpenConns。并查看MySql文档以开始设置,然后进行调整。
db.SetMaxOpenConns(100) //tune this
如果必须使用Go 1.1,则需要确保您的代码一次*sql.DB
仅可被N个客户端使用。
我正在尝试使用Jeter针对SQLServer 2008 R2数据库设置基本负载测试。但是,当仅使用一个用户运行测试时,我收到错误。 响应消息:com。微软sqlserver。jdbc。SQLServerException:用户XXX登录失败。ClientConnectionId:。 这是我的JDBC连接配置数据库URL: jdbc: sqlserver://Serverame: 1433; Da
我正在使用Heroku,并创建了一个新的应用程序和一个Postgres空数据库设置。 我已经安装了Heroku工具带,可以登录到Heroku并成功运行以下命令: 我在这里查看activerecord选项 但是,我运气不太好。 任何Heroku/Postgres大师能帮我指明正确的方向吗?数据库为空。作为第一步,我所要做的就是成功地连接到数据库。 Ruby文件:
我曾想过简单地对数据库运行一个小命令并捕获任何异常,然而,如果出现问题(例如app.config丢失或数据库服务器关闭),应用程序将花费大量时间运行此代码,然后抛出异常(大约1分钟)。我想这是由于连接超时等,但我已经摆弄了这样的属性没有任何作用。 有没有人能提供任何关于去哪里的建议?
本文向大家介绍Yii 连接、修改 MySQL 数据库及phpunit 测试连接,包括了Yii 连接、修改 MySQL 数据库及phpunit 测试连接的使用技巧和注意事项,需要的朋友参考一下 >>>database<<< 1. 修改 protected/config/main.php 去掉mysql数据库连接方式的注释,并且修改用户名,密码以及连接的数据库。 2. 新建 protected/tes
用Python来编写网站,必须要能够通过python操作数据库,所谓操作数据库,就是通过python实现对数据的连接,以及对记录、字段的各种操作。上一讲提到的那种操作方式,是看官直接通过交互模式来操作数据库。 安装python-MySQLdb 要想通过python来操作数据库,还需要在已经安装了mysql的基础上安装一个称之为mysqldb的库,它是一个接口程序,python通过它对mysql数据
是否可以在没有数据库连接的情况下运行我的测试?如果是,我做错了什么/错过了什么?