在我的技術(shù)交流群里,看到有朋友討論實(shí)現(xiàn)重連問題,說說我自己對這個(gè)問題的淺見。
重連接不如重啟;盡力維持穩(wěn)定不如讓它崩潰。
當(dāng)程序內(nèi)部狀態(tài)已經(jīng)紊亂,而我們無法控制,或許這是第三方庫或框架的問題,或許這是其它同事學(xué)藝不精的問題。與其我們花費(fèi)大量精力去解決,想方設(shè)法找一種讓程序永久不停的解決方案,不如我們使用簡單的腳本語言寫一個(gè)簡單的守護(hù),由這個(gè)守護(hù)程序去重啟動(dòng)我們的應(yīng)用程序,那么我們的應(yīng)用程序就可以輕松的退出,就在它無法維持正確狀態(tài)的時(shí)候。簡單了就使程序容易控制,bug相對少而且容易查找,那么我們就能保證守護(hù)程序相對穩(wěn)定,因此把一個(gè)小小的守護(hù)程序做穩(wěn)定,遠(yuǎn)比把一個(gè)不停變化的應(yīng)用系統(tǒng)搞穩(wěn)定容易得多。
守護(hù)程序不穩(wěn)定怎么辦?很多新手擔(dān)心應(yīng)用系統(tǒng)和守護(hù)一起死掉,有這種擔(dān)心是正確的。為解決這個(gè)擔(dān)心,一般采用兩級守護(hù):一級守護(hù),負(fù)責(zé)守護(hù)應(yīng)用系統(tǒng);二級守護(hù),負(fù)責(zé)守護(hù)一級守護(hù)程序。這樣就把同時(shí)死掉的幾率下降很多了。那是不是為了安全,我們搞個(gè)十級、二十級守護(hù),這就繁瑣到杞人憂天的地步了,如果真有那么不穩(wěn)定,我們應(yīng)該檢查程序,提高我們代碼質(zhì)量,好好考慮開發(fā)人員的素質(zhì)和工作態(tài)度了。
當(dāng)然,簡單的程序退出,是否影響應(yīng)用系統(tǒng)的業(yè)務(wù)邏輯完整性?是不是我們的應(yīng)用系統(tǒng)本身不允許簡單的退出?這個(gè)問題很復(fù)雜,看你自己怎么設(shè)計(jì)這個(gè)系統(tǒng)的。為了達(dá)到能簡單的退出,一個(gè)可能的解決辦法就是,在架構(gòu)上保證,在協(xié)議上保證,遵循《unix編程藝術(shù)》上的設(shè)計(jì)原則是很重要的。
早年我力求把程序?qū)懙煤芊€(wěn)定,也要求周圍的人把程序?qū)懙煤芊€(wěn)定,回頭看其實(shí)從來沒達(dá)到過。主要是技術(shù)不行,別人就更無法把握,就算自己是主管,也逼迫不了別人。
記得曾經(jīng)有一個(gè)客戶端是用java寫的,它本身是一個(gè)后臺服務(wù),收集地市服務(wù)器的日志和運(yùn)行狀態(tài),當(dāng)時(shí)采用mina框架,v0.9的版本。為了socket斷開后的重連接,程序員寫了很多代碼,兩三個(gè)while循環(huán),最后竟然不穩(wěn)定。寫了這么多代碼,能達(dá)到預(yù)期目的還好,達(dá)不到還費(fèi)力,就郁悶了。我也沒時(shí)間去查什么bug, 是不是mina使用不對啊什么的。后來,我直接叫他們把那些檢測和重連的代碼刪除,程序一旦發(fā)現(xiàn)連接不了中心服務(wù)器,直接退出算了,我使用bash寫了一個(gè)簡單的守護(hù),負(fù)責(zé)重啟動(dòng)它。這個(gè)問題就這樣簡單的解決了,本來這個(gè)后臺服務(wù)也要求不高,直接退出沒有什么業(yè)務(wù)邏輯問題。
守護(hù)是不可靠的,最終還是需要人來維護(hù)。守護(hù)配合一定的監(jiān)控報(bào)警手段,讓維護(hù)人員及時(shí)發(fā)現(xiàn)問題初現(xiàn),及時(shí)解決軟硬件問題,才是解決之道。
當(dāng)然,程序穩(wěn)定性還是要程序本身穩(wěn)定,如果程序不停core,守護(hù)不停重啟,有什么作用呢。