湖南做網(wǎng)站 真好磐石網(wǎng)絡(luò)網(wǎng)站優(yōu)化推廣方案
MySQL連接池原理與簡易網(wǎng)站數(shù)據(jù)流動(dòng)是如何進(jìn)行
- 1.MySQL連接池原理
- 2.簡易網(wǎng)站數(shù)據(jù)流動(dòng)是如何進(jìn)行
點(diǎn)贊👍👍收藏🌟🌟關(guān)注💖💖
你的支持是對我最大的鼓勵(lì),我們一起努力吧!😃😃
1.MySQL連接池原理
目前我們對mysql有了一定的理解,下面我們談一下,mysql在網(wǎng)站或者公司內(nèi)部一套存儲(chǔ)方案它定位的問題。
實(shí)際上在開發(fā)的時(shí)候把表結(jié)構(gòu)各方面設(shè)計(jì)好了,接下來要做的不是寫各種各樣的sql,在做開發(fā)的時(shí)候,是先要連接數(shù)據(jù)庫的。而我們會(huì)發(fā)現(xiàn)連接數(shù)據(jù)庫的時(shí)候每一次連的都是先創(chuàng)建數(shù)據(jù)庫對象然后connet用完之后要把釋放把連接關(guān)掉,這種執(zhí)行一條sql這種就把連接關(guān)了這是一種短連接,并且挺浪費(fèi)的。
所以mysql在網(wǎng)站和數(shù)據(jù)庫之間,除了一些緩存方面的技術(shù),還有一個(gè)在編碼層面上的技術(shù)叫做 連接池。
那這個(gè)連接池如何理解呢?
以前是這樣做的,需要就連接一下連接之后返回,返回之后就斷開。而實(shí)際上我們可以自己設(shè)計(jì)一個(gè)連接池的小組件,它可以預(yù)先讓多個(gè)線程預(yù)先和mysql建立好連接,建立好連接之后不動(dòng)就一直處于連接的狀態(tài),我們可以把sql語句封裝成任務(wù)扔到連接池中,然后就可以把任務(wù)交給連接池中的線程。一定是這個(gè)線程啟動(dòng)的時(shí)候就綁定或者關(guān)聯(lián)了mysql連接資源,說白了不就是給線程設(shè)計(jì)一個(gè)類,線程內(nèi)部里在創(chuàng)建MYSQL對象。在線程池構(gòu)造線程的同時(shí)把MYSQL對象也構(gòu)建除了。線程啟動(dòng)之后就把mysql連接連上,連上之后線程不就進(jìn)入自己的事件主循環(huán),然后我們就可以直接用這個(gè)連接了。
那這個(gè)玩意怎么做呢?
如果在Linux學(xué)過線程池的話非常簡單,這個(gè)連接池內(nèi)部其實(shí)只需要維護(hù)一個(gè)任務(wù)隊(duì)列就可以。這個(gè)連接池里面創(chuàng)建線程池今天還需要加上MYSQL對象,每一個(gè)線程給它搞一個(gè)MYSQL對象,這個(gè)創(chuàng)建MYSQL對象可以當(dāng)作線程類的類內(nèi)成員,當(dāng)初始化線程就可以把對應(yīng)的MYSQL對象也初始化出來。當(dāng)啟動(dòng)線程之后也把mysql連接建立好,這樣每一個(gè)線程都有自己mysql的句柄,都維護(hù)了自己的連接。然后線程進(jìn)入等待任務(wù)到來的死循環(huán)中不斷從任務(wù)隊(duì)列中拿任務(wù),有任務(wù)就拿沒任務(wù)就在條件變量下去等。我們未來就可以通過任務(wù)隊(duì)列把任務(wù)下達(dá)下去。
上層可以構(gòu)建任務(wù)task類,里面可以包含兩個(gè)成員一個(gè)是string sql,還有一個(gè)回調(diào)函數(shù)function cb。比如我現(xiàn)在是一個(gè)調(diào)用方,我要向mysql服務(wù)器下達(dá)一個(gè)delete指令,所以寫一個(gè)delete 的sql語句然后把它構(gòu)建成一個(gè)task,然后把這個(gè)task扔到連接池的任務(wù)隊(duì)列里,然后線程就可以從任務(wù)隊(duì)列里拿到任務(wù),然后拿到對應(yīng)任務(wù)的線程不是有msyql連接嗎,就可以去執(zhí)行mysql_query,把task對象中的sql拿出來交給mysql_query執(zhí)行。線程池預(yù)先創(chuàng)建,連接池預(yù)先創(chuàng)建,所以就避免了重新建立連接的動(dòng)作,所以此時(shí)一旦拿到task之后就給對mysql下達(dá)sql指令了。
為什么任務(wù)類里面放一個(gè)回調(diào)函數(shù)fuction?
這是因?yàn)槲覀冏约旱哪K可以有一個(gè)函數(shù)A。如果向mysql增加刪除更新還好說,但是讀取的時(shí)候我們需要把結(jié)果拿到。線程拿到這個(gè)sql執(zhí)行之后,然后多做一個(gè)動(dòng)作看看這個(gè)fuction是否存在,如果沒有那執(zhí)行完sql就真的完了。如果設(shè)置了然后線程池繼續(xù)回調(diào)這個(gè)fuction把我們查詢出來的結(jié)果通過回調(diào)拿回來。這個(gè)回調(diào)就是我們曾經(jīng)構(gòu)建task把自己的方法函數(shù)A綁定到task里面的function,所以數(shù)據(jù)就被拿回來了。
所以我們可以用這種想法去設(shè)計(jì)成一個(gè)連接池。
2.簡易網(wǎng)站數(shù)據(jù)流動(dòng)是如何進(jìn)行
一個(gè)用戶邏輯是怎么走的?以注冊和登錄為例。
現(xiàn)在有一個(gè)服務(wù)器上面搭載了一個(gè)網(wǎng)站,然后還有一臺(tái)服務(wù)器上面搭載了內(nèi)網(wǎng)中的mysql。這個(gè)服務(wù)器上面一定要搭建http:nginx或者業(yè)務(wù)型的tomcat。現(xiàn)在有一個(gè)用戶向網(wǎng)站發(fā)起一個(gè)注冊請求,然后這個(gè)網(wǎng)站給你回應(yīng)一個(gè)注冊頁面。然后把對應(yīng)信息填完就提交??赡苡玫氖荊ET或者POST方法把數(shù)據(jù)提交給了服務(wù)器,在服務(wù)器內(nèi)部它可能會(huì)用一些web語言 比如說php,python,java,然后就可以把你提交的這些數(shù)據(jù)進(jìn)行提取出來。然后判斷你這是注冊,所以就把你的數(shù)據(jù)構(gòu)建成sql直接提交到mysql里,自此這個(gè)用戶信息就被記錄到用戶表里了。但直接和數(shù)據(jù)庫打交道太慢了, 其次一般公司數(shù)據(jù)庫服務(wù)可能存在多份,所以它可能存在后端接入多個(gè)數(shù)據(jù)庫。那這個(gè)網(wǎng)站怎么去選擇用那個(gè)數(shù)據(jù)庫呢?那就需要一個(gè)中間鍵,可以用一些效率更到的語言如C/C++等。這個(gè)構(gòu)建成sql不用直接交道數(shù)據(jù)庫了,直接先交給它。然后它內(nèi)部做一些負(fù)載均衡,選擇把記錄插入數(shù)據(jù)庫。這些數(shù)據(jù)庫會(huì)定期做數(shù)據(jù)的互相同步,然后數(shù)據(jù)就都有了。
所以網(wǎng)站根本不關(guān)心后端有多少數(shù)據(jù)庫,我們把數(shù)據(jù)庫集群化。這里就出現(xiàn)這么多數(shù)據(jù)庫選擇那一個(gè)。你也不用管了,這個(gè)時(shí)候就在這兩個(gè)模塊之間添加一層軟件層。這就是在計(jì)算機(jī)學(xué)科任何的問題都可以通過加一層軟件來解決。所以加軟件層來解決對應(yīng)的問題。
然后別人想登錄,登錄也是一樣的要進(jìn)行請求登錄頁面,然后就返回登錄頁面,然后輸入用戶名和密碼接下來就以POST或者GET方法提交上來,然后怎么去驗(yàn)證這個(gè)用戶呢?所以還是提取后構(gòu)建一個(gè)sql語句,把這個(gè)sql通過服務(wù)下達(dá)給后端的數(shù)據(jù)庫。可以根據(jù)負(fù)載均衡隨便去找個(gè)數(shù)據(jù)庫,因?yàn)閿?shù)據(jù)是同步的。然后就去查,查完后把查詢結(jié)果返回,只要有結(jié)果說明這個(gè)用戶是合法,然后就可以在服務(wù)器層面給它形成各種cookie,session這樣的信息。另外我們在訪問頁面時(shí)可能會(huì)有一些高頻熱度的數(shù)據(jù)我們可以在加一些緩存之類的,比如說Rides之類的。所以在查數(shù)據(jù)時(shí)不一定要去數(shù)據(jù)庫里查,而先到緩存里,有的話直接從緩存里返回。沒有的話就去訪問mysql。
這就是一個(gè)網(wǎng)站整個(gè)初步的邏輯就是這個(gè)樣子的。