springcloud----服务熔断、降级、限流--之--Hystrix-服务降级

服务降级、服务熔断、服务限流、服务隔离

分布式面临的问题:

负责的分布式体系结构中应用程序有数十个依赖 ,可能会形成 调用链(一个阻塞,全体等待) , 引起服务雪崩

Hystrix

是一个用于处理分布式系统的延迟容错的开源库, 在分布式系统中,许多不可避免的调用会失败, 比如超时,一场等。Hystrix 能够保证在一个依赖出现问题的情况下,不会导致整体服务的失败、避免级联故障、以提高分布式系统的弹性
断路器” 本身是一种开关装置,当某个服务单元发生故障之后,通过断路器的故障监控(类似保险熔断),向调用方返回一个符合预期的、可处理的备选响应(FallBack) 而不是时间的等待或抛出调用方法处理异常,这样就保证了服务调用方的线程不会长时间,不必要地占用,从而避免了故障在分布式系统无线的蔓延,从而导致雪崩效应

重要概念

  • 服务降级(fallback) :服务器忙,请稍后再试,等友好的提示
    哪些情况会出现服务降级
    • 程序异常、超时、服务熔断触发服务降级、线程池/信号量打满也会导致服务降级
  • 服务熔断(break): 类比保险丝达到最大服务访问,直接拒绝。然后调用服务降级的方法返回友好提示
    服务的降级 -> 进而熔断 -> 恢复调用链路
  • 服务限流(flowlimit): 秒杀、高并发等操作,排队一秒N个有序进入 (Alibaba Sentiel 中详解)

解决场景

  1. 服务超时(前台显示转圈)
  2. 出错(宕机或者程序运行出错)

解决

1.对方服务超时了,调用者不能一直死等,必须有服务降级
2. 对方服务器down机了,调用者不能卡死等待,必须有服务降级
3. 对方服务OK, 调用者自己出现故障(自己等待时间小于服务的超时时间,自己要求服务降级)


服务端

1、模块名 cloud-provider-hystrix-payment8001
2、pml.xml (web、actuator)
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
3、yml 配置文件
server:
  port: 8001
spring:
  application:
    name: cloud-provider-hystrix-service
eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka
4、主启动
@SpringBootApplication
@EnableEurekaClient
@EnableCircuitBreaker  // 开启服务降级。 。。
public class PaymentHystrixMain8001 {
    public static void main(String[] args){
        SpringApplication.run(PaymentHystrixMain8001.class,args) ;
    }
}
@Service
public class PaymentService {
    /** 正常访问的*/
    public String paymentInfoOk(Integer id){
        return "线程池:"+Thread.currentThread().getName()+"paymentInfoOk"+id;
    }
    /** 服务降级的方法 */
    @HystrixCommand(fallbackMethod ="paymentInfoTimeoutHandler",commandProperties = {
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "5000")
    })
    public String paymentInfoTimeout(Integer id){
//  int i = 10/0   程序出错  测试的时候自行打开
// 3秒内正常 超过3秒异常
        try {
            TimeUnit.SECONDS.sleep(3); // hutool 工具包中的方法
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "线程池:"+Thread.currentThread().getName()+"paymentInfoTimeout"+id;
    }
    // 服务降级 后 的callback方法
    public String  paymentInfoTimeoutHandler(Integer id){
        return "调用失败,线程池:"+Thread.currentThread().getName()+"---paymentInfoTimeoutHandler"+id;
    }
}
@RestController
public class PaymentController {
    @Autowired
    private PaymentService paymentService ;

    @Value("${server.port}")
    private String serverPort ;
	// 正常方法
    @GetMapping("/payment/hystrix/ok/{id}")
    public String paymentInfoOk(@PathVariable("id") Integer id){
        String s = paymentService.paymentInfoOk(id);
        System.out.println("result"+s);
        return s ;
    }
   // 超时 、报错。。
    @GetMapping("/payment/hystrix/timeout/{id}")
    public String paymentInfoTimeout(@PathVariable("id") Integer id){
        String s = paymentService.paymentInfoTimeout(id);
        System.out.println("result"+s);
        return s ;
    }
}
5、测试

消费端

1、模块名 cloud-consumer-feign-hystrix-order80
2、pml.xml
<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
3、yml 配置文件
server:
  port: 80
eureka:
  client:
    register-with-eureka: false
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka
feign:
  hystrix:
    enabled: true
#    让feign支持 服务降级
ribbon:
  ReadTimeout: 5000
  ConnectTimeout: 6000

logging:
  level:
    #    feign 日志以什么级别监控那个接口
    com.aqiang9.springcloud.service.PaymentHystrixService: debug
4、主启动
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
@EnableHystrix   // 服务降级
public class OrderHystrixMain80 {
    public static void main(String[] args){
        SpringApplication.run(OrderHystrixMain80.class,args) ;
    }
}
@RestController
public class OrderHystrixController {

    @Autowired
    private PaymentHystrixService paymentHystrixService;

    @GetMapping("/consumer/payment/hystrix/ok/{id}")
    public String paymentInfoOk(@PathVariable("id") Integer id) {
        return paymentHystrixService.paymentInfoOk(id);
    }

    @GetMapping("/consumer/payment/hystrix/timeout/{id}")
    @HystrixCommand(fallbackMethod = "paymentInfoTimeoutFallbackMethod" , commandProperties = {
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "1500")
    })
    @HystrixCommand
    public String paymentInfoTimeout(@PathVariable("id") Integer id) {
        return paymentHystrixService.paymentInfoTimeout(id);
    }

    public String paymentInfoTimeoutFallbackMethod(@PathVariable("id") Integer id){
        return "consumer 服务降级处理";
	}
}
@Component
@FeignClient(value = "CLOUD-PROVIDER-HYSTRIX-SERVICE",fallback = PaymentFallbackService.class)
public interface PaymentHystrixService {
    @GetMapping("/payment/hystrix/ok/{id}")
    String paymentInfoOk(@PathVariable("id") Integer id);

    @GetMapping("/payment/hystrix/timeout/{id}")
    String paymentInfoTimeout(@PathVariable("id") Integer id);
}
5、测试

Hystrix 统一的全局配置

方式一: 如果不指定 ,这采用全局的

@DefaultProperties(defaultFallback = "globalFallbackMethod")
public class OrderHystrixController {
public String globalFallbackMethod(){
        return "全局服务降级";
    }
}

方式二 : 实现OpenFeign 的接口 并在接口上进行指定

@Component
public class PaymentFallbackService implements PaymentHystrixService {
    @Override
    public String paymentInfoOk(Integer id) {
        return "----PaymentFallbackService ---paymentInfoOk---fallback ";
    }
    @Override
    public String paymentInfoTimeout(Integer id) {
        return "----PaymentFallbackService ---paymentInfoTimeout --fallback ";
    }
}
@Component
@FeignClient(value = "CLOUD-PROVIDER-HYSTRIX-SERVICE",fallback = PaymentFallbackService.class)
public interface PaymentHystrixService {
    @GetMapping("/payment/hystrix/ok/{id}")
    String paymentInfoOk(@PathVariable("id") Integer id);

    @GetMapping("/payment/hystrix/timeout/{id}")
    String paymentInfoTimeout(@PathVariable("id") Integer id);
}
发布了119 篇原创文章 · 获赞 9 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/getchar97/article/details/105094974