混沌系列 | 其实制造“假死”很容易
點(diǎn)擊上方“朱小廝的博客”,選擇“設(shè)為星標(biāo)”
回復(fù)”1024“獲取獨(dú)家整理的學(xué)習(xí)資料
歡迎跳轉(zhuǎn)到本文的原文鏈接:https://honeypps.com/chaos/how-to-play-dead/
?
?
這篇也是混沌工程相關(guān)的,之前寫了《看我如何作死| 將CPU、IO打爆》和《看我如何作死| 網(wǎng)絡(luò)延遲、網(wǎng)絡(luò)丟包、網(wǎng)絡(luò)中斷一個(gè)都沒落下》這兩篇,不過這次不用作死,只是假死。^-^
假死,有機(jī)器假死、進(jìn)程假死和線程假死這幾種。讓機(jī)器、進(jìn)程之類的假死本身沒有多大意義,探索當(dāng)機(jī)器、進(jìn)程之類的假死之后,其上游調(diào)用所接收到的狀態(tài)(或者說得到的反饋)才有意義。上游通過評(píng)估下游假死之后其本身所觸發(fā)的動(dòng)作反應(yīng)以及導(dǎo)致的結(jié)果來分析其服務(wù)本身的質(zhì)量,如果未達(dá)預(yù)期,那么就需要做進(jìn)一步的整改優(yōu)化。
現(xiàn)象
機(jī)器假死一般所表現(xiàn)的現(xiàn)象為機(jī)器本身可以ping通,但是任何其它操作沒有反應(yīng),包括ssh無法登陸、內(nèi)部部署的服務(wù)進(jìn)程無法對(duì)外提供服務(wù)等。
對(duì)于某一臺(tái)機(jī)器,首先可以開啟一個(gè)服務(wù)進(jìn)程,可以對(duì)外提供服務(wù),這里假設(shè)服務(wù)端口是6666。這個(gè)時(shí)候你可以啟動(dòng)一個(gè)腳本去fork 100個(gè)進(jìn)程,這樣來直接(如果100不夠就多加一點(diǎn))導(dǎo)致機(jī)器假死,最終ssh也登錄不了這臺(tái)機(jī)器。如果還想要知道對(duì)于上游來說,下游的機(jī)器假死會(huì)得到什么樣的現(xiàn)象的話,可以在這個(gè)時(shí)候去訪問以下假死的這臺(tái)機(jī)器的6666端口的服務(wù)。這里就不賣關(guān)子了,最終上游所接收到的狀態(tài)應(yīng)該是會(huì)出現(xiàn)超時(shí),即timeout。
一個(gè)進(jìn)程結(jié)束后,它并不會(huì)立刻從內(nèi)存中消失,它的進(jìn)程控制塊還駐留在內(nèi)存中,此刻這個(gè)進(jìn)程的狀態(tài)變成EXIT_ZOMBIE,并且會(huì)給它的父進(jìn)程發(fā)送SIGCHLD信號(hào)。父進(jìn)程收到信號(hào)后會(huì)做一些處理,然后子進(jìn)程才會(huì)徹底被移除。假死一般的進(jìn)程并不會(huì)占用太多的系統(tǒng)資源,只會(huì)占用很少的內(nèi)存。不過,假死進(jìn)程會(huì)占用PID,而Linux中的PID的數(shù)量是由限制的。為了向下兼容,Linux中一般設(shè)定PID的上限為32767。
進(jìn)程假死可以總結(jié)為不提供服務(wù),但是還駐留在內(nèi)存中。我們可以在某臺(tái)機(jī)器上運(yùn)行一個(gè)主進(jìn)程和一個(gè)子進(jìn)程,子進(jìn)程開啟7777端口,對(duì)外正常提供服務(wù)。之后關(guān)閉子進(jìn)程,然后讓主進(jìn)程sleep一段時(shí)間,在這段時(shí)間里,子進(jìn)程處于假死狀態(tài)。此時(shí)上游去訪問這個(gè)7777端口的服務(wù)又會(huì)出現(xiàn)什么現(xiàn)象呢?上游會(huì)發(fā)生connection refused。
線程假死會(huì)釋放所使用的資源,但在進(jìn)程表中還會(huì)保留其條目。線程假死的時(shí)候上游會(huì)是timeout。
上面我直接告訴了各種假死場景下的測試結(jié)果,有興趣的同學(xué)可以自行測試一下。
模擬
總結(jié)一下,假死之后上游得到的反饋要么是timeout,要么是connection refused。這個(gè)可以讓我們聯(lián)想到iptables的reject和drop,他們彼此所呈現(xiàn)出來的狀態(tài)是一樣的。
模擬timeout:
iptables?-A?OUTPUT?-p?tcp?--dport?6666?-j?DROP模擬connection refused:
iptables?-A?OUTPUT?-p?tcp?--dport?7777?-j?REJECT我們?cè)谧龉收献⑷牖蛘吖收涎菥毜臅r(shí)候,并不是所有的時(shí)候都需要真的對(duì)某個(gè)下游服務(wù)做一些“出格”的動(dòng)作。有些故障場景下,我們可以事先測試出這個(gè)服務(wù)處于某種故障下時(shí),上游所得到的反饋,然后通過其他的方式去模擬出同樣的反饋即可。這樣當(dāng)要終止故障的時(shí)候也容易快速恢復(fù)。比如機(jī)器假死的故障,如果直接讓機(jī)器假死,然后實(shí)驗(yàn)之后恢復(fù)時(shí)需要重啟機(jī)器,反之只需要簡單的撤銷iptables的策略即可。
混沌工程知識(shí)補(bǔ)充
“故障是注定的,隨著時(shí)間的流逝,一切終將歸于失敗”。我們必須接受故障發(fā)生是新常態(tài)的想法,處在部分故障的系統(tǒng)正常運(yùn)行是完全可行的。當(dāng)我們處理多達(dá)幾十個(gè)服務(wù)實(shí)例的小型系統(tǒng)時(shí),100%的健康運(yùn)行通常是正常狀態(tài),故障則是一種特殊情況。然而,在處理大規(guī)模系統(tǒng)時(shí),即100%的健康運(yùn)行幾乎是不可能實(shí)現(xiàn)的。因此,運(yùn)維的新常態(tài)便是接受部分故障。處在部分故障中的系統(tǒng)要求仍能正常運(yùn)行對(duì)外提供服務(wù),這就需要架構(gòu)本身具備 Resilient 能力,這里的Resilient即為韌性(具備恢復(fù)能力)。
混沌工程就是利用實(shí)驗(yàn)提前探知系統(tǒng)風(fēng)險(xiǎn),通過架構(gòu)優(yōu)化和運(yùn)維模式的改進(jìn)來解決系統(tǒng)風(fēng)險(xiǎn),真正實(shí)現(xiàn)上述韌性架構(gòu),降低企業(yè)損失,提高故障免疫力。
韌性架構(gòu)的重要特征:
?
歡迎跳轉(zhuǎn)到本文的原文鏈接:https://honeypps.com/chaos/how-to-play-dead/
想知道更多?掃描下面的二維碼關(guān)注我
相關(guān)推薦:
?
?
>>>Learn More<<
?
點(diǎn)個(gè)"在看"唄^_^
總結(jié)
以上是生活随笔為你收集整理的混沌系列 | 其实制造“假死”很容易的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 干货!Elasticsearch性能优化
- 下一篇: Spring Boot 几条最佳实践!