軟件混沌工程原則以及應用介紹(PRINCIPLES OF CHAOS ENGINEERING)

文章首發於微信公衆號【軟測小生

Chaos Engineering(混沌工程),相信搞互聯網的或多或少都聽過,Netflix 發明了 Chaos Monkey,經過社區的發展回饋,慢慢形成了 Chaos Engineering。

混沌工程是在分佈式系統上進行實驗的學科, 目的是建立對系統抵禦生產環境中失控條件的能力以及信心。

混沌工程原文地址:
https://github.com/wizardbyron/principlesofchaos_zh-cn

大規模分佈式軟件系統的發展正在改變軟件工程。作爲一個行業,我們很快採用了提高開發靈活性和部署速度的實踐。緊隨着這些優點的一個迫切問題是:我們對投入生產的複雜系統有多少信心?

即使分佈式系統中的所有單個服務都正常運行, 這些服務之間的交互也會導致不可預知的結果。 這些不可預知的結果, 由影響生產環境的罕見且破壞性的事件複合而成,令這些分佈式系統存在內在的混沌。

我們需要在異常行爲出現之前,在整個系統內找出這些弱點。這些弱點包括以下形式:

  • 當服務不可用時的不正確回滾設置;
  • 不當的超時設置導致的重試風暴;
  • 由於下游依賴的流量過載導致的服務中斷;
  • 單點故障時的級聯失敗等。

我們必須主動的發現這些重要的弱點,在這些弱點通過生產環境暴露給我們的用戶之前。我們需要一種方法來管理這些系統固有的混沌, 通過增加的靈活性和速率以提升我們對生產環境部署的信心, 儘管系統的複雜性是由這些部署所導致的。

我們採用基於經驗和系統的方法解決了分佈式系統在規模增長時引發的問題, 並以此建立對系統抵禦這些事件的能力和信心。通過在受控實驗中觀察分佈式系統的行爲來了解它的特性,我們稱之爲混沌工程。

混沌工程實踐

爲了具體地解決分佈式系統在規模上的不確定性,可以把混沌工程看作是爲了揭示系統弱點而進行的實驗。這些實驗遵循四個步驟:

  • 首先,用系統在正常行爲下的一些可測量的輸出來定義“穩定狀態”。
  • 其次,假設這個在控制組和實驗組都會繼續保持穩定狀態。
  • 然後,在實驗組中引入反映真實世界事件的變量,如服務器崩潰、硬盤故障、網絡連接斷開等。
  • 最後,通過控制組和實驗組之間的狀態差異來反駁穩定狀態的假說。

破壞穩態的難度越大,我們對系統行爲的信心就越強。如果發現了一個弱點,那麼我們就有了一個改進目標。避免在系統規模化之後被放大。

高級原則

以下原則描述了應用混沌工程的理想方式,這些原則基於上述實驗過程。對這些原則的匹配程度能夠增強我們在大規模分佈式系統的信心。

1、建立一個圍繞穩定狀態行爲的假說

要關注系統的可測量輸出, 而不是系統的屬性。對這些輸出在短時間內的度量構成了系統穩定狀態的一個代理。 整個系統的吞吐量、錯誤率、延遲百分點等都可能是表示穩態行爲的指標。 通過在實驗中的系統性行爲模式上的關注, 混沌工程驗證了系統是否正常工作, 而不是試圖驗證它是如何工作的。

2、多樣化真實世界的事件

混沌變量反映了現實世界中的事件。 我們可以通過潛在影響或估計頻率排定這些事件的優先級。考慮與硬件故障類似的事件, 如服務器宕機、軟件故障 (如錯誤響應) 和非故障事件 (如流量激增或伸縮事件)。 任何能夠破壞穩態的事件都是混沌實驗中的一個潛在變量。

3、在生產環境中運行實驗

系統的行爲會依據環境和流量模式都會有所不同。 由於資源使用率變化的隨時可能發生, 因此通過採集實際流量是捕獲請求路徑的唯一可靠方法。 爲了保證系統執行方式的真實性與當前部署系統的相關性, 混沌工程強烈推薦直接採用生產環境流量進行實驗。

