springcloud7---hystrix
目前使用eureka server完成了服务注册和服务发现,ribbon完成了客户端负载均衡。如果服务提供者的响应很慢那么服务消费者会强制等待,一直等到http请求超时,如果服务消费者还是其他的服务提供者,那么就会产生级联的雪崩。
超时机制:等待几秒还是没响应,就直接返回了。
断路器模式:A如果有大量的超时,B一直去请求A是没有意义的,不再去请求A直接返回异常。保证B不会拖死。
断路器全开(B不去请求A),断路器半开(过了10分钟,B猜测A是不是好了,留一小部分流量去请求A大部分还是直接抛异常,发现A响应时间/失败率达标了就把断路器关闭)
容错:雪崩效应。CD的微服务调了B的接口,B又调了A的接口。A宕机了,B里面就会堆积线程,接着B宕机了,CD里面堆积线程,接着CD宕机了。
5秒钟失败20次就打开。
实践:
1.监控:判断A是不是挂掉了(有一个阈值,请求多少次有多少次失败了)。
2.断路器状态:打开,关闭,半开。
3.分流:留小部分流量尝试请求A服务。
4.自我修复:断路器状态切换
超时机制:高并发下,A挂了,设置超时机制,内网传输很快。
断路器:B调用A出现了异常,并不会立即扔到断路器里面去,比如达到60%都是异常状态,就会丢到断路器里面去,B就不请求A了。
断路器打开了,过一段时间看A微服务是否已经修复了,就小部分流量去请求(判断是否达到阈值),如果还是失败就继续打开(继续直接返回),如果好了就关闭。
ribbon整合hystrix:
package com.itmuch.cloud; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; import org.springframework.context.annotation.Bean; import org.springframework.web.client.RestTemplate; @SpringBootApplication @EnableEurekaClient @EnableCircuitBreaker //启用断路器 public class ConsumerMovieRibbonApplication { @Bean @LoadBalanced //ribbon的客户端负载均衡 public RestTemplate restTemplate() { return new RestTemplate(); } public static void main(String[] args) { SpringApplication.run(ConsumerMovieRibbonApplication.class, args); } }
package com.itmuch.cloud.controller; 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.itmuch.cloud.entity.User; import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; @RestController public class MovieController { @Autowired private RestTemplate restTemplate; //http://localhost:8010/movie/1 //查看hystrix的状态http://localhost:8010/hystrix.stream //第一次会进fallbackMethod方法,后面走microservice-provider-user。因为Hystrix默认超时时间是1秒。 //microservice-provider-user挂了就进fallbackMethod @GetMapping("/movie/{id}") @HystrixCommand(fallbackMethod = "findByIdFallback") //参数和返回值类型一样,当用户微服务挂了就走fallbackMethod。进入了fallbackMethod不代表断路器打开。 public User findById(@PathVariable Long id) { return this.restTemplate.getForObject("http://microservice-provider-user/simple/" + id, User.class); } public User findByIdFallback(Long id) { User user = new User(); user.setId(0L); return user; } }
package com.itmuch.cloud.entity; import java.math.BigDecimal; public class User { private Long id; private String username; private String name; private Short age; private BigDecimal balance; public Long getId() { return this.id; } public void setId(Long id) { this.id = id; } public String getUsername() { return this.username; } public void setUsername(String username) { this.username = username; } public String getName() { return this.name; } public void setName(String name) { this.name = name; } public Short getAge() { return this.age; } public void setAge(Short age) { this.age = age; } public BigDecimal getBalance() { return this.balance; } public void setBalance(BigDecimal balance) { this.balance = balance; } }
spring: application: name: microservice-consumer-movie-ribbon-with-hystrix server: port: 8010 eureka: client: healthcheck: enabled: true serviceUrl: defaultZone: http://user:password123@localhost:8761/eureka instance: prefer-ip-address: true hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 5000
<?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>
<artifactId>microservice-consumer-movie-ribbon-with-hystrix</artifactId>
<packaging>jar</packaging>
<parent>
<groupId>com.itmuch.cloud</groupId>
<artifactId>microservice-spring-cloud</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<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.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- 添加依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
</dependencies>
</project>
package com.itmuch.cloud.controller; 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.itmuch.cloud.entity.User; import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty; @RestController public class MovieController { @Autowired private RestTemplate restTemplate; @GetMapping("/movie/{id}") @HystrixCommand(fallbackMethod = "findByIdFallback", commandProperties = @HystrixProperty(name = "execution.isolation.strategy", value = "SEMAPHORE")) //配置上面之后findById方法和fallbackMethod的方法在一个线程里面 public User findById(@PathVariable Long id) { return this.restTemplate.getForObject("http://microservice-provider-user/simple/" + id, User.class); } public User findByIdFallback(Long id) { User user = new User(); user.setId(0L); return user; } }
<!-- 使用http://localhost:8010/health要有这个依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>