• Hystrix熔断器整合 - Feign实现服务容错


    实战前需了解:https://blog.csdn.net/wanzijy/article/details/125041622
    Hystrix熔断器整合 - 搭建项目:https://blog.csdn.net/wanzijy/article/details/125496651
    Hystrix熔断器整合 - 请求缓存:https://blog.csdn.net/wanzijy/article/details/125512072
    Hystrix熔断器整合 - 请求合并:https://blog.csdn.net/wanzijy/article/details/125579664
    Hystrix熔断器整合 - 服务隔离之线程池隔离:https://blog.csdn.net/wanzijy/article/details/125630353
    Hystrix熔断器整合 - 服务隔离之信号量隔离:https://blog.csdn.net/wanzijy/article/details/125826690
    Hystrix熔断器整合 - 服务熔断和服务降级:https://blog.csdn.net/wanzijy/article/details/125826853
    Hystrix熔断器整合 - Feign实现服务容错:https://blog.csdn.net/wanzijy/article/details/125985304
    Hystrix熔断器整合 - 可视化界面三部曲:https://blog.csdn.net/wanzijy/article/details/126005452

    1. 模块搭建

    1.1 pom.xml

    <dependencies>
    	<dependency>
    		<groupId>org.springframework.cloudgroupId>
    		<artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
    	dependency>
    	<dependency>
    		<groupId>org.springframework.cloudgroupId>
    		<artifactId>spring-cloud-starter-openfeignartifactId>
    	dependency>
    	<dependency>
    		<groupId>org.springframework.bootgroupId>
    		<artifactId>spring-boot-starter-webartifactId>
    	dependency>
    	<dependency>
    		<groupId>org.projectlombokgroupId>
    		<artifactId>lombokartifactId>
     		<scope>providedscope>
    	dependency>
    	<dependency>
    		<groupId>org.springframework.bootgroupId>
    		<artifactId>spring-boot-starter-testartifactId>
    		<scope>testscope>
    		<exclusions>
    			<exclusion>
    				<groupId>org.junit.vintagegroupId>
    				<artifactId>junit-vintage-engineartifactId>
    			exclusion>
    		exclusions>
    	dependency>
    dependencies>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    1.2 配置文件

    spring:
      application:
        name: order-service-feign
    
    server:
      port: 9091
    
    eureka:
      instance:
        prefer-ip-address: true  #  是否使用 ip 地址注册
        instance-id: ${spring.cloud.client.ip-address}:${server.port}  #  ip:port
      client:
        service-url:  #  设置服务注册中心地址
          defaultZone: http://eureka01:8761/eureka/,http://eureka02:8762/eureka/
        register-with-eureka: true
        fetch-registry: true
    
    feign:
      hystrix:
        enabled: true
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    1.3 启动类

    @SpringBootApplication
    @EnableEurekaClient
    @EnableFeignClients
    public class OrderServiceFeignApplication {
        public static void main(String[] args) {
            SpringApplication.run(OrderServiceFeignApplication.class, args);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    1.4 pojo

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class Order {
        private Integer id;
        private String orderNo;
        private String orderAddress;
        private Double totalPrice;
        private List<Product> productList;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class Product {
        private Integer id;
        private String productName;
        private Integer productNum;
        private Double productPrice;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    1.5 service

    @FeignClient(value = "product-service", fallback = ProductServiceFallback.class)
    public interface ProductService {
        @GetMapping("/product/list")
        List<Product> selectProductList();
    
        @GetMapping("/product/listByIds")
        List<Product> selectProductListByIds(@RequestParam("id") List<Integer> ids);
    
        @GetMapping("/product/{id}")
        Product selectProductListById(@PathVariable("id") Integer id);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    public interface OrderService {
        Order selectOrderById(Integer id);
    
        Order queryOrderById(Integer id);
    
        Order searchOrderById(Integer id);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    @Service
    public class OrderServiceImpl implements OrderService{
    
        @Autowired
        private ProductService productService;
    
        @Override
        public Order selectOrderById(Integer id) {
            return new Order(id, "order-001", "中国", 22788D,
                    productService.selectProductList());
        }
    
        @Override
        public Order queryOrderById(Integer id) {
            return new Order(id, "order-002", "中国", 11600D,
                    productService.selectProductListByIds(Arrays.asList(1, 2)));
        }
        
        @Override
        public Order searchOrderById(Integer id) {
            return new Order(id, "order-003", "中国", 2666D,
                    Arrays.asList(productService.selectProductListById(1)));
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    1.6 controller

    @RestController
    @RequestMapping("/order")
    public class OrderController {
    
        @Autowired
        private OrderService orderService;
    
        @GetMapping("/{id}/product/list")  //  localhost:9091/order/1/product/list
        public Order selectOrderById(@PathVariable("id") Integer id) {
            return orderService.selectOrderById(id);
        }
    
        @GetMapping("/{id}/product/listByIds")  //  http://localhost:9091/order/1/product/listByIds
        public Order queryOrderById(@PathVariable("id") Integer id) {
            return orderService.queryOrderById(id);
        }
    
        @GetMapping("/{id}/product")  //  http://localhost:9091/order/1/product
        public Order searchOrderById(@PathVariable("id") Integer id) {
            return orderService.searchOrderById(id);
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    1.7 fallback 包

    @Component
    public class ProductServiceFallback implements ProductService {
    
        @Override
        public List<Product> selectProductList() {
            return Arrays.asList(
                    new Product(1, "托底数据-华为手机", 1, 5800D),
                    new Product(2, "托底数据-联想笔记本", 1, 6888D),
                    new Product(3, "托底数据-小米平板", 5, 2020D)
            );
        }
    
        @Override
        public List<Product> selectProductListByIds(List<Integer> ids) {
            List<Product> products = new ArrayList<>();
            ids.forEach(id -> products.add(new Product(id, "托底数据-电视机" + id, 1, 8650D)));
            return products;
        }
    
        @Override
        public Product selectProductListById(Integer id) {
            return new Product(id, "托底数据-冰箱", 1, 2666D);
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    2. 简介

    Feign 实现容错,主要是通过 @FeignClient 注解实现
    该注解下有一个参数 fallback ,值填上远程调用实现接口的实现类的 class
    所有发生容错方法的托底数据都在远程调用接口的实现类上

    远程调用接口:ProductService
    远程调用接口实现类:ProductServiceFallback

    3. 测试

    上述有3个接口,在这随意访问一个: http://localhost:9091/order/1/product/listByIds

    在这里插入图片描述

    此时关掉 product-service 模块,再次访问

    在这里插入图片描述

    4. 修改上述的容错,使其打印在控制台上

    4.1 在 fallback 包下新建一个类

    @Component
    public class ProductServiceFallbackFactory implements FallbackFactory<ProductService> {
    
        Logger logger = LoggerFactory.getLogger(ProductServiceFallbackFactory.class);
    
        @Override
        public ProductService create(Throwable cause) {
            return new ProductService() {
                @Override
                public List<Product> selectProductList() {
                    logger.error("ProductService 服务的 selectProductList 方法出现异常,异常信息如下:" + cause);
    
                    return Arrays.asList(
                            new Product(1, "托底数据-华为手机", 1, 5800D),
                            new Product(2, "托底数据-联想笔记本", 1, 6888D),
                            new Product(3, "托底数据-小米平板", 5, 2020D)
                    );
                }
    
                @Override
                public List<Product> selectProductListByIds(List<Integer> ids) {
                    logger.error("ProductService 服务的 selectProductListByIds 方法出现异常,异常信息如下:" + cause);
    
                    List<Product> products = new ArrayList<>();
                    ids.forEach(id -> products.add(new Product(id, "托底数据-电视机" + id, 1, 8650D)));
                    return products;
                }
    
                @Override
                public Product selectProductListById(Integer id) {
                    logger.error("ProductService 服务的 selectProductListById 方法出现异常,异常信息如下:" + cause);
    
                    return new Product(id, "托底数据-冰箱", 1, 2666D);
                }
            };
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    4.2 修改 ProductService

    @FeignClient(value = "product-service", fallbackFactory = ProductServiceFallbackFactory.class)
    public interface ProductService {
    
        @GetMapping("/product/list")
        List<Product> selectProductList();
    
        @GetMapping("/product/listByIds")
        List<Product> selectProductListByIds(@RequestParam("id") List<Integer> ids);
    
        @GetMapping("/product/{id}")
        Product selectProductListById(@PathVariable("id") Integer id);
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    4.3 测试

    重复第3节的测试,然后看其控制台

    在这里插入图片描述

  • 相关阅读:
    【从0到1进阶Redis】哨兵模式
    前端架构选择
    -角谷猜想-
    MySQL如何进行增量备份与恢复?
    对象 的属性名 在何时使用obj[‘属性名‘]
    人工智能数学基础--概率与统计12:连续随机变量的概率密度函数以及正态分布
    【函数式编程实战】(十一) CompletableFuture、反应式编程源码解析与实战
    kubernetes问题(一)-异常事件
    会多门编程语言的你,最推荐哪3-5门语言?
    .NET周刊【5月第1期 2024-05-05】
  • 原文地址:https://blog.csdn.net/wanzijy/article/details/125985304