日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

面试官:了解雪崩效应吗?了解Hystrix吗?怎么解决雪崩效应吗?(大型社死现场,教你运筹帷幄之中)

發(fā)布時(shí)間:2024/10/5 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 面试官:了解雪崩效应吗?了解Hystrix吗?怎么解决雪崩效应吗?(大型社死现场,教你运筹帷幄之中) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

上篇我們模擬了高并發(fā)場景下,系統(tǒng)資源被耗盡導(dǎo)致其他接口訪問非常之慢。至此,這篇給出了五種解決方案(當(dāng)然這個(gè)是次要的,主要還是理解原理)
上篇地址:https://blog.csdn.net/Kevinnsm/article/details/117302197?spm=1001.2014.3001.5501

文章目錄

  • 一、雪崩效應(yīng)是什么?
  • 二、什么是Hystrix?
  • 三、Hystrix用來解決什么問題?
  • 四、雪崩效應(yīng)的五大解決方案
    • 1、請求緩存
      • Ⅰ、redis安裝
      • Ⅱ、代碼配置
      • Ⅲ、啟動(dòng)測試接口
      • Ⅳ、模擬2500訪問量高并發(fā)測試
    • 2、請求合并
    • 3、服務(wù)隔離
      • 1、線程隔離
      • 2、信號(hào)量隔離
    • 4、服務(wù)熔斷
    • 5、服務(wù)降級(jí)
  • 五、總結(jié)


一、雪崩效應(yīng)是什么?

在微服務(wù)項(xiàng)目當(dāng)中,服務(wù)之間的調(diào)用是錯(cuò)綜復(fù)雜的,服務(wù)之間相互依賴;一旦某個(gè)服務(wù)發(fā)生了問題,那么將可能出現(xiàn)鏈?zhǔn)椒磻?yīng),導(dǎo)致整個(gè)系統(tǒng)崩潰,這就是所謂的雪崩效應(yīng)
(大白話說就是A服務(wù)依賴(調(diào)用)B服務(wù),B服務(wù)依賴C服務(wù),一旦C服務(wù)出了問題,那么A、B服務(wù)將一直處于阻塞狀態(tài))

二、什么是Hystrix?

Hystrix是由Netflix開源的一個(gè)服務(wù)隔離組件,通過服務(wù)隔離來避免由于依賴延遲、異常,引起資源耗盡導(dǎo)致系統(tǒng)不可用的解決方案。

Hystrix地址:https://github.com/Netflix/Hystrix

三、Hystrix用來解決什么問題?

服務(wù)之間錯(cuò)綜復(fù)雜的調(diào)用,如果某一個(gè)服務(wù)出現(xiàn)了問題,那么就會(huì)出現(xiàn)我們前面介紹的雪崩效應(yīng)問題。而Hystrix為這個(gè)服務(wù)故障提供了一套解決方案。
例如:

1、請求緩存
2、請求合并
3、服務(wù)隔離
4、服務(wù)熔斷
5、服務(wù)降級(jí)

當(dāng)你回答到這,面試官估計(jì)會(huì)對你嘿嘿一笑,說:來做CTO吧




上篇我們模擬了高并發(fā)場景下,系統(tǒng)資源被耗盡導(dǎo)致其他接口訪問非常慢。至此,這篇給出了五種解決方案

演示代碼免費(fèi)下載地址:https://download.csdn.net/download/Kevinnsm/19098746



四、雪崩效應(yīng)的五大解決方案

1、請求緩存

Ⅰ、redis安裝

此處為了方便,我直接在windows上進(jìn)行快速安裝

另外我也使用了Reids Desktop Manager(圖形化界面),這個(gè)現(xiàn)在收費(fèi)了,不過對于我們來說,肯定白嫖!

Ⅱ、代碼配置

在consumer模塊配置RedisConfig文件

