成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

快放開那些搗亂的猴子!

開發 架構
粗看標題你可能感覺莫名其妙,什么「搗亂的猴子」,還要放開。不急,且聽我說說為什么不光要放開這些搗亂的猴子,還要歡迎他們。

 

[[357021]]

粗看標題你可能感覺莫名其妙,什么「搗亂的猴子」,還要放開。不急,且聽我說說為什么不光要放開這些搗亂的猴子,還要歡迎他們。

0.背景信息

在構建高可用性軟件架構領域,有個詞叫「混沌工程」,對應的英文是Chaos Engineering,通過 Chaos 的測試,可以發現系統的潛在風險,特別對于分布式系統,找出脆弱的地方進行增強,提升可用性,避免系統間級聯影響。

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

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

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

https://principlesofchaos.org/zh/

后來Netflix 開源了其關于混沌工程的實現 ChaosMonkey,以猴子的形象來代表在系統里出其不意的破壞者。

比如

  • 機器或者一個機房掛了
  • 一部分網絡延遲嚴重
  • CPU、內存占用嚴重
  • 隨機讓某些服務異常或者響應延遲

再看Chaos 原則里提到的這些:

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

我們自己在代碼層面,在部署層面僅能關注應用的功能正常,但上述這些意想不到的出錯,是我們在代碼層面不太容易控制,也不易去測試的。

而ChaosMonkey 就是用來做這個的。所以,對于這些搗亂的猴子,我們是應該歡迎的,是不是像犀牛鳥之于犀牛?

關于ChaosMonkey,各個語言,各個公司也都有一些實現,其中Netflix的最出名。是go語言實現的。

在 Java Spring Boot 技術棧中,我發現一個容易理解和上手的實現。

https://github.com/codecentric/chaos-monkey-spring-boot

我們一起來看下如何上手以及它是怎樣實現的。

1. 上手

添加maven 依賴

  1. <dependency> 
  2.   <groupId>de.codecentric</groupId> 
  3.   <artifactId>chaos-monkey-spring-boot</artifactId> 
  4.   <version>2.3.0-SNAPSHOT</version> 
  5. </dependency> 

application.yml 中增加關于chaosmonkey的配置:

  1. chaos: 
  2.   monkey: 
  3.     enabled: true 
  4.     assaults: 
  5.       level: 1 
  6.       latencyRangeStart: 1000 
  7.       latencyRangeEnd: 10000 
  8.       exceptionsActive: true 
  9.       killApplicationActive: true 
  10.     watcher: 
  11.       repository: true 
  12.       controller: true 
  13. #      restController: true 
  14. #      service: true 

應用啟動時,記得激活chaosmonkey的配置:

  1. java -jar your-app.jar --spring.profiles.active=chaos-monkey 

再去請求你應用的controller,是不是發現異常產生了?這就是猴子在努力的搗亂中...

關于上面這些配置,再簡單解釋下:

你會發現chaos - monkey 配置下,除了 enabled,還有兩項比較大的配置項,一個是Assault,一個是Watcher。

其中Assault代表是搞什么破壞,比如破壞類型有超時、內存占用、殺死進程、拋出異常等等

  • Latency Assault
  • Exception Assault
  • AppKiller Assault
  • Memory Assault

而Watcher 表示都要在哪些地方搞破壞。一個是What,一個是Where。

Watcher支持多種類型,比如Spring 常用的組件:

  • @Controller
  • @RestController
  • @Service
  • @Repository
  • @Component

那你說都 What 和 Where 了,怎么沒有When?還真有Level就是。

chaos.monkey.enabled 用來打開和關閉ChaosMonkey。對應的配置中,除了設置Assault之外,不同的Assault也可以設置攻擊的頻率,配置項是chaos.monkey.assaults.level比如1代表每次請求都攻擊,10代表每十次請求攻擊一次。

chaos.monkey.assaults.latencyRangeStart 和chaos.monkey.assaults.latencyRangeEnd 這兩個配置項用來配置LatencyAssault這個攻擊的延遲時間值范圍。

如下圖所示,實際部署之后,每個ChaosMonkey會藏身于各個服務中,出其不意進行攻擊。

這下子配置和使用就明白了。我們再來看看實現。

2.實現原理

aaa實際我們想一下,前面配置Watcher,后面決定進行攻擊,那必須得是Watcher把它攔下來再攻擊,所以在Spring 里攔截常用的,就是它:AOP。

原理如圖所示:

以Controller 的攔截為例

  1. /** @author Benjamin Wilms */ 
  2. @Aspect 
  3. @AllArgsConstructor 
  4. @Slf4j 
  5. public class SpringControllerAspect extends ChaosMonkeyBaseAspect { 
  6.   private final ChaosMonkeyRequestScope chaosMonkeyRequestScope; 
  7.  
  8.   private MetricEventPublisher metricEventPublisher; 
  9.  
  10.   private WatcherProperties watcherProperties; 
  11.  
  12.   @Pointcut("within(@org.springframework.stereotype.Controller *)"
  13.   public void classAnnotatedWithControllerPointcut() {} 
  14.  
  15.   @Around( 
  16.       "classAnnotatedWithControllerPointcut() && allPublicMethodPointcut() && !classInChaosMonkeyPackage()"
  17.   public Object intercept(ProceedingJoinPoint pjp) throws Throwable { 
  18.  
  19.     if (watcherProperties.isController()) { 
  20.       log.debug("Watching public method on controller class: {}", pjp.getSignature()); 
  21.  
  22.       if (metricEventPublisher != null) { 
  23.         metricEventPublisher.publishMetricEvent( 
  24.             calculatePointcut(pjp.toShortString()), MetricType.CONTROLLER); 
  25.       } 
  26.  
  27.       MethodSignature signature = (MethodSignature) pjp.getSignature(); 
  28.  
  29.       chaosMonkeyRequestScope.callChaosMonkey(createSignature(signature)); 
  30.     } 
  31.     return pjp.proceed(); 
  32.   } 
  1. public void callChaosMonkey(String simpleName) { 
  2.     if (isEnabled() && isTrouble()) { 
  3.  
  4.       if (metricEventPublisher != null) { 
  5.         metricEventPublisher.publishMetricEvent(MetricType.APPLICATION_REQ_COUNT, "type""total"); 
  6.       } 
  7.  
  8.       // Custom watched services can be defined at runtime, if there are anyonly 
  9.       // these will be attacked! 
  10.       if (chaosMonkeySettings.getAssaultProperties().isWatchedCustomServicesActive()) { 
  11.         if (chaosMonkeySettings 
  12.             .getAssaultProperties() 
  13.             .getWatchedCustomServices() 
  14.             .contains(simpleName)) { 
  15.           // only all listed custom methods will be attacked 
  16.           chooseAndRunAttack(); 
  17.         } 
  18.       } else { 
  19.         // default attack if no custom watched service is defined 
  20.         chooseAndRunAttack(); 
  21.       } 
  22.     } 
  23.   } 

這里是 Controller AOP的代碼,基本沒門檻。先判斷 Controller 的開關是否打開,然后再看是否需要事件通知,緊接著,就是重頭戲,召喚 Chaos Monkey 來搞破壞了。

注意這里,從激活的幾種攻擊方式里,選擇一種去調用。

  1. private void chooseAndRunAttack() { 
  2.     List<ChaosMonkeyAssault> activeAssaults = 
  3.         assaults.stream().filter(ChaosMonkeyAssault::isActive).collect(Collectors.toList()); 
  4.     if (isEmpty(activeAssaults)) { 
  5.       return
  6.     } 
  7.     getRandomFrom(activeAssaults).attack();  // 注意這里,從激活的幾種攻擊方式里,選擇一種去調用。 
  8.  
  9.     if (metricEventPublisher != null) { 
  10.       metricEventPublisher.publishMetricEvent( 
  11.           MetricType.APPLICATION_REQ_COUNT, "type""assaulted"); 
  12.     } 
  13.   } 

延遲攻擊

比如LatencyAssault,就是要執行延遲攻擊,此時,會生成一個隨機的延遲時間

  1. public void attack() { 
  2.     Logger.debug("Chaos Monkey - timeout"); 
  3.  
  4.     atomicTimeoutGauge.set(determineLatency()); 
  5.  
  6.     // metrics 
  7.     if (metricEventPublisher != null) { 
  8.       metricEventPublisher.publishMetricEvent(MetricType.LATENCY_ASSAULT); 
  9.       metricEventPublisher.publishMetricEvent(MetricType.LATENCY_ASSAULT, atomicTimeoutGauge); 
  10.     } 
  11.  
  12.     assaultExecutor.execute(atomicTimeoutGauge.get()); 
  13.   } 

然后把這個值傳在線程池中進行這個時間的

sleep。 assaultExecutor.execute(atomicTimeoutGauge.get());

  1. public class LatencyAssaultExecutor implements ChaosMonkeyLatencyAssaultExecutor { 
  2.  public void execute(long durationInMillis) { 
  3.    try { 
  4.      Thread.sleep(durationInMillis); 
  5.   } catch (InterruptedException e) { 
  6.   } 

Exception攻擊

再來看Exception 攻擊,攻擊的時候,則是構造一個Exception 直接拋出

  1. @Override 
  2.   public void attack() { 
  3.     Logger.info("Chaos Monkey - exception"); 
  4.  
  5.     AssaultException assaultException = this.settings.getAssaultProperties().getException(); 
  6.     assaultException.throwExceptionInstance(); 
  7.   } 
  1. @SneakyThrows 
  2.   public void throwExceptionInstance() { 
  3.     Exception instance; 
  4.     try { 
  5.       Class<? extends Exception> exceptionClass = getExceptionClass(); 
  6.       if (arguments == null) { 
  7.         Constructor<? extends Exception> constructor = exceptionClass.getConstructor(); 
  8.         instance = constructor.newInstance(); 
  9.       } else { 
  10.         Constructor<? extends Exception> constructor = 
  11.             exceptionClass.getConstructor(this.getExceptionArgumentTypes().toArray(new Class[0])); 
  12.         instance = 
  13.             constructor.newInstance(this.getExceptionArgumentValues().toArray(new Object[0])); 
  14.       } 
  15.     } catch (ReflectiveOperationException e) { 
  16.       Logger.warn( 
  17.           "Cannot instantiate the class for provided type: {}. Fallback: Throw RuntimeException"
  18.           type); 
  19.       instance = new RuntimeException("Chaos Monkey - RuntimeException"); 
  20.     } 
  21.  
  22.     throw instance;  // 哈哈,直接拋出 
  23.   } 

KillApp 就直接執行應用的退出操作,System.exit.

本文轉載自微信公眾號「 Tomcat那些事兒」,可以通過以下二維碼關注。轉載本文請聯系 Tomcat那些事兒公眾號。

 

責任編輯:武曉燕 來源: Tomcat那些事兒
相關推薦

2016-08-04 13:42:25

ExcelExcel快捷鍵

2010-06-07 10:31:19

2011-05-07 13:39:35

2018-02-05 11:10:05

A站APP騰訊

2024-11-25 16:25:23

內網穿透網絡協議

2010-08-24 13:32:20

故障排除

2010-05-13 16:48:10

網絡故障

2010-08-24 11:13:47

2013-07-30 10:26:37

2013-11-24 20:01:57

2022-04-11 07:51:53

鴨子類型猴子補丁Python

2024-04-15 00:02:00

Java補丁技術

2020-05-12 15:20:04

ifswitchJava

2022-10-27 08:31:31

架構

2012-05-31 09:53:38

IT風云15年

2023-11-10 20:28:45

ChatGPT微軟OpenAI

2020-12-21 08:32:07

內存性能優化

2009-07-03 09:08:34

Mono微軟

2015-11-02 11:46:36

bug開發程序員

2017-08-24 08:18:03

WindowsLinux編輯器
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美日韩一区二区在线观看 | 欧美精品黄| 午夜精品一区二区三区三上悠亚 | 精品亚洲一区二区三区 | 国产一区二区影院 | 97精品超碰一区二区三区 | 日韩欧美国产精品一区 | 欧美精品久久久 | 免费国产视频在线观看 | 麻豆久久久久久久久久 | 午夜男人的天堂 | 久久99精品久久久久久噜噜 | 一区二区三区视频在线观看 | 91资源在线 | 亚洲欧美日韩国产 | 亚洲视频在线播放 | 久久国产精品久久久久久 | 亚洲日韩中文字幕一区 | 免费成人高清 | 国产成人aⅴ | 日韩在线一区二区 | 夜夜爽99久久国产综合精品女不卡 | 人妖无码 | 国产精品久久久久久久久久免费看 | 黄色成人免费在线观看 | 中文字幕亚洲视频 | 伦理二区| 一区视频 | 国产一二三区免费视频 | 国产一区二区三区四区 | 国产精品久久久久久久久久不蜜臀 | 日韩在线免费观看视频 | 亚洲精品免费观看 | 久久99精品久久久久久狂牛 | 日韩欧美网 | 亚洲嫩草| 激情在线视频网站 | 亚洲精品久久久久久久久久吃药 | 国产一区二区视频在线观看 | www.久久精品| 久久网站黄 |