4、持續自動化運行實驗

手動運行實驗是勞動密集型的, 最終是不可持續的。所以我們要把實驗自動化並持續運行,混沌工程要在系統中構建自動化的編排和分析。

5、最小化爆炸半徑

在生產中進行試驗可能會造成不必要的客戶投訴。雖然對一些短期負面影響必須有一個補償, 但混沌工程師的責任和義務是確保這些後續影響最小化且被考慮到。

混沌工程是一個強大的實踐, 它已經在世界上一些規模最大的業務系統上改變了軟件是如何設計和工程化的。 相較於其他方法解決了速度和靈活性, 混沌工程專門處理這些分佈式系統中的系統不確定性。 混沌工程的原則爲我們大規模的創新和給予客戶他們應得的高質量的體驗提供了信心。

當你看到這裏的時候,相信你對混沌工程是有一丟丟想法的,要不然你也不會找到這裏來,國內關於混沌工程的資料不多,多數都是講解概念的,可借鑑的落地方案不多(但也不是沒有),例如阿里的 Chaosblade,搞明白國內的之後,就可以朝着國外放眼了,這裏有大量Chaos Engineering的資料。
本文就以 chaosblade 工具爲例,來看看一個簡單的 Chaos Engineering 怎麼來落地,快速上手:chaosblade wiki,關於 chaosblade 的架構設計本文就不聊了,直接兩個字:開幹,所有操作均在/mnt/chaosblade-0.0.3 下進行

blade 指令

./blade  -h
An easy to use and powerful chaos engineering experiment toolkit

Usage:
  blade [command]

Available Commands:
  create      Create a chaos engineering experiment  #create 創建一個chaos engineering
  destroy     Destroy a chaos experiment  #destroy 銷燬一個destroy,一般銷燬完之後,再執行revoke子命令
  help        Help about any command  #在任何子命令後輸入help可查看該子命令的用法
  prepare     Prepare to experiment  #prepare 準備一個chaos engineering實驗
  query       Query the parameter values required for chaos experiments  #查詢已經註冊的chaos
  revoke      Undo chaos engineering experiment preparation  #撤回註冊chaos engineering
  status      Query preparation stage or experiment status  #查看註冊的chaos engineering的狀態
  version     Print version info

Flags:
  -d, --debug   Set client to DEBUG mode
  -h, --help    help for blade

Use "blade [command] --help" for more information about a command.

ps:其中 prepare、create、destroy、revoke 四個指令用的比較多,prepare 是運行 java 程序的時候需要提前使用的一個指令,提前 attach 到 jvm 上

blade 默認支持場景

./blade create -h
Create a chaos engineering experiment

Usage:
  blade create [command]

Aliases:
  create, c

Examples:
create dubbo delay --time 3000 --offset 100 --service com.example.Service --consumer

Available Commands:
  cpu         Cpu experiment   #cpu負載測試,還可以指定負載在哪個cpu上
  disk        Disk experiment   #disk負載測試,支持disk的read/write負載模擬,還支持模擬磁盤填充
  docker      Execute a docker experiment   #docker負載測試,支持docker的cpu、disk、network、process、remove、script等負載測試
  druid       Druid experiment   #支持druid連接池的連接滿模擬
  dubbo       dubbo experiment   #支持dubbo的延遲、連接池滿、異常模擬
  jvm         method   #這個支持的就多了,下面細聊
  k8s         Kubernetes experiment   #k8s負載測試,支持k8s的同期的刪除測試
  mysql       mysql experiment   #支持mysql的延遲、異常模擬
  network     Network experiment   #network負載測試,支持網絡的延遲、dns查詢延遲、丟包、遠程服務丟失等場景
  process     Process experiment   #process負載測試,支持模擬kill process的場景
  script      Script chaos experiment
  servlet     java servlet experiment   #支持servlet的延遲、異常模擬

Flags:
  -h, --help   help for create

Global Flags:
  -d, --debug   Set client to DEBUG mode

Use "blade create [command] --help" for more information about a command.

