springcloud(五) Hystrix 降级,超时
生活随笔
收集整理的這篇文章主要介紹了
springcloud(五) Hystrix 降级,超时
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
?分布式系統(tǒng)中一定會(huì)遇到的一個(gè)問(wèn)題:服務(wù)雪崩效應(yīng)或者叫級(jí)聯(lián)效應(yīng)
什么是服務(wù)雪崩效應(yīng)呢?
在一個(gè)高度服務(wù)化的系統(tǒng)中,我們實(shí)現(xiàn)的一個(gè)業(yè)務(wù)邏輯通常會(huì)依賴多個(gè)服務(wù),比如:
商品詳情展示服務(wù)會(huì)依賴商品服務(wù),?價(jià)格服務(wù),?商品評(píng)論服務(wù).?調(diào)用三個(gè)依賴服務(wù)會(huì)共享商品詳情服務(wù)的線程池.?如果其中的商品評(píng)論服務(wù)不可用,?就會(huì)出現(xiàn)線程池里所有線程都因等待響應(yīng)而被阻塞,?從而造成服務(wù)雪崩.?如圖所示:
簡(jiǎn)單理解:?就是商品評(píng)論服務(wù)耗時(shí)假如是15S,那么在高并發(fā)的時(shí)候,其他服務(wù)很快就做出響應(yīng)并把線程回收但是商品評(píng)論服務(wù)需要10S。在這10S內(nèi)100個(gè)線程都會(huì)集中被消耗在商品評(píng)論服務(wù),就造成商品評(píng)論服務(wù)沒(méi)有線程對(duì)外提供服務(wù)了。
服務(wù)雪崩效應(yīng):因服務(wù)提供者的不可用導(dǎo)致服務(wù)調(diào)用者的不可用,并將不可用逐漸放大的過(guò)
程,就叫服務(wù)雪崩效應(yīng)
導(dǎo)致服務(wù)不可用的原因有幾點(diǎn):?程序Bug,大流量請(qǐng)求,硬件故障,緩存擊穿
【大流量請(qǐng)求】:在秒殺和大促開始前,如果準(zhǔn)備不充分,瞬間大量請(qǐng)求會(huì)造成服務(wù)提供者的不可用.
【硬件故障】:可能為硬件損壞造成的服務(wù)器主機(jī)宕機(jī),?網(wǎng)絡(luò)硬件故障造成的服務(wù)提供者的不可訪問(wèn).
【緩存擊穿】:一般發(fā)生在緩存應(yīng)用重啟,?緩存失效時(shí)高并發(fā),?所有緩存被清空時(shí),以及短時(shí)間內(nèi)大量緩存失效時(shí).?大量的緩存不命中,?使請(qǐng)求直擊后端,造成服務(wù)提供者超負(fù)荷運(yùn)行,引起服務(wù)不可用。
用戶重試/代碼邏輯重試,用戶重試:在服務(wù)提供者不可用后,?用戶由于忍受不了界面上長(zhǎng)時(shí)間的等待,會(huì)不斷刷新頁(yè)面甚至提交表單,或者是代碼有重試策略等等
那么,歸根結(jié)底導(dǎo)致雪崩效應(yīng)的最根本原因是:大量請(qǐng)求線程同步等待造成的資源耗盡
解決方案
1.?超時(shí)機(jī)制
2.?服務(wù)限流
3.?服務(wù)熔斷
4.?服務(wù)降級(jí)?
先啟動(dòng)Eureka 注冊(cè)中心,代碼就不上了,截圖:
?
?
order微服務(wù)工程
pom.xml :
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.tuling.cloud</groupId><artifactId>microservice-consumer-order-ribbon-hystrix-fallback</artifactId><version>0.0.1-SNAPSHOT</version><packaging>jar</packaging><name>06-ms-consumer-order-ribbon-hystrix-fallback</name><!-- 引入spring boot的依賴 --><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>1.5.9.RELEASE</version></parent><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><!-- <artifactId>spring-cloud-starter-eureka</artifactId> 依賴了 <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> --><!-- 此包包含了eurekaclient,ribbon--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency><!-- hystrix 依賴--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-hystrix</artifactId></dependency><!-- feign 依賴--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency></dependencies><!-- 引入spring cloud的依賴 --><dependencyManagement><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>Edgware.RELEASE</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><!-- 添加spring-boot的maven插件 --><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build> </project>OrderController.java:
package com.jiagoushi.cloud.study.user.controller;import com.jiagoushi.cloud.study.user.entity.User; import com.jiagoushi.cloud.study.user.feign.UserFeignClient; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate;import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;/*** 演示 user服務(wù)掛了超時(shí)和執(zhí)行請(qǐng)求超時(shí)*/ @RestController public class OrderController {private static final Logger logger = LoggerFactory.getLogger(OrderController.class);@Autowiredprivate UserFeignClient userFeignClient;@Autowiredprivate RestTemplate restTemplate;/*** Hystrix調(diào)用接口默認(rèn)1秒超時(shí),超時(shí)后會(huì)自動(dòng)執(zhí)行降級(jí)方法,可在文件配置,配置文件配置是全局的,* @HystrixCommand(fallbackMethod = "findByIdFallback") 注解也可以配置超時(shí)*/@HystrixCommand(fallbackMethod = "findByIdFallback") // 基于注解的hystrix 推薦使用@GetMapping("/user/{id}")public User findById(@PathVariable Long id) {logger.info("================請(qǐng)求用戶中心接口==============");return this.restTemplate.getForObject("http://microservice-provider-user/" + id, User.class);}// 降級(jí)的方法public User findByIdFallback(Long id) { User user = new User();user.setId(-1L);user.setName("降級(jí)用戶");return user;}}ConsumerOrderApplication.java:
package com.jiagoushi.cloud.study;import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.cloud.netflix.feign.EnableFeignClients; import org.springframework.context.annotation.Bean; import org.springframework.web.client.RestTemplate;@EnableDiscoveryClient @SpringBootApplication @EnableCircuitBreaker//開啟斷路器功能 public class ConsumerOrderApplication {@Bean@LoadBalancedpublic RestTemplate restTemplate() {return new RestTemplate();}public static void main(String[] args) {SpringApplication.run(ConsumerOrderApplication.class, args);} }
?
user微服務(wù):
package com.tuling.cloud.study.controller;import java.util.Random;import org.apache.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cloud.client.serviceregistry.Registration; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController;import com.tuling.cloud.study.entity.User; import com.tuling.cloud.study.repository.UserRepository;@RestController public class UserController {private final Logger logger = Logger.getLogger(getClass());@Autowiredprivate UserRepository userRepository;@Autowiredprivate Registration registration;@GetMapping("/{id}")public User findById(@PathVariable Long id) throws Exception {logger.info("用戶中心接口:查詢用戶"+ id +"信息");//模擬系統(tǒng)執(zhí)行速度很慢的情況Thread.sleep(5000);User findOne = userRepository.findOne(id);return findOne;}@GetMapping("/getIpAndPort")public String findById() {return registration.getHost() + ":" + registration.getPort();} }user微服務(wù)在停止或者阻塞5s 的時(shí)候,order服務(wù)會(huì)走降級(jí)方法
如何想修改接口超時(shí)間時(shí)間可以在order調(diào)用方修改yml 文件:
server:port: 9010 spring:application:name: microservice-consumer-order eureka:client:serviceUrl:defaultZone: http://localhost:8761/eureka/ instance:prefer-ip-address: true hystrix:command:default:execution:isolation:thread:timeoutInMilliseconds: 3000 #命令執(zhí)行超時(shí)時(shí)間,默認(rèn)1000ms,就是調(diào)接口的響應(yīng)時(shí)間超過(guò)3S就執(zhí)行降級(jí),不管提供者是否掛機(jī)還是延遲超過(guò)時(shí)間就走降級(jí)?
轉(zhuǎn)載于:https://www.cnblogs.com/smallFishs/p/10600517.html
總結(jié)
以上是生活随笔為你收集整理的springcloud(五) Hystrix 降级,超时的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: flask 定义数据库关系(一对多) -
- 下一篇: [Lintcode]136. Palin