有很多教程是關(guān)于Go的sql.DB類型和如何使用它來執(zhí)行SQL數(shù)據(jù)庫查詢的。但大多數(shù)內(nèi)容都沒有講述 SetMaxOpenConns() , SetMaxIdleConns() 和 SetConnMaxLifetime()方法, 您可以使用它們來配置sql.DB的行為并改變其性能。
創(chuàng)新互聯(lián)建站是一家集網(wǎng)站建設(shè),額爾古納企業(yè)網(wǎng)站建設(shè),額爾古納品牌網(wǎng)站建設(shè),網(wǎng)站定制,額爾古納網(wǎng)站建設(shè)報(bào)價(jià),網(wǎng)絡(luò)營銷,網(wǎng)絡(luò)優(yōu)化,額爾古納網(wǎng)站推廣為一體的創(chuàng)新建站企業(yè),幫助傳統(tǒng)企業(yè)提升企業(yè)形象加強(qiáng)企業(yè)競(jìng)爭(zhēng)力??沙浞譂M足這一群體相比中小企業(yè)更為豐富、高端、多元的互聯(lián)網(wǎng)需求。同時(shí)我們時(shí)刻保持專業(yè)、時(shí)尚、前沿,時(shí)刻以成就客戶成長自我,堅(jiān)持不斷學(xué)習(xí)、思考、沉淀、凈化自己,讓我們?yōu)楦嗟钠髽I(yè)打造出實(shí)用型網(wǎng)站。
轉(zhuǎn)自:
整理:go語言中文文檔:
在本文我將詳細(xì)解釋這些設(shè)置的作用,并說明它們所能產(chǎn)生的(積極和消極)影響。
一個(gè)sql.DB對(duì)象就是一個(gè)數(shù)據(jù)庫連接池,它包含“正在用”和“空閑的”連接。一個(gè)正在用的連接指的是,你正用它來執(zhí)行數(shù)據(jù)庫任務(wù),例如執(zhí)行SQL語句或行查詢。當(dāng)任務(wù)完成連接就是空閑的。
當(dāng)您創(chuàng)建sql.DB執(zhí)行數(shù)據(jù)庫任務(wù)時(shí),它將首先檢查連接池中是否有可用的空閑連接。如果有可用的連接,那么Go將重用現(xiàn)有連接,并在執(zhí)行任務(wù)期間將其標(biāo)記為正在使用。如果池中沒有空閑連接,而您需要一個(gè)空閑連接,那么Go將創(chuàng)建一個(gè)新的連接。
默認(rèn)情況下,在同一時(shí)間打開連接的數(shù)量是沒有限制(包含使用中+空閑)。但你可以通過SetMaxOpenConns()方法實(shí)現(xiàn)自定義限制,如下所示:
在這個(gè)示例代碼中,連接池現(xiàn)在有5個(gè)并發(fā)打開的連接數(shù)。如果所有5個(gè)連接都已經(jīng)被標(biāo)記為正在使用,并且需要另一個(gè)新的連接,那么應(yīng)用程序?qū)⒈黄鹊却?,直?個(gè)連接中的一個(gè)被釋放并變?yōu)榭臻e。
為了說明更改MaxOpenConns的影響,我運(yùn)行了一個(gè)基準(zhǔn)測(cè)試,將最大打開連接數(shù)設(shè)置為1、2、5、10和無限?;鶞?zhǔn)測(cè)試在PostgreSQL數(shù)據(jù)庫上執(zhí)行并行的INSERT語句,您可以在這里找到代碼。測(cè)試結(jié)果:
對(duì)于這個(gè)基準(zhǔn)測(cè)試,我們可以看到,允許打開的連接越多,在數(shù)據(jù)庫上執(zhí)行INSERT操作所花費(fèi)的時(shí)間就越少(打開的連接數(shù)為1時(shí),執(zhí)行速度3129633ns/op,而無限連接:531030ns/op——大約快了6倍)。這是因?yàn)樵试S打開的連接越多,可以并發(fā)執(zhí)行的數(shù)據(jù)庫查詢就越多。
默認(rèn)情況下,sql.DB允許連接池中最多保留2個(gè)空閑連接。你可以通過SetMaxIdleConns()方法改變它,如下所示:
從理論上講,允許池中有更多的空閑連接將提高性能,因?yàn)檫@樣就不太可能從頭開始建立新連接——因此有助于提升數(shù)據(jù)庫性能。
讓我們來看看相同的基準(zhǔn)測(cè)試,最大空閑連接設(shè)置為none, 1,2,5和10:
當(dāng)MaxIdleConns設(shè)置為none時(shí),必須為每個(gè)INSERT從頭創(chuàng)建一個(gè)新的連接,我們可以從基準(zhǔn)測(cè)試中看到,平均運(yùn)行時(shí)和內(nèi)存使用量相對(duì)較高。
只允許保留和重用一個(gè)空閑連接對(duì)基準(zhǔn)測(cè)試影響特別明顯——它將平均運(yùn)行時(shí)間減少了大約8倍,內(nèi)存使用量減少了大約20倍。繼續(xù)增加空閑連接池的大小會(huì)使性能變得更好,盡管改進(jìn)并不明顯。
那么,您應(yīng)該維護(hù)一個(gè)大的空閑連接池嗎?答案取決于應(yīng)用程序。重要的是要意識(shí)到保持空閑連接是有代價(jià)的—它占用了可以用于應(yīng)用程序和數(shù)據(jù)庫的內(nèi)存。
還有一種可能是,如果一個(gè)連接空閑時(shí)間太長,那么它可能會(huì)變得不可用。例如,MySQL的wait_timeout設(shè)置將自動(dòng)關(guān)閉任何8小時(shí)(默認(rèn))內(nèi)未使用的連接。
當(dāng)發(fā)生這種情況時(shí),sql.DB會(huì)優(yōu)雅地處理它。壞連接將自動(dòng)重試兩次,然后放棄,此時(shí)Go將該連接從連接池中刪除,并創(chuàng)建一個(gè)新的連接。因此,將MaxIdleConns設(shè)置得太大可能會(huì)導(dǎo)致連接變得不可用,與空閑連接池更小(使用更頻繁的連接更少)相比,會(huì)占有更多的資源。所以,如果你很可能很快就會(huì)再次使用,你只需保持一個(gè)空閑的連接。
最后要指出的是,MaxIdleConns應(yīng)該總是小于或等于MaxOpenConns。Go強(qiáng)制執(zhí)行此操作,并在必要時(shí)自動(dòng)減少M(fèi)axIdleConns。
現(xiàn)在讓我們看看SetConnMaxLifetime()方法,它設(shè)置連接可重用的最大時(shí)間長度。如果您的SQL數(shù)據(jù)庫也實(shí)現(xiàn)了最大連接生命周期,或者—例如—您希望方便地在負(fù)載均衡器后交換數(shù)據(jù)庫,那么這將非常有用。
你可以這樣使用它:
在這個(gè)例子中,所有的連接都將在創(chuàng)建后1小時(shí)“過期”,并且在過期后無法重用。但注意:
從理論上講,ConnMaxLifetime越短,連接過期的頻率就越高——因此,需要從頭創(chuàng)建連接的頻率就越高。為了說明這一點(diǎn),我運(yùn)行了將ConnMaxLifetime設(shè)置為100ms、200ms、500ms、1000ms和無限(永遠(yuǎn)重用)的基準(zhǔn)測(cè)試,默認(rèn)設(shè)置為無限打開連接和2個(gè)空閑連接。這些時(shí)間段顯然比您在大多數(shù)應(yīng)用程序中使用的時(shí)間要短得多,但它們有助于很好地說明行為。
在這些特定的基準(zhǔn)測(cè)試中,我們可以看到,與無限生存期相比,在100ms生存期時(shí)內(nèi)存使用量增加了3倍以上,而且每個(gè)INSERT的平均運(yùn)行時(shí)也稍微長一些。
如果您在代碼中設(shè)置了ConnMaxLifetime,那么一定要記住連接將過期(隨后重新創(chuàng)建)的頻率。例如,如果您總共有100個(gè)連接,而ConnMaxLifetime為1分鐘,那么您的應(yīng)用程序可能每秒鐘殺死和重新創(chuàng)建1.67個(gè)連接(平均值)。您不希望這個(gè)頻率太大,最終會(huì)阻礙性能,而不是提高性能。
最后,如果不說明超過數(shù)據(jù)庫連接數(shù)量的硬限制將會(huì)發(fā)生什么,那么本文就不完整了。 為了說明這一點(diǎn),我將修改postgresql.conf文件,這樣總共只允許5個(gè)連接(默認(rèn)是100個(gè))…
然后在無限連接的情況下重新運(yùn)行基準(zhǔn)測(cè)試……
一旦達(dá)到5個(gè)連接的硬限制,數(shù)據(jù)庫驅(qū)動(dòng)程序(pq)立即返回一個(gè)太多客戶端連接的錯(cuò)誤消息,而無法完成INSERT。為了防止這個(gè)錯(cuò)誤,我們需要將sql.DB中打開連接的最大總數(shù)(正在使用的+空閑的)設(shè)置為低于5。像這樣:
現(xiàn)在,sql.DB在任何時(shí)候最多只能創(chuàng)建3個(gè)連接,基準(zhǔn)測(cè)試運(yùn)行時(shí)應(yīng)該不會(huì)出現(xiàn)任何錯(cuò)誤。但是這樣做需要注意:當(dāng)達(dá)到開放連接數(shù)限制,并且所有連接都在使用時(shí),應(yīng)用程序需要執(zhí)行的任何新的數(shù)據(jù)庫任務(wù)都將被迫等待,直到連接標(biāo)記為空閑。例如,在web應(yīng)用程序的上下文中,用戶的HTTP請(qǐng)求看起來會(huì)“掛起”,甚至在等待數(shù)據(jù)庫任務(wù)運(yùn)行時(shí)可能會(huì)超時(shí)。
為了減輕這種情況,你應(yīng)該始終在一個(gè)上下文中傳遞。在調(diào)用數(shù)據(jù)庫時(shí),啟用上下文的方法(如ExecContext()),使用固定的、快速的超時(shí)上下文對(duì)象。
總結(jié)
1、根據(jù)經(jīng)驗(yàn),應(yīng)該顯式設(shè)置MaxOpenConns值。這應(yīng)該小于數(shù)據(jù)庫和基礎(chǔ)設(shè)施對(duì)連接數(shù)量的硬性限制。
2、一般來說,更高的MaxOpenConns和MaxIdleConns值將帶來更好的性能。但你應(yīng)該注意到效果是遞減的,連接池空閑連接太多(連接沒有被重用,最終會(huì)變壞)實(shí)際上會(huì)導(dǎo)致性能下降。
3、為了降低上面第2點(diǎn)帶來的風(fēng)險(xiǎn),您可能需要設(shè)置一個(gè)相對(duì)較短的ConnMaxLifetime。但你也不希望它太短,導(dǎo)致連接被殺死或不必要地頻繁重建。
4、MaxIdleConns應(yīng)該總是小于或等于MaxOpenConns。
對(duì)于中小型web應(yīng)用程序,我通常使用以下設(shè)置作為起點(diǎn),然后根據(jù)實(shí)際吞吐量水平的負(fù)載測(cè)試結(jié)果進(jìn)行優(yōu)化。
Android中文版
api手冊(cè)地址:
Ant最新版
api手冊(cè)地址:
ASM字節(jié)碼操作
api手冊(cè)地址:
Axis2最新版
api手冊(cè)地址:
Bash腳本
api手冊(cè)地址:
Bootstrap 3
api手冊(cè)地址:
Bootstrap 4
api手冊(cè)地址:
C/C++
api手冊(cè)地址:
C3P0連接池
api手冊(cè)地址:
CentOS使用文檔
api手冊(cè)地址:
Commons-Beanutils
api手冊(cè)地址:
Commons-Fileupload
api手冊(cè)地址:
Commons-IO最新版
api手冊(cè)地址:
Commons-Lang最新版
api手冊(cè)地址:
Commons-Net最新版
api手冊(cè)地址:
CSS 3
api手冊(cè)地址:
DBCP連接池
api手冊(cè)地址:
Dom4j
api手冊(cè)地址:
dubbo中文文檔
api手冊(cè)地址:
EhCache
api手冊(cè)地址:
Freemarker
api手冊(cè)地址:
Go語言
api手冊(cè)地址:
Hadoop
api手冊(cè)地址:
Hibernate中文版
api手冊(cè)地址:
IKAnalyzer中文版
api手冊(cè)地址:
Java 10
api手冊(cè)地址:
Java 6
api手冊(cè)地址:
Java 7
api手冊(cè)地址:
Java 8中文版
api手冊(cè)地址:
jqGrid中文版
api手冊(cè)地址:
Jquery中文版
api手冊(cè)地址:
Json-lib
api手冊(cè)地址:
Junit4最新版
api手冊(cè)地址:
Kryo
api手冊(cè)地址:
Log4j最新版
api手冊(cè)地址:
Lucene
api手冊(cè)地址:
Maven
api手冊(cè)地址:
Windows MFC中文版
api手冊(cè)地址:
Mybatis
api手冊(cè)地址:
MySql中文版
api手冊(cè)地址:
Netty 3.6
api手冊(cè)地址:
Nginx中文版
api手冊(cè)地址:
OpenJPA最新版
api手冊(cè)地址:
PHP中文版
api手冊(cè)地址:
POI-apache
api手冊(cè)地址:
QuickServer
api手冊(cè)地址:
redis中文參考文檔
api手冊(cè)地址:
Ruby
api手冊(cè)地址:
Ruby-library
api手冊(cè)地址:
Ruby on Rails
api手冊(cè)地址:
Shiro
api手冊(cè)地址:
Spring最新版
api手冊(cè)地址:
Spring for Android
api手冊(cè)地址:
Spring Boot
api手冊(cè)地址:
Spring Cloud中文文檔
api手冊(cè)地址:
Spring Security
api手冊(cè)地址:
Spring中文版
api手冊(cè)地址:
Struts 2最新版
api手冊(cè)地址:
Taperstry
api手冊(cè)地址:
TensorFlow中文
api手冊(cè)地址:
Tomcat
api手冊(cè)地址:
Ubuntu
api手冊(cè)地址:
Velocity 1.7
api手冊(cè)地址:
VelocityTools2.0
api手冊(cè)地址:
Vue Router中文參考
api手冊(cè)地址:
vue.js中文文檔
api手冊(cè)地址:
XMLBeans
api手冊(cè)地址:
Yahoo UI中文版
api手冊(cè)地址:
Zend Framework中文版
api手冊(cè)地址:
Zookeeper
api手冊(cè)地址:
《Go程序設(shè)計(jì)語言中文版》百度網(wǎng)盤pdf最新全集下載:
鏈接:
?pwd=0cii 提取碼:0cii
簡(jiǎn)介:本書由《C程序設(shè)計(jì)語言》的作者Kernighan和谷歌公司Go團(tuán)隊(duì)主管Alan Donovan聯(lián)袂撰寫,是學(xué)習(xí)Go語言程序設(shè)計(jì)的指南。本書共13章,主要內(nèi)容包括:Go的基礎(chǔ)知識(shí)、基本結(jié)構(gòu)、
基本數(shù)據(jù)類型、復(fù)合數(shù)據(jù)類型、函數(shù)、方法、接口、goroutine、通道、共享變量的并發(fā)性、包、go工具、測(cè)試、反射等。
本書適合作為計(jì)算機(jī)相關(guān)專業(yè)的教材,也可供Go語言愛好者閱讀?