其中 network、jvm、mysql、docker 都是一些熱門組件的異常模擬場景。

下面看看 jvm 的,jvm 支持以下五個場景:

delay                  delay time
outofmemoryerror       JVM out of memory
return                 Return the specify value
throwCustomException   throw custom exception
throwDeclaredException Throw the first declared exception of method

ps:其中 delay、throwCustomException 都是需要指定到方法級別的,如果測試人員對業務代碼瞭解深入的話,可以利用這個特性做破壞性測試。

看着支持的場景很多,其實在 Chaosblade 沒出現之前,cpu、disk、network、process、k8s 這些場景都是可以通過 linux 下面的某些命令來模擬的,如果是阿里生態系的,jvm、druid、dubbo 這三個需要熟練的使用, 如果官方能提供 oracle 的異常場景就更好了。

blade 啓動注意

blade 需要和待測試的運行進程屬於同一用戶,且 JAVA 版本、JAVA_HOME 要設置正確。針對系統層面的設置,則需要管理員權限。

blade 模擬接口延時

1、準備 attach 一個 jvm

./blade prepare jvm --process 19761
---
{"code":200,"success":true,"result":"2679c66005a0aadd"}

ps:2679c66005a0aadd 需要記住,如果忘記也可以通過 query 查詢

2、模擬接口延遲

./blade create network delay --interface eth0 --exclude-port 22 --time 10000
---
{"code":200,"success":true,"result":"dc913ccc9a7e5ea1"}

ps:注意針對接口的延遲需要管理員權限才能操作

3、測試接口延遲

#測試前
time  curl http://192.168.1.6:8000/test/index.php -I
---
HTTP/1.1 200
Content-Type: application/json;charset=UTF-8
Content-Length: 69
Date: Mon, 10 Jun 2019 08:35:31 GMT

real	0m0.026s
user	0m0.003s
sys	0m0.000s

#測試後
time  curl http://192.168.1.6:8000/test/index.php -I
---
curl: (7) couldn't connect to host

real	0m3.003s
user	0m0.001s
sys	0m0.003s

ps:可以看到針對 url 的訪問明顯失敗

4、查看有哪些 chaos 實驗

./blade status --type create
{
	"code": 200,
	"success": true,
	"result": [
		{
			"Uid": "dc913ccc9a7e5ea1",
			"Command": "network",
			"SubCommand": "delay",
			"Flag": "--exclude-port 45685 --debug false --help false --interface eth0 --time 10000",
			"Status": "Success",
			"Error": "",
			"CreateTime": "2019-06-10T16:36:31.072125181+08:00",
			"UpdateTime": "2019-06-10T16:36:31.107533437+08:00"
		}
	]
}

5、銷燬創建的 chaos 實驗

./blade destroy dc913ccc9a7e5ea1
---
{"code":200,"success":true,"result":"command: network delay --exclude-port 22 --debug false --help false --interface eth0 --time 10000"}

6、撤銷 chaos 工程

    先查詢id
./blade status --type prepare
---
{
	"code": 200,
	"success": true,
	"result": [
		{
			"Uid": "2679c66005a0aadd",
			"ProgramType": "jvm",
			"Process": "19761",
			"Port": "16698",
			"Status": "Running",
			"Error": "",
			"CreateTime": "2019-06-10T16:31:58.09072211+08:00",
			"UpdateTime": "2019-06-10T16:32:05.907016597+08:00"
		}
	]
}
    再撤銷
./blade revoke 2679c66005a0aadd
---
{"code":200,"success":true,"result":"success"}

Chaosblade 模型

ps:默認的場景肯定不能完全適應你的需求,所以我們還是需要了解 Chaosblade 的設計模型的,看看如何自定義擴展需求場景

Chaosblade 命令執行過程

阿里 Chaosblade 項目地址: https://github.com/chaosblade-io/chaosblade/wiki/%E6%96%B0%E6%89%8B%E6%8C%87%E5%8D%97

ChaosEngineering工程實戰–chaosblade https://my.oschina.net/guol/blog/3060265
作者:China_OS(開源中國)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章