<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          面試官:為什么數(shù)據(jù)庫(kù)連接很消耗資源,資源都消耗在哪里?

          共 2843字,需瀏覽 6分鐘

           ·

          2022-07-01 01:52

          點(diǎn)擊關(guān)注公眾號(hào),Java干貨及時(shí)送達(dá)??

          來(lái)源:blog.csdn.net/lmy86263/article/details/76165714


          ?

          開(kāi)發(fā)應(yīng)用程序久了,總想刨根問(wèn)底,尤其對(duì)一些有公共答案的問(wèn)題。大家都能解釋?zhuān)亲犯康祝冀忉尣磺濉7彩嵌加袨槭裁矗矣脭?shù)字說(shuō)明問(wèn)題是最直觀的。

          ?

          本文主要想探究一下連接數(shù)據(jù)庫(kù)的細(xì)節(jié),尤其是在Web應(yīng)用中要使用數(shù)據(jù)庫(kù)來(lái)連接池,以免每次發(fā)送一次請(qǐng)求就重新建立一次連接。對(duì)于這個(gè)問(wèn)題,答案都是一致的,建立數(shù)據(jù)庫(kù)連接很耗時(shí),但是這個(gè)耗時(shí)是都多少呢,又是分別在哪些方面產(chǎn)生的耗時(shí)呢?

          本文以連接MySQL數(shù)據(jù)庫(kù)為例,因?yàn)?code style="font-size: 14px;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(40, 202, 113);">MySQL數(shù)據(jù)庫(kù)是開(kāi)源的,其通信協(xié)議是公開(kāi)的,所以我們能夠詳細(xì)分析建立連接的整個(gè)過(guò)程。

          ?

          在本文中,消耗資源的分析主要集中在網(wǎng)絡(luò)上,當(dāng)然,資源也包括內(nèi)存、CPU等計(jì)算資源,使用的編程語(yǔ)言是Java,但是不排除編程語(yǔ)言也會(huì)有一定的影響。

          ?

          首先先看一下連接數(shù)據(jù)庫(kù)的Java代碼,如下:

          Class.forName("com.mysql.jdbc.Driver");

          String name = "xttblog2";
          String password = "123456";
          String url = "jdbc:mysql://172.16.100.131:3306/xttblog2";
          Connection conn = DriverManager.getConnection(url, name, password);
          // 之后程序終止,連接被強(qiáng)制關(guān)閉

          然后通過(guò)「Wireshark」 分析整個(gè)連接的建立過(guò)程,如下:

          Wireshark抓包

          在上圖中顯示的連接過(guò)程中,可以看出MySQL的通信協(xié)議是基于TCP傳輸協(xié)議的,而且該協(xié)議是二進(jìn)制協(xié)議,不是類(lèi)似于HTTP的文本協(xié)議,其中建立連接的過(guò)程具體如下:

          • 第1步:建立TCP連接,通過(guò)三次握手實(shí)現(xiàn);
          • 第2步:服務(wù)器發(fā)送給客戶端「握手信息」 ,客戶端響應(yīng)該握手消息;
          • 第3步:客戶端「發(fā)送認(rèn)證包」 ,用于用戶驗(yàn)證,驗(yàn)證成功后,服務(wù)器返回OK響應(yīng),之后開(kāi)始執(zhí)行命令;

          用戶驗(yàn)證成功之后,會(huì)進(jìn)行一些連接變量的設(shè)置,比如字符集、是否自動(dòng)提交事務(wù)等,其間會(huì)有多次數(shù)據(jù)的交互。完成了這些步驟后,才會(huì)執(zhí)行真正的數(shù)據(jù)查詢和更新等操作。

          在本文的測(cè)試中,只用了5行代碼來(lái)建立連接,但是并沒(méi)有通過(guò)該連接去執(zhí)行任何操作,所以在程序執(zhí)行完畢之后,連接不是通過(guò)Connection.close()關(guān)閉的,而是由于程序執(zhí)行完畢,導(dǎo)致進(jìn)程終止,造成與數(shù)據(jù)庫(kù)的連接異常關(guān)閉,所以最后會(huì)出現(xiàn)TCPRST報(bào)文。在這個(gè)最簡(jiǎn)單的代碼中,沒(méi)有設(shè)置任何額外的連接屬性,所以在設(shè)置屬性上占用的時(shí)間可以認(rèn)為是最少的(其實(shí),雖然我們沒(méi)有設(shè)置任何屬性,但是驅(qū)動(dòng)仍然設(shè)置了字符集、事務(wù)自動(dòng)提交等,這取決于具體的驅(qū)動(dòng)實(shí)現(xiàn)),所以整個(gè)連接所使用的時(shí)間可以認(rèn)為是最少的。但從統(tǒng)計(jì)信息中可以看出,在不包括最后TCPRST 報(bào)文時(shí)(因?yàn)樵搱?bào)文不需要服務(wù)器返回任何響應(yīng)),但是其中仍需在客戶端和服務(wù)器之間進(jìn)行往返「7」 次,「也就是說(shuō)完成一次連接,可以認(rèn)為,數(shù)據(jù)在客戶端和服務(wù)器之間需要至少往返7次」 ,從時(shí)間上來(lái)看,從開(kāi)始TCP的三次握手,到最終連接強(qiáng)制斷開(kāi)為止(不包括最后的RST報(bào)文),總共花費(fèi)了:

          10.416042 - 10.190799 = 0.225243s = **225.243ms**!!!

          這意味著,建立一次數(shù)據(jù)庫(kù)連接需要225ms,而這還是還可以認(rèn)為是最少的,當(dāng)然「花費(fèi)的時(shí)間可能受到網(wǎng)絡(luò)狀況、數(shù)據(jù)庫(kù)服務(wù)器性能以及應(yīng)用代碼是否高效的影響」 ,但是這里只是一個(gè)最簡(jiǎn)單的例子,已經(jīng)足夠說(shuō)明問(wèn)題了!

          由于上面是程序異常終止了,但是在正常的應(yīng)用程序中,連接的關(guān)閉一般都是通過(guò)Connection.close()完成的,代碼如下:

          Class.forName("com.mysql.jdbc.Driver");

          String name = "shine_user";
          String password = "123";
          String url = "jdbc:mysql://172.16.100.131:3306/clever_mg_test";
          Connection conn = DriverManager.getConnection(url, name, password);
          conn.close();

          這樣的話,情況發(fā)生了變化,主要體現(xiàn)在與數(shù)據(jù)庫(kù)連接的斷開(kāi),如下圖:

          網(wǎng)絡(luò)抓包

          • 第1步:此時(shí)處于MySQL通信協(xié)議階段,客戶端發(fā)送關(guān)閉連接請(qǐng)求,而且不用等待服務(wù)端的響應(yīng);
          • 第2步:TCP斷開(kāi)連接,4次揮手完成連接斷開(kāi);

          這里是完整地完成了從數(shù)據(jù)庫(kù)連接的建立到關(guān)閉,整個(gè)過(guò)程花費(fèi)了:

          747.284311 - 747.100954 = 0.183357s = 183.357ms

          這里可能也有網(wǎng)絡(luò)狀況的影響,比上述的225ms少了,但是也幾乎達(dá)到了200ms的級(jí)別。

          那么問(wèn)題來(lái)了,想象一下這個(gè)場(chǎng)景,對(duì)于一個(gè)日活2萬(wàn)的網(wǎng)站來(lái)說(shuō),假設(shè)每個(gè)用戶只會(huì)發(fā)送5個(gè)請(qǐng)求,那么一天就是10萬(wàn)個(gè)請(qǐng)求,對(duì)于建立數(shù)據(jù)庫(kù)連接,我們保守一點(diǎn)計(jì)算為150ms好了,那么一天當(dāng)中花費(fèi)在建立數(shù)據(jù)庫(kù)連接的時(shí)間有(還不包括執(zhí)行查詢和更新操作):

          100000 * 150ms = 15000000ms = 15000s = 250min = 4.17h

          也就說(shuō)每天花費(fèi)在建立數(shù)據(jù)庫(kù)連接上的時(shí)間已經(jīng)達(dá)到「4個(gè)小時(shí)」 ,所以說(shuō)數(shù)據(jù)庫(kù)連接池是必須的嘛,而且當(dāng)日活增加時(shí),單單使用數(shù)據(jù)庫(kù)連接池也不能完全保證你的服務(wù)能夠正常運(yùn)行,還需要考慮其他的解決方案:

          • 緩存
          • SQL的預(yù)編譯
          • 負(fù)載均衡
          • ……

          當(dāng)然這不是本文的主要內(nèi)容,「本文想要闡述的核心思想只有一個(gè),數(shù)據(jù)庫(kù)連接真的很耗時(shí),所以不要頻繁的建立連接」

          程序汪資料鏈接

          程序汪接的7個(gè)私活都在這里,經(jīng)驗(yàn)整理

          Java項(xiàng)目分享  最新整理全集,找項(xiàng)目不累啦 07版

          堪稱(chēng)神級(jí)的Spring Boot手冊(cè),從基礎(chǔ)入門(mén)到實(shí)戰(zhàn)進(jìn)階

          臥槽!字節(jié)跳動(dòng)《算法中文手冊(cè)》火了,完整版 PDF 開(kāi)放下載!

          臥槽!阿里大佬總結(jié)的《圖解Java》火了,完整版PDF開(kāi)放下載!

          字節(jié)跳動(dòng)總結(jié)的設(shè)計(jì)模式 PDF 火了,完整版開(kāi)放下載!


          歡迎添加程序汪個(gè)人微信 itwang009  進(jìn)粉絲群或圍觀朋友

          瀏覽 50
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  日本黄色片视频 | 人人人人人色 | 大香蕉伊然在亚洲91 | 国产手机在线操你啦 | 国产夫妻自拍在线观看 |