SpringCloud------熔断器Hystrix的使用

1.GitHub地址

https://github.com/Netflix/Hystrix

https://github.com/Netflix/Hystrix/wiki

 

官方文档

https://cloud.spring.io/spring-cloud-static/spring-cloud-netflix/2.2.2.RELEASE/reference/html/#circuit-breaker-spring-cloud-circuit-breaker-with-hystrix

 

2.为什么要用Hystrix?

在一个分布式系统里,一个服务依赖多个服务,可能存在某个服务调用失败,

比如超时,异常等,如何能保证在一个依赖出问题的情况下,不会导致整体服务失败,

通过Hystrix就可以解决

 

3.功能

提供熔断,隔离,Fallback,cache,监控等功能

 

4.熔断后怎么处理?

出现错误后,可以Fallback错误的处理信息

 

5.代码实现

1)添加依赖

<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.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.28</version>
</dependency>

 

 

2)启动类添加@EnableCircuitBreaker

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.openfeign.EnableFeignClients;

@SpringBootApplication
@MapperScan("cn.ytheng.order_service")
@EnableFeignClients
@EnableCircuitBreaker
public class OrderServiceApplication {

    public static void main(String[] args) {

        SpringApplication.run(OrderServiceApplication.class, args);
    }

}

 

3)添加ProductOrder订单实体类

import lombok.Data;
import java.io.Serializable;
import java.util.Date;

/**
 * 商品订单实体类
 */
@Data
public class ProductOrder implements Serializable {
    private String id;
    private int userId;
    private String productName;
    private String tradeNo;
    private Date createTime;

    public ProductOrder() {
    }

}

 

4)添加feign,为了测试Product服务挂掉时,降级处理的情况

import cn.theng.order_service.fallback.ProductFallback;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

/**
 *
 * 商品服务客户端
 * product-service: 调用服务名称,即spring.application.name
 * ProductFallback:需要继承当前FeignClient的类
 *
 */
@FeignClient(name = "product-service", fallback = ProductFallback.class)
public interface ProductClient {

    @GetMapping("/api/v1/product/find")
    String getById(@RequestParam("id") int id);

}

 

5)添加针对product-service服务的降级处理类

import cn.theng.order_service.service.ProductClient;
import org.springframework.stereotype.Component;

/**
 *
 * 针对商品服务,做降级处理
 *
 */
@Component
public class ProductFallback implements ProductClient {

    //当调用product-service的getById接口出现错误时,就会执行该方法
    @Override
    public String getById(int id) {

        System.out.println("feign 调用product-service服务异常...");

        return "null";
    }
}

 

6)添加ProductOrderService接口

import cn.theng.order_service.domain.ProductOrder;

/**
 * 订单业务类
 */
public interface ProductOrderService {

    /**
     * 下单接口
     */
    ProductOrder save(int userId, int productId);

}

 

7)添加ProductOrderServiceImpl接口实现类import cn.theng.order_service.domain.ProductOrder;import cn.theng.order_service.mapper.ProductOrderMapper;

import cn.theng.order_service.service.ProductClient;
import cn.theng.order_service.service.ProductOrderService;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.UUID;

@Service
public class ProductOrderServiceImpl implements ProductOrderService {

    @Autowired
    private ProductClient productClient;

    @Override
    public ProductOrder save(int userId, int productId) {

        String data = productClient.getById(productId);

// 下面代码会报错,触发熔断
JSONObject product = JSON.parseObject(data); ProductOrder order = new ProductOrder(); order.setTradeNo(UUID.randomUUID().toString()); order.setProductName(product.getString("productName")); order.setCreateTime(new Date()); return order; } }

 

8)添加controller

package cn.theng.order_service.controller;

import cn.theng.order_service.domain.ProductOrder;
import cn.theng.order_service.service.ProductClient;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/api/v1/order")
public class ProductOrderController {

    @Autowired
    private ProductOrderService productOrderService;

    @PostMapping("/test2")
    @HystrixCommand(fallbackMethod = "getProductFail")
    public Object test2(@RequestParam("product_id") int productId) {

        //如果test2内有报错,则会执行getProductFail方法
        ProductOrder order = productOrderService.save(1, productId);

        return "success";
    }

    //方法签名一定要与上面方法保持一致
    public Object getProductFail(int productId) {
        Map<String, Object> map = new HashMap<>();
        map.put("code", -1);
        map.put("msg", "目前排队人数过多,请稍后再试...");
        return map;
    }
}

 

9)修改application.yml配置

server:
  port: 8781
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/

spring:
  application:
    name: order-service

#设置调用服务超时时间
#product-service为服务名称,也可以设置为默认值default
#默认配置下,feign的hystrix配置是关闭的
feign:
  hystrix:
    enabled: true
  client:
    config:
      product-service:
        connectTimeout: 5000
        readTimeout: 11000

 

 

10)访问地址

 

posted @ 2020-03-13 16:53  玉天恒  阅读(902)  评论(0编辑  收藏  举报