@Configuration public class RedisConfig { // 重寫RedisTemplate序列@Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {RedisTemplate<String, Object> template = new RedisTemplate<>(); // 為String類型key設(shè)置序列化器template.setKeySerializer(new StringRedisSerializer()); // 為String類型value設(shè)置序列化器template.setValueSerializer(new GenericJackson2JsonRedisSerializer()); // 為Hash類型key設(shè)置序列化器template.setHashKeySerializer(new StringRedisSerializer()); // 為Hash類型Value設(shè)置序列化器template.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());template.setConnectionFactory(redisConnectionFactory);return template;} // 重寫Cache序列public RedisCacheManager redisCacheManager(RedisTemplate redisTemplate) {RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(redisTemplate.getConnectionFactory());RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig() // 設(shè)置默認(rèn)時(shí)間為30秒.entryTtl(Duration.ofMinutes(30)) // 設(shè)置key和value的序列化.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisTemplate.getKeySerializer())).serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(redisTemplate.getValueSerializer()));return new RedisCacheManager(redisCacheWriter, redisCacheConfiguration);} }

redis配置

在啟動(dòng)類上開啟緩存

在遠(yuǎn)程調(diào)用接口上開啟緩存配置(第一個(gè)接口和第三個(gè)接口)
具體不明白的可以參考上一篇

@FeignClient(value = "service-provider") public interface ProductService {@GetMapping(value = "/product/list")@Cacheable(cacheNames = "orderService:product:list")List<Product> selectProductList();@GetMapping(value = "/product/byIds")List<Product> selectProductListByIds(@RequestBody List<Integer> ids);@GetMapping(value = "/search/{id}")@Cacheable(cacheNames = "orderService:product:single", key = "#id")Product selectProductById(@PathVariable("id") Integer id); }

Ⅲ、啟動(dòng)測試接口

啟動(dòng)這四個(gè)服務(wù)訪問http://localhost:9090/select/1
由于我們在第一個(gè)消費(fèi)接口的服務(wù)提供類的接口處暫停了兩秒,所以當(dāng)我們訪問時(shí),第一次會(huì)耗時(shí)>2s,后面就會(huì)非常快了,因?yàn)閺木彺孀x取了嘛!

之后我們從RedisManager查看結(jié)果

Ⅳ、模擬2500訪問量高并發(fā)測試

和上一篇操作一樣:https://blog.csdn.net/Kevinnsm/article/details/117302197?spm=1001.2014.3001.5501

此時(shí)我們可以看到結(jié)果

為什么2500個(gè)請求很快就完成了呢?究其原因還是緩存的功勞嘛!一般情況下從第二個(gè)請求開始就一直從緩存中取的數(shù)據(jù)。雖然我暫停了兩秒,但那和緩存沒毛線關(guān)系(就第一次走那個(gè)路線)。


在那2500個(gè)請求的過程中,訪問第三個(gè)接口,有可能2499個(gè)請求都找緩存去了,然后就不存在線程資源競爭嘛!當(dāng)然就很快了




2、請求合并

什么是請求合并?
在高并發(fā)場景下,一個(gè)請求就需要一個(gè)線程進(jìn)行處理;一旦訪問量很大,那么就會(huì)浪費(fèi)很多的資源;所以引入了請求合并,將多個(gè)請求進(jìn)行拼接,只進(jìn)行一次訪問即可。

hystrix依賴

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-hystrix</artifactId><version>2.2.8.RELEASE</version></dependency>


這兩個(gè)注解配置一下即可

