新聞中心
本篇內(nèi)容主要講解“golang MySQL庫連接池有什么作用”,感興趣的朋友不妨來看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“golang mysql庫連接池有什么作用”吧!
網(wǎng)站建設(shè)公司,為您提供網(wǎng)站建設(shè),網(wǎng)站制作,網(wǎng)頁設(shè)計(jì)及定制網(wǎng)站建設(shè)服務(wù),專注于成都企業(yè)網(wǎng)站定制,高端網(wǎng)頁制作,對(duì)木托盤等多個(gè)行業(yè)擁有豐富的網(wǎng)站建設(shè)經(jīng)驗(yàn)的網(wǎng)站建設(shè)公司。專業(yè)網(wǎng)站設(shè)計(jì),網(wǎng)站優(yōu)化推廣哪家好,專業(yè)成都網(wǎng)站營銷優(yōu)化,H5建站,響應(yīng)式網(wǎng)站。
golang mysql庫連接池分析
0x1 背景
golang的協(xié)程是好用,但是有時(shí)候瓶頸并不在語言上,而是在后面的數(shù)據(jù)源上面,例如我們常見的mysql,redis等,當(dāng)一個(gè)后端服務(wù)很多請(qǐng)求的時(shí)候,語言是能hold得住,但是 mysql產(chǎn)生錯(cuò)誤,比如 too many connection, too many time_wait 等等這些,今天我們就分析一下怎么解決這種問題
0x2 代碼范例
請(qǐng)查看main.go, halokid (有幫忙的話請(qǐng)start或者follow一下哦,謝謝)
0x3 分析
只執(zhí)行ini函數(shù), 檢查mysql的進(jìn)程顯示為(原有的mysql是沒有進(jìn)程在處理的)
沒執(zhí)行前
mysql> show processlist; +----+-----------------+------------------+------+---------+------+------------------------+------------------+ | Id | User | Host | db | Command | Time | State | Info | +----+-----------------+------------------+------+---------+------+------------------------+------------------+ | 4 | event_scheduler | localhost | NULL | Daemon | 2304 | Waiting on empty queue | NULL | | 9 | root | 10.244.1.1:64000 | test | Sleep | 1315 | | NULL | | 10 | root | 10.244.1.1:64022 | test | Query | 0 | starting | show processlist | +----+-----------------+------------------+------+---------+------+------------------------+------------------+ 3 rows in set (0.01 sec)
執(zhí)行后
mysql> show processlist; +----+-----------------+------------------+------+---------+------+------------------------+------------------+ | Id | User | Host | db | Command | Time | State | Info | +----+-----------------+------------------+------+---------+------+------------------------+------------------+ | 4 | event_scheduler | localhost | NULL | Daemon | 2284 | Waiting on empty queue | NULL | | 9 | root | 10.244.1.1:64000 | test | Sleep | 1295 | | NULL | | 10 | root | 10.244.1.1:64022 | test | Query | 0 | starting | show processlist | | 13 | root | 10.244.1.1:52134 | test | Sleep | 20 | | NULL | +----+-----------------+------------------+------+---------+------+------------------------+------------------+ 4 rows in set (0.00 sec)
可見執(zhí)行 db.Ping() 之后, process多了一個(gè) Sleep 的連接,就是放了一個(gè)連接進(jìn) 連接池
運(yùn)行
db.SetMaxOpenConns(10) db.SetMaxIdleConns(5)
兩句之后, 連接池并沒有改變, 可見上面的邏輯是在 數(shù)據(jù)庫處理邏輯真實(shí)執(zhí)行的時(shí)候才生效的
執(zhí)行協(xié)程查詢
mysql> show processlist; +----+-----------------+------------------+------+---------+------+------------------------+------------------+ | Id | User | Host | db | Command | Time | State | Info | +----+-----------------+------------------+------+---------+------+------------------------+------------------+ | 4 | event_scheduler | localhost | NULL | Daemon | 4397 | Waiting on empty queue | NULL | | 9 | root | 10.244.1.1:64000 | test | Sleep | 3408 | | NULL | | 10 | root | 10.244.1.1:64022 | test | Query | 0 | starting | show processlist | | 19 | root | 10.244.1.1:54823 | test | Sleep | 952 | | NULL | | 20 | root | 10.244.1.1:54824 | test | Sleep | 1104 | | NULL | | 47 | root | 10.244.1.1:57906 | test | Sleep | 0 | | NULL | | 48 | root | 10.244.1.1:57909 | test | Sleep | 0 | | NULL | | 49 | root | 10.244.1.1:57912 | test | Sleep | 0 | | NULL | | 50 | root | 10.244.1.1:57907 | test | Sleep | 0 | | NULL | | 51 | root | 10.244.1.1:57908 | test | Sleep | 0 | | NULL | | 52 | root | 10.244.1.1:57913 | test | Sleep | 0 | | NULL | | 53 | root | 10.244.1.1:57911 | test | Sleep | 0 | | NULL | | 54 | root | 10.244.1.1:57910 | test | Sleep | 0 | | NULL | | 55 | root | 10.244.1.1:57915 | test | Sleep | 0 | | NULL | | 56 | root | 10.244.1.1:57914 | test | Sleep | 0 | | NULL | +----+-----------------+------------------+------+---------+------+------------------------+------------------+ 15 rows in set (0.00 sec)
執(zhí)行完在等待
mysql> show processlist; +----+-----------------+------------------+------+---------+------+------------------------+------------------+ | Id | User | Host | db | Command | Time | State | Info | +----+-----------------+------------------+------+---------+------+------------------------+------------------+ | 4 | event_scheduler | localhost | NULL | Daemon | 3931 | Waiting on empty queue | NULL | | 9 | root | 10.244.1.1:64000 | test | Sleep | 2942 | | NULL | | 10 | root | 10.244.1.1:64022 | test | Query | 0 | starting | show processlist | | 19 | root | 10.244.1.1:54823 | test | Sleep | 486 | | NULL | | 20 | root | 10.244.1.1:54824 | test | Sleep | 638 | | NULL | | 32 | root | 10.244.1.1:56588 | test | Sleep | 22 | | NULL | | 33 | root | 10.244.1.1:56591 | test | Sleep | 22 | | NULL | | 34 | root | 10.244.1.1:56589 | test | Sleep | 22 | | NULL | | 35 | root | 10.244.1.1:56590 | test | Sleep | 22 | | NULL | | 36 | root | 10.244.1.1:56592 | test | Sleep | 22 | | NULL | +----+-----------------+------------------+------+---------+------+------------------------+------------------+ 10 rows in set (0.00 sec)
協(xié)程執(zhí)行完之后
mysql> show processlist; +----+-----------------+------------------+------+---------+------+------------------------+------------------+ | Id | User | Host | db | Command | Time | State | Info | +----+-----------------+------------------+------+---------+------+------------------------+------------------+ | 4 | event_scheduler | localhost | NULL | Daemon | 3941 | Waiting on empty queue | NULL | | 9 | root | 10.244.1.1:64000 | test | Sleep | 2952 | | NULL | | 10 | root | 10.244.1.1:64022 | test | Query | 0 | starting | show processlist | | 19 | root | 10.244.1.1:54823 | test | Sleep | 496 | | NULL | | 20 | root | 10.244.1.1:54824 | test | Sleep | 648 | | NULL | +----+-----------------+------------------+------+---------+------+------------------------+------------------+ 5 rows in set (0.00 sec)
我們發(fā)現(xiàn)最大連接控制在了10個(gè), 執(zhí)行完之后還有5個(gè)連接在保持著
這里有一個(gè)很重要的問題,就是連接池的過期時(shí)間
0x4 深入分析 我們把 db.SetConnMaxLifetime(15 * time.Second), 連接池連接的生命周期設(shè)置為 15秒, 我們會(huì)發(fā)現(xiàn)15秒之后,連接池的連接都會(huì)斷掉
mysql> show processlist; +----+-----------------+------------------+------+---------+------+------------------------+------------------+ | Id | User | Host | db | Command | Time | State | Info | +----+-----------------+------------------+------+---------+------+------------------------+------------------+ | 4 | event_scheduler | localhost | NULL | Daemon | 4987 | Waiting on empty queue | NULL | | 9 | root | 10.244.1.1:64000 | test | Sleep | 3998 | | NULL | | 10 | root | 10.244.1.1:64022 | test | Query | 0 | starting | show processlist | | 19 | root | 10.244.1.1:54823 | test | Sleep | 1542 | | NULL | | 20 | root | 10.244.1.1:54824 | test | Sleep | 1694 | | NULL | +----+-----------------+------------------+------+---------+------+------------------------+------------------+ 5 rows in set (0.00 sec)
30秒之后再次查詢數(shù)據(jù)庫
time.Sleep(30 * time.Second) rows, err := db.Query("select name from users") fmt.Println("err -----", err) defer rows.Close() for rows.Next(){ var name string rows.Scan(&name) fmt.Println("name---", name) }
這個(gè)時(shí)候發(fā)現(xiàn)程序會(huì)重新發(fā)起新的db連接
總結(jié):
mysql服務(wù)端的連接生命周期
還有一種請(qǐng)況就是,我們的程序的連接池生命周期設(shè)置大于mysql服務(wù)器的生命周期設(shè)置, 這個(gè)時(shí)候就會(huì)有一種請(qǐng)況,假如我們重復(fù)用連接池的連接,會(huì)產(chǎn)生 連接錯(cuò)誤的問題,解決方法有兩種:
可以在程序里面設(shè)置生命周期時(shí)間小于mysql服務(wù)端的連接生命周期時(shí)間就可以了
增加程序的重連(keepalive)機(jī)制,就是定時(shí)發(fā)送一個(gè)連接包服務(wù)端 關(guān)于第2點(diǎn)我們我們以后可以再發(fā)散來說,一般如果允許的話,用第一種方式即可。
mysql> show variables like 'mysqlx_wait_timeout'; +---------------------+-------+ | Variable_name | Value | +---------------------+-------+ | mysqlx_wait_timeout | 28800 | +---------------------+-------+ 1 row in set (0.00 sec)
到此,相信大家對(duì)“golang mysql庫連接池有什么作用”有了更深的了解,不妨來實(shí)際操作一番吧!這里是創(chuàng)新互聯(lián)網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!
網(wǎng)站題目:golangmysql庫連接池有什么作用
轉(zhuǎn)載注明:http://www.ef60e0e.cn/article/iheipe.html