SpringCloud-20-Spring Cloud Hystrix客户端服务降级

8.5 客户端服务降级

  • 通常情况下,我们都会在客户端进行服务降级,当客户端调用的服务端的服务不可用时,客户端直接进行服务降级处理,避免其线程被长时间、不必要地占用。
  • 沿用microservice-cloud-consumer-dept-openFeign客户端工程,在pom.xml 中添加 Hystrix 的依赖,代码如下。


    
    
        spring-cloud-microservice
        org.example
        1.0-SNAPSHOT
    
    4.0.0
    microservice-cloud-consumer-dept-openFeign
    
    
        
        
            org.example
            microservice-cloud-api
            1.0-SNAPSHOT
        
        
        
            org.springframework.boot
            spring-boot-starter-web
            
                
                    org.springframework.boot
                    spring-boot-starter-tomcat
                
            
        
        
        
            org.springframework.boot
            spring-boot-devtools
            runtime
            true
        
        
        
            org.projectlombok
            lombok
            true
        
        
        
            org.springframework.boot
            spring-boot-starter-test
            test
        
        
        
            org.springframework.boot
            spring-boot-starter-jetty
        
        
        
            org.springframework
            springloaded
            1.2.8.RELEASE
        
        
        
            org.apache.logging.log4j
            log4j-core
        
        
            ch.qos.logback
            logback-core
        
        
        
            org.springframework.cloud
            spring-cloud-starter-netflix-eureka-client
            2.2.10.RELEASE
        
        
            org.springframework.cloud
            spring-cloud-starter-openfeign
            3.1.3
        
        
        
            org.springframework.cloud
            spring-cloud-starter-loadbalancer
            3.1.3
        
        
            com.netflix.ribbon
            ribbon-loadbalancer
            2.7.18
            compile
        
        
            org.springframework.cloud
            spring-cloud-netflix-ribbon
            2.2.10.RELEASE
            compile
        
        
        
            org.springframework.cloud
            spring-cloud-starter-netflix-hystrix
            2.2.10.RELEASE
        
    

    
        
            
                org.springframework.boot
                spring-boot-maven-plugin
                
                    
                        
                            org.projectlombok
                            lombok
                        
                    
                
            
        
    


  • 在 microservice-cloud-consumer-dept-openFeign 的 application.yml 中添加以下配置,开启客户端的 Hystrix 功能。
feign:
 circuitbreaker:
   enabled: true
  • 在 com.example.service包下,创建一个名为 DeptHystrixService 的服务绑定接口,与 microservice-cloud-provider-dept-hystrix-8004中提供的服务接口进行绑定,代码如下。
package com.example.service;

import com.example.config.FeignConfiguration;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

@Service
@FeignClient(value = "MICROSERVICECLOUDPROVIDERDEPTHYSTRIX",configuration = FeignConfiguration.class)
public interface DeptHystrixService {

    @GetMapping("/dept/getInfo/Hystrix/200/{id}")
    String dept_200(@PathVariable("id") Integer id);

    @GetMapping("/dept/testTimeOut/Hystrix/{id}")
    String testTimeOut(@PathVariable("id") Integer id);
}
  • 在 com.example.controller 包下创建一个名为 DeptHystrixController的 Controller ,注意超时提示要与服务端进行区分,方便测试。代码如下。
package com.example.controller;

import com.example.service.DeptHystrixService;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import lombok.extern.slf4j.Slf4j;
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;

@RestController
@Slf4j
public class DeptHystrixController {

    @Autowired
    private DeptHystrixService deptHystrixService;

    @GetMapping("/consumer/dept/getInfo/Hystrix/200/{id}")
    public String dept_200(@PathVariable("id") Integer id) {
        String info = deptHystrixService.dept_200(id);
        log.info(info);
        return "客户端请求"+info;
    }
    //在客户端进行降级
    //超时测试,该服务的响应时间为 3 秒
    @GetMapping("/consumer/dept/testTimeOut/Hystrix/{id}")
    @HystrixCommand(fallbackMethod = "deptTimeoutHandler")
    public String testTimeOut(@PathVariable("id") Integer id){
        String info = deptHystrixService.testTimeOut(id);
        //当Application.yml中没有配置当前端口号,只能使用此方式获取端口
        log.info(info);
        return info;
    }

    // testTimeOut方法的 专用 fallback 方法
    public String deptTimeoutHandler(Integer id){
        log.info("testTimeOut 出错,服务被降级!");
        return "因当前请求testTimeOut超时,客户端服务降级,返回提示信息!当前线程:"+Thread.currentThread().getName()+"请求超时500。ID+"+id;
    }
}
  • 在配置文件 appliction.yml 中添加以下配置,在客户端配置ribbon和hystrix全局和特定方法请求超时的时间。
spring:
  application:
    name: feignServer
server:
  port: 80
  servlet:
    context-path: /
#Jetty specific properties
  jetty:
    threads:
      acceptors: -1                   #Number of acceptor threads to use. When the value is -1, the default, the number of acceptors is derived from the operating environment.
      selectors: -1                   #Number of selector threads to use. When the value is -1, the default, thenumber of selectors is derived from the operating environment.
    max-http-form-post-size: 200000   #Maximum size of the form content in any HTTP post request.

eureka:
  client:
    register-with-eureka: false #false表示不向注册中心注册自己。
    fetch-registry: true #指示此客户端是否应从 eureka 服务器获取 eureka 注册表信息
    service-url: #监控页面地址
      #defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ #发布的服务注册中心地址,单机
      defaultZone: http://eurekaserver7001.com:7001/eureka/,http://eurekaserver7002.com:7002/eureka/,http://eurekaserver7003.com:7003/eureka/ #集群版 将当前的 Eureka Server 注册到 7003 和 7003 上,形成一组互相注册的 Eureka Server 集群
