golang mysql断线_MySQL的连接池、异步、断线重连-Go语言中文社区
MySQL長連接
MySQL短連接每次請求操作數(shù)據(jù)庫都需要建立與MySQL服務(wù)器建立TCP連接,這是需要時(shí)間開銷的。TCP連接需要3次網(wǎng)絡(luò)通信。這樣就增加了一定的延時(shí)和額外的IO消耗。請求結(jié)束后會(huì)關(guān)閉MySQL連接,還會(huì)發(fā)生3/4次網(wǎng)絡(luò)通信。
close操作不會(huì)增加響應(yīng)延時(shí),原因是close后是由操作系統(tǒng)自動(dòng)進(jìn)行通信的,應(yīng)用程序感知不到
長連接就可以避免每次請求都創(chuàng)建連接的開銷,節(jié)省了時(shí)間和IO消耗。提升了PHP程序的性能。
斷線重連
在cli環(huán)境下,PHP程序需要長時(shí)間運(yùn)行,客戶端與MySQL服務(wù)器之間的TCP連接是不穩(wěn)定的。
MySQL-Server會(huì)在一定時(shí)間內(nèi)自動(dòng)切斷連接
PHP程序遇到空閑期時(shí)長時(shí)間沒有MySQL查詢,MySQL-Server也會(huì)切斷連接回收資源
其他情況,在MySQL服務(wù)器中執(zhí)行kill process殺掉某個(gè)連接,MySQL服務(wù)器重啟
這時(shí)PHP程序中的MySQL連接就失效了。如果仍然執(zhí)行mysql_query,就會(huì)報(bào)一個(gè)“MySQL server has gone away”的錯(cuò)誤。程序處理不到就直接遇到致命錯(cuò)誤并退出了。所以PHP程序中需要斷線重連。
有很多人提出了mysql_ping的方案,每次mysql_query進(jìn)行連接檢測或者定時(shí)連接檢測。這個(gè)方案不是最好的。原因是
mysql_ping需要主動(dòng)偵測連接,帶來了額外的消耗
定時(shí)執(zhí)行mysql_ping不能解決問題,如剛剛執(zhí)行過mysql_ping檢測之后,連接就關(guān)閉了
最佳的方案是進(jìn)行斷線重連 。它的原理是:
(SwooleCoroutineMysql和PDO等其他客戶端同理, 此處簡單舉例)
mysql_query執(zhí)行后檢測返回值
如果mysql_query返回失敗,檢測錯(cuò)誤碼發(fā)現(xiàn)為2006/2013(這2個(gè)錯(cuò)誤表示連接失敗),再執(zhí)行一次mysql_connect
執(zhí)行mysql_connect后,重新執(zhí)行mysql_query,這時(shí)必然會(huì)成功,因?yàn)橐呀?jīng)重新建立了連接
如果mysql_query返回成功,那么連接是有效的,這是一次正常的調(diào)用
MySQL異步
MySQL異步是指將MySQL連接事件驅(qū)動(dòng)化,這樣就變成了非阻塞IO。數(shù)據(jù)庫操作并不會(huì)阻塞進(jìn)程,在MySQL-Server返回結(jié)果時(shí)再執(zhí)行對應(yīng)的邏輯。
有幾個(gè)點(diǎn)需要注意一下:
異步MySQL并沒有節(jié)省SQL執(zhí)行的時(shí)間
一個(gè)MySQL連接同時(shí)只能執(zhí)行1個(gè)SQL,如果異步MySQL存在并發(fā)那么必須創(chuàng)建多個(gè)MySQL連接
異步回調(diào)程序中,異步MySQL并沒有提升性能。異步最大的好處是可以高并發(fā),如果并發(fā)1萬個(gè)請求,那么就需要建立1萬個(gè)MySQL連接,這會(huì)給MySQL-Server帶來巨大的壓力。
MySQL是根據(jù)連接數(shù)分配資源的,一個(gè)連接需要開啟一個(gè)線程。1000連接那么需要維持1000線程才可以。線程數(shù)量增加后,線程間切換會(huì)占用大量CPU資源
MySQL短連接反而不會(huì)出現(xiàn)此問題,因?yàn)槎踢B接在使用完后就釋放了。不會(huì)占用MySQL-Server的連接資源
雖然應(yīng)用層代碼使用異步回調(diào)避免了自身的阻塞,實(shí)際上真正的瓶頸是數(shù)據(jù)庫服務(wù)器。異步MySQL還帶來了額外的編程復(fù)雜度,所以除非是特殊場景的需求,否則不建議使用異步MySQL。
如果程序中堅(jiān)持要使用異步,那么必須是異步MySQL+連接池的形式。超過規(guī)定的MySQL最大連接后,應(yīng)當(dāng)對SQL請求進(jìn)行排隊(duì),而不是創(chuàng)建新連接,避免大量并發(fā)請求導(dǎo)致MySQL服務(wù)器崩潰。
MySQL連接池
連接池是可以有效降低MySQL-Server負(fù)載的。原理是 連接池使用一個(gè)共享資源的模式,如并發(fā)100個(gè)請求,實(shí)際上并不是每個(gè)請求的所有時(shí)間都在執(zhí)行SQL查詢。這樣100個(gè)請求,共享20個(gè)MySQL連接就可以滿足需求了。當(dāng)一個(gè)請求操作完數(shù)據(jù)庫后,開始進(jìn)入模板渲染等流程,這時(shí)就會(huì)釋放數(shù)據(jù)庫連接給其他的請求使用。
連接池僅在超大型應(yīng)用中才有價(jià)值。普通的應(yīng)用采用MySQL長連接方案,每個(gè)php-fpm創(chuàng)建一個(gè)MySQL連接,每臺(tái)機(jī)器開啟100個(gè)php-fpm進(jìn)程。如果有10臺(tái)機(jī)器,每臺(tái)機(jī)器并發(fā)的請求為100。實(shí)際上只需要?jiǎng)?chuàng)建1000個(gè)MySQL連接就能滿足需求,數(shù)據(jù)庫的壓力并不大。即使有100臺(tái)機(jī)器,硬件配置好的存儲(chǔ)服務(wù)器依然可以承受。
達(dá)到數(shù)百或者數(shù)千臺(tái)應(yīng)用服務(wù)器時(shí),MySQL服務(wù)器就需要維持十萬級的連接。這時(shí)數(shù)據(jù)庫的壓力就會(huì)非常大了。連接池技術(shù)就可以派上用場了,可以大大降低數(shù)據(jù)庫連接數(shù)。
同步阻塞模式
可基于swoole的AsyncTask模塊實(shí)現(xiàn)的連接池,編程簡單,沒有數(shù)據(jù)同步和鎖的問題。甚至可以多個(gè)服務(wù)共享連接池。缺點(diǎn)是: 1. 靈活性不如多線程連接池,無法動(dòng)態(tài)增減連接 2. 有一次進(jìn)程間通信的開銷
協(xié)程模式
可使用channel實(shí)現(xiàn)連接池。
總結(jié)
以上是生活随笔為你收集整理的golang mysql断线_MySQL的连接池、异步、断线重连-Go语言中文社区的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: php处理base64数据,php基于b
- 下一篇: 鸿蒙系统能不能用了,【图片】华为鸿蒙系统