推荐看大神的
Hystrix 是一个用来处理分布式系统的延迟和容错的开源库,例如在分布式环境下,服务与服务之间相互依赖不可避免出现调用失败问题,超时,异常等等,通过 Hystrix 保证一个服务出现问题时不影响其他服务,避免级联故障,提高分布式系统的弹性
Hystrix 主要作用: 服务降级, 服务熔断, 提供接近实时的监控
服务降级: 当服务不可用时(例如服务等待,服务报错等等)返回一个错误提示给用户,用户不用继续等待,提供用户体验,使用fallback返回当前服务不可用的提示,服务熔断与服务降级一般会一块使用,当拒绝请求后给出提示,例如请稍后再试(适用于高并发,防止服务器的血崩效应,服务器挂掉)
服务熔断: 设置一个限制,当服务请求超过限制时,拒绝请求,调用服务降级方法给用户提示信息, ,比如最多只能同时访问100个请求,超出请求放入缓存队列中,队列已满时,拒绝访问,并且调用链路会有一个自动恢复过程,在恢复期内请求正常了可能还是会走降级方法,要等到关闭熔断
服务隔离: 通过服务熔断降级,实现服务隔离的效果,服务与服务
服务限流: 防止恶意请求工具,服务限流,服务熔断,服务降级,放到一块是一条顺序性的执行流程
Hystrix 降级熔断底层可以通过线程池或信号量两种方式来实现,可以通过编码或注解两种方式来进行具体实现
- 项目中引入 Hystrix 依赖
- 项目启动类添加 @EnableHystrix 修饰开启 Hystrix
- 设置指定需要降级处理的方法,提供降级方法
- 服务消费方调用服务提供方降级时 yml 文件中配置开启 Feign 客户端的 Hystrix 功能
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
server:
port: 80 #当前服务端口号
spring:
application:
name: cloud-feign-hystix-order-service #当前服务名称
eureka:
client:
register-with-eureka: true
fetch-registry: true
service-url:
#eureka 注册中心访问连接,集群环境多个注册地址
defaultZone: http://127.0.0.1:7001/eureka,http://127.0.0.1:7002/eureka
instance:
instance-id: order80 #配置当前服务向eureka注册中心注册时显示的服务器主机名称
prefer-ip-address: true #配置在开发人员直接访问eureka服务器时显示当前eureka上注册的服务的ip
lease-renewal-interval-in-seconds: 1 #指定定时向eureka注册中心发送代表当前服务心跳包的时间默认30秒
lease-expiration-duration-in-seconds: 2 # Eureka 接收到当前服务最后一次发送代表正常心跳包的等待时间,超过则将当前服务在 Eureka 上踢除
#=====================Feign===========================================
#开启 Feign 接口调用 Hystrix功能
feign:
hystrix:
enabled: true
#超时时间配置
ribbon:
ReadTimeout: 5000 #当前服务消费方调用服务提供方,建立连接超时时间,默认1秒超过报错
ConnectTimeout: 5000 #当前服务消费方与服务提供方建立连接后调用服务接口读取资源的时间
#配置 Feign 日志功能
logging:
level:
#表示 com.order.feignService.PaymentFeignService 接口中的方法执行,被 Feign 监控,记录日志
com.order.feignService.PaymentFeignService: debug
#=====================Feign end===========================================
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableFeignClients
@EnableHystrix //开启Hystrix
public class OrderFeignHystixMain80 {
public static void main(String[] args) {
SpringApplication.run(OrderFeignHystixMain80.class,args);
}
}
@DefaultProperties(defaultFallback = “降级方法名称”) 注解用来修饰类, defaultFallback 属性值设置为指定的降级方法
@HystrixCommand 修饰该类中需要进行降级处理的方法,当该类中被该注解修饰的方法执行时,触发降级条件会自动执行 defaultFallback 中指定的方法
该方式存在的缺点: 不能对指定方法进行指定降级处理,并且降级方法的入参出参要与实际的方法一一对应,否则可能会报错找不到该降级方法
代码示例: 该方法中的 getException() 方法或 getException2() 方法执行报错会执行降级方法 defaultFallBack()
import com.common.result.JsonResult;
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 com.order.feignServer.PaymentFeignServer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping(value = "/consumer")
@DefaultProperties(defaultFallback = "defaultFallBack")
public class OrderController {
@Autowired
private PaymentFeignServer paymentFeignServer;
@GetMapping(value = "/getException")
@HystrixCommand
public JsonResult getException(){
return paymentFeignServer.getException();
}
@GetMapping(value = "/getException2")
@HystrixCommand
public JsonResult getException2(){
int i =1/0;
return paymentFeignServer.getException();
}
public JsonResult defaultFallBack(){
return JsonResult.successResult("默认的降级方法执行");
}
}
@DefaultProperties( defaultFallback = "defaultFallBack"
commandProperties={
// 请求必须达到以下参数以上才有可能触发,也就是10秒內发生连续调用的最小参数
@HystrixProperty(name="circuitBreaker.requestVolumeThreshold", value="10"),
// 请求到达requestVolumeThreshold 上限以后,调用失败的请求百分比
@HystrixProperty(name="circuitBreaker.errorThresholdPercentage", value="75")}
)
@GetMapping(value = "/timeout")
@HystrixCommand(fallbackMethod ="fallBack", commandProperties = {
@HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds", value = "4000")
})
public JsonResult hystixGetValTimeout(){
return paymentFeignServer.hystixGetValTimeout();
}
public JsonResult fallBack(){
return JsonResult.successResult("指定的降级方法执行");
}
@HystrixCommand(ignoreExceptions = {RuntimeException.class},
fallbackMethod = "buildFallbackTestException")
import com.common.result.JsonResult;
import com.order.fallback.PaymentFallBackService;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.concurrent.TimeUnit;
//该接口表示:在注册中心获取名为"CLOUD-PROVIDER-HYSTIX-PAYMENT" 的服务提供方的调用地址
//本地Ribbon 负载后可以调用该服务中请求路径为"/getValOk","/timeout","/getException" 的方法
//并且通过 fallback 属性指定降级类为 PaymentFallBackService, 该类继承了该接口,重写该接口中
//的所有抽象方法,就是对应调用服务时触发降级自动执行的降级方法
@Component
@FeignClient(value = "CLOUD-PROVIDER-HYSTIX-PAYMENT", fallback = PaymentFallBackService.class)
public interface PaymentFeignServer {
@RequestMapping(value = "/getValOk", method = RequestMethod.GET)
public JsonResult hystixGetValOk();
@RequestMapping(value = "/timeout", method = RequestMethod.GET)
public JsonResult hystixGetValTimeout();
@RequestMapping(value = "/getException", method = RequestMethod.GET)
public JsonResult getException();
}
import com.common.result.JsonResult;
import com.order.feignServer.PaymentFeignServer;
import org.springframework.stereotype.Component;
@Component
public class PaymentFallBackService implements PaymentFeignServer {
@Override
public JsonResult hystixGetValOk() {
return JsonResult.successResult("执行 /getValOk 请求异常 fallBack 降级");
}
@Override
public JsonResult hystixGetValTimeout() {
return JsonResult.successResult("执行 /timeout 请求异常 fallBack 降级");
}
@Override
public JsonResult getException() {
return JsonResult.successResult("执行 /getException 请求异常 fallBack 降级");
}
}
推荐看大神的
//设置隔离策略"THREAD"为线程池方式(默认),"SEMAPHORE"为信号量方式
@HystrixProperty(name="execution.isolation.strategy",value="THREAD"),
//线程池方式设置线程微调
@HystrixProperty(name = "coreSize",value="30"),
@HystrixProperty(name="maxQueueSize", value="10")},
//当隔离策略为信号量方式时,设置最大并发数量
@HystrixProperty(name="execution.isolation.semaphore.maxConcurrentRequests",value = "10"),
//是否开启超时时间
@HystrixProperty(name="execution.timeout.enabled",value="true"),
//方法调用超时时间
@HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds", value = "3000"),
//执行超时时是否中断
@HystrixProperty(name = "execution.isolation.thread.interruptOnTimeout",value = "true"),
//执行被取消时候是否中断
@HystrixProperty(name = "execution.isolation.thread.interruptOnCancel",value = "true"),
//设置回调降级方法执行的最大并发数
@HystrixProperty(name = "fallback.isolation.semaphore.maxConcurrentRequests",value = "10"),
//服务降级是否启动,是否执行回到函数
@HystrixProperty(name = "fallback.enabled",value = "true"),
@HystrixProperty(name="circuitBreaker.forceOpen",value = "false"),//强制开启断路器
@HystrixProperty(name="circuitBreaker.enabled", value = "true"), //是否开启断路器
@HystrixProperty(name="circuitBreaker.requestVolumeThreshold", value="20"),//请求次数
@HystrixProperty(name="circuitBreaker.sleepWindowInMilliseconds", value="10000"),//时间窗口期
@HystrixProperty(name="circuitBreaker.errorThresholdPercentage", value = "50")//失败率达到多少跳闸