1Hystrix Ribbon · SpringCloud微服务实战 · 看云

1.Hystrix Ribbon

导航

本节代码地址


在Spring Cloud 中,Hystrix 主要用在被调用方,还是之前那张图,服务A调用服务B,如果服务A调用不同服务B是,及时回退信息给用户,防止因为超时问题引起更多的问题至服务不可用。
1eeb845ac5760b7b735e20d586c4c831_MD5.webp

本次演示需要fw-cloud-ribbon-server先启动起来,用于提供服务,也就是上图的服务B,现在我们需要自己开发服务A。

1.1 新建项目

4e88262507afa7d8f49f56be5954b691_MD5.webp

1.2 maven 配置

我们需要在maven引入spring-cloud-starter-netflix-hystrix的包。

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</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-netflix-hystrix</artifactId>
    </dependency>
</dependencies>

1.3 新建启动类

启动类中添加 @EnableHystrix注解用于开启Hystrix

@EnableHystrix
@EnableDiscoveryClient
@SpringBootApplication
public class FwHystrixRibbonApplication {
    public static void main(String[] args) {
        SpringApplication.run(FwHystrixRibbonApplication.class, args);
    }


}

1.4 创建接收用的实体


@Data
@AllArgsConstructor
@NoArgsConstructor
public class User implements Serializable {

    
    private long id;

    
    private String username;

    
    private String realname;

    
    private String email;

    
    private String remark;
}

1.5 创建Ribbon调用类

这里需要注意我们在远程调用的方法上添加了@HystrixCommand(fallbackMethod = "findUserByIdFailure"),也就是说如果调用失败会执行findUserByIdFailure方法

@Service
@Slf4j
public class EurekaHystrixRibbonService {


    @Autowired
    RestTemplate restTemplate;

    @HystrixCommand(fallbackMethod = "findUserByIdFailure")
    public User findUserById(Long id) {
        
        return restTemplate.getForObject("http://fw-cloud-ribbon-server/user/" + id, User.class);
    }

    
    public User findUserByIdFailure(Long id) {
        return new User(id,null,null,null,"网络繁忙,请稍后再试,请确认手牌");
    }

}

1.6 Ribbon 基本配置

这里添加了一个getServlet()方法,用于后面Hystrix dashboard 用,继续读你可以看到的。

@Configuration
public class EurekaRibbonConfig {

    @Bean
    @LoadBalanced 
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

    @Bean
    public IRule ribbonRule() {

        
        

        return new RandomRule();
    }


    
    @Bean
    public ServletRegistrationBean getServlet() {
        HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet();
        ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet);
        registrationBean.setLoadOnStartup(1);
        registrationBean.addUrlMappings("/hystrix.stream");
        registrationBean.setName("HystrixMetricsStreamServlet");
        return registrationBean;
    }

}

1.7 控制层

@RestController
public class EurekaHystrixController {
    @Resource
    private EurekaHystrixRibbonService eurekaRibbonService;
    
    @GetMapping("/user/{id:\\d+}")
    public User findUserById(@PathVariable long id){
        return eurekaRibbonService.findUserById(id);
    }
}

1.8 应用配置

server:
  port: 8675
spring:
  application:
    name: fw-hystrix-ribbon
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/

1.9 启动项目

需要先启动Eureka、再启动fw-cloud-ribbon-server、再启动当前项目
0484cd1027db66aca190ae4f7ee8aa50_MD5.png

利用Postman测试localhost:8675/user/1

005f3f3071c79e310c72b04d4f4613d6_MD5.png

下面我们将fw-cloud-ribbon-server关掉,再测试,可以看到返回就是findUserByIdFailure设置的描述
a0d2d1e3264dc9d1883a9d2bbb848632_MD5.png

1.10 @HystrixCommand配置拓展

除了指定fallbackMethod以外,还有很多属性可以配置,下图是@HystrixCommand的全部属性
711e9f40ef183ff917ec3eacfeb1f4da_MD5.png

例如
指定回退方法和默认方法都是findUserByIdFailure,也可以不同,指定超时时间100毫秒,线程池大小为1,忽略Exception触发的回退等,具体的属性,根据字面意思应该没问题。一般我们也用不到这么多属性

@HystrixCommand(fallbackMethod = "findUserByIdFailure"
        , groupKey = "MyGroup"
        , commandKey = "MyCommandKey"
        , threadPoolKey = "MyThreadPool"
        , commandProperties = {
        @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "100")}
        , threadPoolProperties = {
        @HystrixProperty(name = "coreSize", value = "1")}
        , ignoreExceptions = {Exception.class}
        , observableExecutionMode = ObservableExecutionMode.EAGER
        , raiseHystrixExceptions = {HystrixException.RUNTIME_EXCEPTION}
        , defaultFallback = "findUserByIdFailure"
)

1.11 默认配置

对于一些默认的配置,可以使用@DefaultProperties,可以减少@HystrixCommand中的代码量,如下

@Service
@Slf4j
@DefaultProperties(groupKey = "MyGroup")
public class EurekaHystrixRibbonService {


    @Autowired
    RestTemplate restTemplate;
    ......