workerman與數(shù)據(jù)庫結(jié)合的時(shí)候,產(chǎn)生的問題和解決案例。
這里拿mysql數(shù)據(jù)庫為例
可能產(chǎn)生的問題如下:
一般數(shù)據(jù)庫類都是單例模式,也就是一個(gè)數(shù)據(jù)庫實(shí)例對(duì)應(yīng)一個(gè)數(shù)據(jù)庫鏈接,后續(xù)直接復(fù)用了這個(gè)數(shù)據(jù)庫鏈接,避免了建立鏈接TCP三次握手、權(quán)限驗(yàn)證、鏈接關(guān)閉TCP四次握手等網(wǎng)絡(luò)交互過程。在worekrman中這種復(fù)用更為徹底,每個(gè)進(jìn)程只需要?jiǎng)?chuàng)建一個(gè)數(shù)據(jù)庫實(shí)例,在整個(gè)進(jìn)程生命周期內(nèi)(可能很長很長)都可以一直復(fù)用這個(gè)鏈接,所以在workerman中使用數(shù)據(jù)庫等資源(包括其它存儲(chǔ)如memcache、redis等等)是非常高效的。
但是在mysql中會(huì)有一個(gè)問題,就是mysql服務(wù)端會(huì)定時(shí)關(guān)閉一些長期沒有活動(dòng)的數(shù)據(jù)庫鏈接,當(dāng)鏈接關(guān)閉時(shí),在php的mysql擴(kuò)展層面并沒有重連機(jī)制,導(dǎo)致在php中使用這個(gè)鏈接已經(jīng)被服務(wù)端斷開的數(shù)據(jù)庫實(shí)例時(shí)會(huì)報(bào) mysql gone away 錯(cuò)誤,導(dǎo)致數(shù)據(jù)庫操作失敗。從這里看出來其實(shí)這并不是workerman的問題。應(yīng)該算作php mysql擴(kuò)展機(jī)制或者說mysql機(jī)制的問題
這個(gè)問題是很好解決的,比如
1、在性能要求不苛刻的時(shí)候,不使用單例模式,每次重新創(chuàng)建鏈接
2、使用單例模式,出錯(cuò)時(shí)判斷錯(cuò)誤碼 是不是2006(mysql gone away固定是這個(gè)錯(cuò)誤碼),是的話重連(或者說重新創(chuàng)建一個(gè)數(shù)據(jù)庫實(shí)例)
3、單例模式,每次請(qǐng)求完畢后刪除實(shí)例
4、定時(shí)任務(wù)(Man\Core\Lib\Task),定時(shí)ping mysql,不讓mysql關(guān)閉鏈接
經(jīng)過測試 memcache和redis會(huì)自動(dòng)重連,沒有這個(gè)問題
我一直擔(dān)心redis的訂閱,長時(shí)間沒有消息,連接會(huì)不會(huì)中斷,導(dǎo)致訂閱出問題。walkor的意思是不會(huì)有這個(gè)問題?
@walkor 我的業(yè)務(wù)對(duì)數(shù)據(jù)庫性能要求不高,那我用sqlite數(shù)據(jù)庫會(huì)不會(huì)也存在上述mysql數(shù)據(jù)庫的問題?