feign:
  client:
    config:
      ## default 设置的全局超时时间,指定服务名称可以设置单个服务的超时时间
      feignServer:  #feignServer这个服务单独配置超时时间
        connectTimeout: 6000
        readTimeout: 6000
  circuitbreaker:
    enabled: true
ribbon:
  eager-load:
    enabled: true  #关闭懒加载
  # 指的是建立连接后从服务器读取到可用资源所用的时间
  ReadTimeout: 6000
  # 指的是建立连接所用的时间,适用于网络状态正常的情况下,两端连接所用的时间
  ConnectTimeout: 6000
  eureka:
    enabled: false #禁用Eureka
logging:
  level:
    com:
      example:
        service: debug

MICROSERVICECLOUDPROVIDERDEPT:
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 7000  #配置请求超时时间
    DeptHystrixService#testTimeOut(Integer):
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 3000   #配置具体方法超时时间 为 3 秒
  • 在配置文件中设计请求的超时时间时,需要注意以下 2 点:
    • Hystrix 可以来为所有请求(方法)设置超时时间(单位为毫秒),若请求超时则触发全局的回退方法进行处理。
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=mmm
    • Hystrix 还可以为某个特定的服务请求(方法)设置超时时间,格式如下:
hystrix.command.xxx#yyy(zzz).execution.isolation.thread.timeoutInMilliseconds=mmm

格式说明如下:

  • xxx:为包含该服务方法的类的名称(通常为服务绑定接口的名称),例如 DeptHystrixService 接口。
  • yyy:服务方法名,例如 testTimeOut 方法。
  • zzz:方法内的参数类型,例如 Integer、String 等等
  • mmm:要设置的超时时间,单位为毫秒(1 秒 =1000 毫秒)
  • 在 microservice-cloud-consumer-dept-openFeign 的主启动类上,使用 @EnableHystrix 注解开启客户端 Hystrix 功能,代码如下。
package com.example;

import com.example.config.FeignConfiguration;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.cloud.netflix.ribbon.RibbonClient;
import org.springframework.cloud.netflix.ribbon.RibbonClients;
import org.springframework.cloud.openfeign.EnableFeignClients;

//OpenFeign和Eureka整合以后,容户端可以直接调用用,不用关心服务的IP地址和端口号
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients //开启 OpenFeign 功能
// 如果只有一个服务就可以直接使用@RibbonClient注解,而不需要@RibbonClients。
// name是写服务提供方的服务名     configuration是指定我们上面创建的配置类
@RibbonClients(value = {
        @RibbonClient(name = "MICROSERVICECLOUDPROVIDERDEPT",configuration = FeignConfiguration.class)
})
//@RibbonClient(name = "MICROSERVICECLOUDPROVIDERDEPT",configuration = FeignConfiguration.class)
@EnableHystrix //启用 Hystrix
public class MicroserviceCloudConsumerDeptOpenFeignApplication {

    public static void main(String[] args) {
        SpringApplication.run(MicroserviceCloudConsumerDeptOpenFeignApplication.class, args);
    }

}
  • 测试前提是保证服务端请求正常不被降级。所以要修改 microservice-cloud-provider-dept-hystrix-8004 中 DeptServiceImpl的代码,将 dept_timeout_500() 方法的运行时间修改为 4 秒(小于超时时间 5 秒),以,代码如下。
//一旦该方法失败并抛出了异常信息后,会自动调用  @HystrixCommand 注解标注的 fallbackMethod 指定的方法
@HystrixCommand(fallbackMethod = "dept_timeout_handler",
        规定 5 秒钟以内就不报错,正常运行,超过 5 秒就报错,调用指定的方法
        commandProperties = {@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "5000")})
@Override
public String dept_timeout_500(Integer id) {
    try {
        //Thread.sleep(6000);
        TimeUnit.SECONDS.sleep(4);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    return "服务端当前线程:"+Thread.currentThread().getName()+"请求超时500。ID+"+id;
}
// 当服务出现故障后,调用该方法给出友好提示
    public String dept_timeout_handler(Integer id){
        return "服务端因当前请求超时,服务降级,返回提示信息!当前线程:"+Thread.currentThread().getName()+"请求超时500。ID+"+id;
    }
  • 先测试下服务端dept_timeout_500() 方法是否被降级,重启 microservice-cloud-provider-dept-hystrix-8004 和 microservice-cloud-consumer-dept-openFeign,使用浏览器访问,访问http://127.0.0.1:8004/dept/testTimeOut/Hystrix/1
    SpringCloud-20-Spring Cloud Hystrix客户端服务降级_第1张图片
  • 使用浏览器访问“http://localhost/consumer/dept/testTimeOut/Hystrix/1”,结果如下图。
    在这里插入图片描述SpringCloud-20-Spring Cloud Hystrix客户端服务降级_第2张图片
  • 修改microservice-cloud-consumer-dept-openFeign的application.yml,将超时方法请求时间改为5 秒
DeptHystrixService#testTimeOut(Integer):
  execution:
    isolation:
      thread:
        timeoutInMilliseconds: 5000   #配置具体方法超时时间 为 5 秒
  • 重启 microservice-cloud-consumer-dept-openFeign,使用浏览器访问,访问http://localhost/consumer/dept/testTimeOut/Hystrix/1
    SpringCloud-20-Spring Cloud Hystrix客户端服务降级_第3张图片SpringCloud-20-Spring Cloud Hystrix客户端服务降级_第4张图片

  • 由此可见可以正常访问dept_timeout_500方法内的数据,请求并未超时。

下一篇:SpringCloud-21-Hystrix全局降级和解耦降级逻辑

你可能感兴趣的:(分布式,Hystrix,SpringCloud,spring,cloud,hystrix,eureka)