@HystrixCollapser(batchMethod = "searchOrderById", //合并請求方法scope = com.netflix.hystrix.HystrixCollapser.Scope.GLOBAL, //請求方式collapserProperties = {//請求的最大等待時(shí)間 - 30s ,默認(rèn)20s@HystrixProperty(name = "timeDelayInMilliseconds", value = "30"),//最多合并多少個(gè)請求 - 200個(gè)@HystrixProperty(name = "maxRequestsInBatch", value = "200")})

注意啟動(dòng)類上需要開啟Hystrix熔斷。



3、服務(wù)隔離

1、線程隔離

什么是線程隔離?
我們以前沒有使用線程隔離的項(xiàng)目的所有接口都運(yùn)行在一個(gè)ThreadPool中,一旦某一個(gè)接口壓力過大就會(huì)造成資源耗盡,從而導(dǎo)致其他接口的正常使用;如使用了線程隔離技術(shù),我們可以將某個(gè)實(shí)例接口單獨(dú)使用ThreadPool隔離起來,一旦它出現(xiàn)故障,不會(huì)影響其他接口的使用,如下圖詳解兩種方式


異步,提高了系統(tǒng)的并發(fā)性;但是如果隔離的實(shí)例過多,還是推薦使用這種方式

使用注解方式實(shí)現(xiàn)線程隔離,注解方式和配置方式各有優(yōu)缺點(diǎn)

配置方式可以在服務(wù)在線時(shí)進(jìn)行修改配置,但是一個(gè)實(shí)例需要一個(gè)配置類,一旦需要隔離較多的實(shí)例就要寫很多類
注解方式雖然很方便,但是不能在服務(wù)在線時(shí)進(jìn)行修改配置

@Service public class OrderServiceImpl implements OrderService {@Autowiredprivate ProductService productService;@Override@HystrixCommand(groupKey = "consumer-product-pool-1", //服務(wù)名稱commandKey = "selectOrderById", //接口名稱,默認(rèn)方法名threadPoolKey = "consumer-product-pool-1", //線程池名稱,相同名稱使用一個(gè)線程此commandProperties = {//超時(shí)時(shí)間。默認(rèn)1000ms@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "5000")},threadPoolProperties = {//線程大小@HystrixProperty(name = "coreSize", value = "6"),//隊(duì)列等待閾值@HystrixProperty(name = "maxQueueSize", value = "100"),//線程存活時(shí)間@HystrixProperty(name = "keepAliveTimeMinutes", value = "30"),//超出隊(duì)列等待閾值執(zhí)行拒絕策略@HystrixProperty(name = "queueSizeRejectionThreshold", value = "100")})public Order selectOrderById(Integer id) {return new Order(id, "one", "china", 199D,productService.selectProductList());}private List<Product> selectProductListFallback() {return Arrays.asList(new Product(1, "默認(rèn)數(shù)據(jù)1", 9, 100D),new Product(2, "默認(rèn)數(shù)據(jù)2", 15, 200D),new Product(3, "默認(rèn)數(shù)據(jù)3", 13, 300D));}@Overridepublic Order queryOrderById(Integer id) {return new Order(id, "two", "nyist", 11D, productService.selectProductListByIds(Arrays.asList(1, 2)));}@Override@HystrixCommand(groupKey = "consumer-product-pool-2", //服務(wù)名稱commandKey = "searchOrderById", //接口名稱,默認(rèn)方法名threadPoolKey = "consumer-product-pool-1", //線程池名稱,相同名稱使用一個(gè)線程此commandProperties = {//超時(shí)時(shí)間。默認(rèn)1000ms@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "5000")},threadPoolProperties = {//線程大小@HystrixProperty(name = "coreSize", value = "3"),//隊(duì)列等待閾值@HystrixProperty(name = "maxQueueSize", value = "100"),//線程存活時(shí)間@HystrixProperty(name = "keepAliveTimeMinutes", value = "2"),//超出隊(duì)列等待閾值執(zhí)行拒絕策略@HystrixProperty(name = "queueSizeRejectionThreshold", value = "100")})public Order searchOrderById(Integer id) {return new Order(id, "three", "china", 110D, Arrays.asList(productService.selectProductById(3)));} }

在tomcat進(jìn)行配置系統(tǒng)最多只能使用10個(gè)線程,方便查看結(jié)果

使用JMeter進(jìn)行測試



由于我在注解中配置了該接口每次只能使用6個(gè)線程進(jìn)行處理,可以發(fā)現(xiàn)每次會(huì)打印6個(gè)日志。(我暫停兩秒的那個(gè)接口)

2、信號(hào)量隔離

什么是信號(hào)量隔離?
信號(hào)量有一個(gè)大小,一旦請求的線程數(shù)超過了這個(gè)信號(hào)量的大小,直接獲取失敗做fallback處理。獲取到信號(hào)量的線程繼續(xù)訪問,訪問完成后歸還信號(hào)量;當(dāng)然可以通過上調(diào)信號(hào)量的大小,來提高系統(tǒng)的性能

同步調(diào)用,信號(hào)量是不能用于網(wǎng)絡(luò)環(huán)境的;多用于本地環(huán)境。

@HystrixCommand(commandProperties = { // 超時(shí)時(shí)間@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "5000"),//信號(hào)量隔離@HystrixProperty(name = HystrixPropertiesManager.EXECUTION_ISOLATION_STRATEGY, value = "SEMAPHORE"),//信號(hào)量最大并發(fā)@HystrixProperty(name = HystrixPropertiesManager.EXECUTION_ISOLATION_SEMAPHORE_MAX_CONCURRENT_REQUESTS, value = "10")})public Order selectOrderById(Integer id) {return new Order(id, "one", "china", 199D,productService.selectProductList());}

4、服務(wù)熔斷

為什么要進(jìn)行服務(wù)熔斷?
在微服務(wù)架構(gòu)中,可能由于某種原因?qū)е路?wù)出現(xiàn)了過載現(xiàn)象,有可能引發(fā)整個(gè)系統(tǒng)發(fā)生故障;為防止這種情況發(fā)生引入服務(wù)熔斷技術(shù);可以將熔斷理解為我們生活中的閘刀。

Hystrix熔斷技術(shù)原理:

服務(wù)模塊業(yè)務(wù)類代碼

為了模擬服務(wù)熔斷,我手動(dòng)加入異常,使其開啟熔斷。
訪問id=1,下面會(huì)報(bào)運(yùn)行時(shí)異常,然后就會(huì)走fallback函數(shù)。

@HystrixCommand(commandProperties = {//10s內(nèi)請求大于10個(gè)就啟動(dòng)熔斷器,默認(rèn)20個(gè)@HystrixProperty(name = HystrixPropertiesManager.CIRCUIT_BREAKER_REQUEST_VOLUME_THRESHOLD, value = "10"),//請求錯(cuò)誤率大于50%就啟動(dòng)熔斷器@HystrixProperty(name = HystrixPropertiesManager.CIRCUIT_BREAKER_ERROR_THRESHOLD_PERCENTAGE, value = "50"),//熔斷5s進(jìn)行重試請求, 默認(rèn)5s@HystrixProperty(name = HystrixPropertiesManager.CIRCUIT_BREAKER_SLEEP_WINDOW_IN_MILLISECONDS, value = "5000")},fallbackMethod = "selectProductListFallback")public Order queryOrderById(Integer id) {if (id ==1 )throw new RuntimeException("id=1的信息異常,開始進(jìn)行服務(wù)熔斷處理!");return new Order(id, "two", "nyist", 11D, productService.selectProductListByIds(Arrays.asList(1, 2)));}

服務(wù)熔斷異常執(zhí)行函數(shù)fallback

private Order selectProductListFallback(Integer id) {System.out.println("------------》調(diào)用了默認(rèn)數(shù)據(jù)000《---------------");return new Order(1, "系統(tǒng)故障,默認(rèn)數(shù)據(jù)", "開啟熔斷", 11D, Arrays.asList(new Product(1,"vim", 2, 11D)));}



可以發(fā)現(xiàn)確實(shí)是走的fallback函數(shù),服務(wù)熔斷模擬成功!



5、服務(wù)降級(jí)

如何理解服務(wù)降級(jí)?
服務(wù)降級(jí)是為了保留核心業(yè)務(wù),舍棄邊緣業(yè)務(wù)。

@HystrixCommand(fallbackMethod = "selectProductListFallback")

進(jìn)行服務(wù)降級(jí)只需添加這一行代碼即可,前面服務(wù)熔斷已經(jīng)使用過。

有幾種觸發(fā)條件
1、發(fā)生異常
2、調(diào)用超時(shí)
3、超出服務(wù)隔離設(shè)置的上限
4、開啟服務(wù)熔斷

五、總結(jié)

到這里基本就結(jié)束了,這里講述的都是基于Hystrix的雪崩解決方案,當(dāng)然其他技術(shù)也能實(shí)現(xiàn),比如Feign實(shí)現(xiàn)熔斷降級(jí)等等。雖然Hystrix已經(jīng)進(jìn)入維護(hù)之中,但是這個(gè)組件真的香,我一直都認(rèn)為學(xué)習(xí)不能什么熱就學(xué)什么,為什么不去探究一下其中的奧妙呢?深入學(xué)習(xí)之后我發(fā)現(xiàn)

溜了溜了!

與50位技術(shù)專家面對面20年技術(shù)見證,附贈(zèng)技術(shù)全景圖

總結(jié)

以上是生活随笔為你收集整理的面试官:了解雪崩效应吗?了解Hystrix吗?怎么解决雪崩效应吗?(大型社死现场,教你运筹帷幄之中)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。