pom引入依赖
org.springframework.cloud
spring-cloud-starter-netflix-hystrix
启动类添加注解
@EnableCircuitBreaker
A服务访问B服务,B服务不可用时,触发降级,转到某静态页面如提示"太拥挤了,请稍后再试"
新建 HystrixController 测试
package com.viki.order.controller;
import com.netflix.hystrix.contrib.javanica.annotation.DefaultProperties;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.util.Arrays;
/**
* @Author Sakura
* @Date 14/11/2019
**/
@RestController
public class HystrixController {
//超时配置
@HystrixCommand(fallbackMethod = "fallback") //回调方法名
@GetMapping("/getProductInfoList")
public String getProductInfoList() {
//使用RestTemplate 调用其他服务方法名
RestTemplate restTemplate = new RestTemplate();
return restTemplate.postForObject("http://127.0.0.1:8090/product/listForOrder",
Arrays.asList("10"),
String.class);
}
private String fallback() {
return "太拥挤了, 请稍后再试~~";
}
}
也可以指定默认方法
package com.viki.order.controller;
import com.netflix.hystrix.contrib.javanica.annotation.DefaultProperties;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.util.Arrays;
/**
* @Author Sakura
* @Date 14/11/2019
**/
@RestController
@DefaultProperties(defaultFallback = "defaultFallback")
public class HystrixController {
//超时配置
@HystrixCommand
@GetMapping("/getProductInfoList")
public String getProductInfoList() {
//使用RestTemplate 调用其他服务方法名
RestTemplate restTemplate = new RestTemplate();
return restTemplate.postForObject("http://127.0.0.1:8090/product/listForOrder",
Arrays.asList("10"),
String.class);
}
private String defaultFallback() {
return "默认提示:太拥挤了, 请稍后再试~~";
}
}
超时时间配置
默认超时时间是1秒,即在一秒钟之内无法收到返回的结果就会降级。而许多服务的运行时间确实长,所以需要更改超时时间
@HystrixCommand(commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000")
})
使用配置项设置
在方法加注解@HystrixCommand的前提下,配置文件中配置
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 1000
getProductInfoList:
execution:
isolation:
thread:
timeoutInMilliseconds: 3000
可使用default统一设置,也可以为具体的方法具体设置,如getProductInfoList
feign-hystrix的使用
配置添加
feign:
hystrix:
enabled: true
启动类添加扫描使Feign的包被扫描到
@ComponentScan(basePackages = "com.viki")
Feignclient的配置更改
@FeignClient(name = "product", fallback = ProductClient.ProductClientFallback.class)
public interface ProductClient {
@PostMapping("/product/listForOrder")
List listForOrder(@RequestBody List productIdList);
@PostMapping("/product/decreaseStock")
void decreaseStock(@RequestBody List decreaseStockInputList);
//降级回调函数
@Component
static class ProductClientFallback implements ProductClient{
@Override
public List listForOrder(List productIdList) {
return null;
}
@Override
public void decreaseStock(List decreaseStockInputList) {
}
}
}
Hystrix使用仓壁模式实现了线程池的隔离,会为每个HystrixCommand创建一个独立的线程池,各HystrixCommand之前互相隔离,不会相互影响,自动实现依赖隔离。
服务降级和依赖隔离是一体化实现的
@HystrixCommand(commandProperties = {
@HystrixProperty(name = "circuitBreaker.enabled", value = "true"), //设置熔断
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"), //在滚动时间窗口中断路器最小请求数
@HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000"), //休眠时间窗计时时间
@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "60") //失败率,高于此则打开断路器
})
主要有4个参数,以上都有注释
整体的效果是:在10秒钟之内,若请求数大于等于10次,其中失败率达到60%,即失败超过6次,熔断器就会开启。此时就会触发降级。
10秒钟结束后,自动发一次请求,若成功,则关闭熔断器,请求会正常;若失败,熔断器保持打开,服务降级。
package com.viki.order.controller;
import com.netflix.hystrix.contrib.javanica.annotation.DefaultProperties;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.util.Arrays;
/**
* @Author Sakura
* @Date 14/11/2019
**/
@RestController
@DefaultProperties(defaultFallback = "defaultFallback")
public class HystrixController {
//当断路器打开,服务不可用,休眠时间窗就开始计时,计时结束后,将熔断器设为半打开,尝试发一次请求,若请求成功,关闭熔断器;若失败,休眠时间窗继续计时
@HystrixCommand(commandProperties = {
@HystrixProperty(name = "circuitBreaker.enabled", value = "true"), //设置熔断
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"), //在滚动时间窗口中断路器最小请求数
@HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000"), //休眠时间窗计时时间
@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "60") //失败率,高于此则打开断路器
})
@GetMapping("/getProductInfoList")
public String getProductInfoList(@RequestParam("number") Integer number) {
if(number%2 == 0){
return "success";
}
RestTemplate restTemplate = new RestTemplate();
return restTemplate.postForObject("http://127.0.0.1:8090/product/listForOrder",
Arrays.asList("10"),
String.class);
}
private String defaultFallback() {
return "默认提示:太拥挤了, 请稍后再试~~";
}
}
请求必须携带number参数,若number为偶数,就直接访问成功,显示为success;若number为奇数,就调用服务,此时服务未启动,便失败触发降级。
http://localhost:8081/getProductInfoList?number=1 失败
http://localhost:8081/getProductInfoList?number=2 成功
不断访问失败链接,一直快速访问。此时在访问成功链接,也出现了降级,失败
Dashboard界面查看熔断
pom引入依赖
org.springframework.cloud
spring-cloud-starter-netflix-hystrix-dashboard
启动类添加注解
@EnableHystrixDashboard
打开上方提到的熔断器,启动项目后网页输入 http://localhost:8081/hystrix
URL输入 http://localhost:8081/actuator/hystrix.stream
Delay延时设置为2000
Title应用名称设置为Order
点击Monitor Stream
此时访问上述两个链接之一才会显示仪表盘