文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

SpringCloud hystrix断路器与全局解耦全面介绍

2022-11-13 18:49

关注

第七章中在ProductController 和OrderController 中都使用了局部服务降级,但同时也导致两个问题, 通过观察两个局部降级的案例,可以发现:

每个业务方法都对应一个降级方法,会导致代码膨胀业务逻辑方法和处理服务异常降级方法混在一起。

业务逻辑方法和处理服务异常降级方法混在一起,不便于维护,为解决此问题,可以使用注解 @FeignClient(value = "PRODUCT-SERVICE",fallback = xxx.class)在调用远端服务的接口上进行指定服务降级方法解耦,并实现调用远端服务的接口的实现类,在实现类中统计管理服务降级解耦的方法。

进行全局解耦,以 订单服务 OrderController 调用 商品服务ProductController 为案例,过程如下:

1、订单服务 和 商品服务引入依赖

订单服务引入依赖 openfegin , 商品服务分别引入依赖 Hystrix

2、清除OrderController 和 ProductController 所有降级方法

清除OrderController 所有降级方法

import com.hwadee.springcloud.entity.Product;
import com.hwadee.springcloud.service.IOrderFeignService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/order")
public class OrderController {
    @Autowired
    IOrderFeignService orderFeignService;
    @RequestMapping("/buy/{id}")
    public Product buy(@PathVariable Long id) {
        System.out.println("进入OrderController的buy方法, orderFeignService 准备调用远端接口 findById");
        Product product = orderFeignService.findOrderById(id);
        return product;
    }
    @RequestMapping(value = "/delete/{id}")
    public Product deleteOrderById(@PathVariable Long id) {
        System.out.println("进入OrderController的deleteOrderById方法, orderFeignService 准备调用远端接口deleteOrderById");
        Product product = orderFeignService.deleteOrderById(id);
        return product;
    }
}

清除 ProductController 所有降级方法

注意,若有全局或者专属降级可以自己增加。此处为方便演示,不使用全局或者专属。

import com.hwadee.springcloud.entity.Product;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.math.BigDecimal;
@RestController
@RequestMapping("/product")
public class ProductController {
    //方便后面讲负载均衡,查看ip,此处获取配置中的端口号和ip
    @Value("${server.port}")
    private String port;
    @Value("${spring.cloud.client.ip-address}")
    private String ip;
    @RequestMapping("/buy/{id}")
    public Product findById(@PathVariable Long id) {
        Product product = new Product();
        product.setId(id);
        // 后面需要测试负载均衡,所以返回 ip 地址及端口号
        product.setName("当前访问服务地址:" + ip + ":" + port + "  " + "查询商品订单,订单号:" + id);
        product.setPrice(new BigDecimal(10000.0));
        System.out.println(product);
        //测试超时熔断
        try {
            Thread.sleep(5000);
            //测试并发熔断
            //Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return product;
    }
    @RequestMapping(value = "/delete/{id}")
    public Product deleteOrderById(@PathVariable Long id) {
        Product product = new Product();
        product.setId(id);
        // 后面需要测试负载均衡,所以返回 ip 地址及端口号
        product.setName("当前访问服务地址:" + ip + ":" + port + "  " + "从购物车删除订单,订单号:" + id);
        product.setPrice(new BigDecimal(10000.0));
        System.out.println(product);
        //测试异常熔断
        System.out.println(10 / 0);
        return product;
    }
}

2、定义Feign接口的实现类

因为订单服务 OrderController中通过 接口IOrderFeignService和 注解@FeignClient 远程调用商品服务ProductController,因此当订单服务 OrderController出现超时或异常,可以通过订单服务 OrderController中通过 接口IOrderFeignService的 实现类OrderFeignServiceFallBack 将务逻辑的处理方法 和 降级方法进行解耦。

import com.hwadee.springcloud.entity.Product;
import com.hwadee.springcloud.service.IOrderFeignService;
import org.springframework.stereotype.Component;
@Component
public class OrderFeignServiceFallBack implements IOrderFeignService {
    @Override
    public Product findOrderById(Long id) {
        Product product = new Product();
        product.setId(id);
        product.setName("当前订单服务访问/order/buy/1 超时:"+id);
        return product;
    }
    @Override
    public Product deleteOrderById(Long id) {
        Product product = new Product();
        product.setId(id);
        product.setName("当前订单服务访问/order/delete/1 10/0异常:"+id);
        return product;
    }
}

3、修改IOrderFeignService代码

在 接口IOrderFeignService的注解@FeignClient中指定服务解耦的类OrderFeignServiceFallBack 。

@Component // 让 spring 可以识别,不加也行,但是在注入的时候 IDEA 会报错,不会影响运行,但有条红线让自己不舒服
@FeignClient(value = "PRODUCT-SERVICE",fallback = OrderFeignServiceFallBack.class)
public interface IOrderFeignService {
    @RequestMapping(value = "/product/buy/{id}")
    Product findOrderById(@PathVariable Long id);
    @RequestMapping(value = "/product/delete/{id}")
    Product deleteOrderById(@PathVariable Long id);
}

4、定义 订单服务 和 商品服务主启动类

由于订单服务中引入的spring-cloud-starter-openfeign依赖中已经集成了feign-hystrix,有了对 Hystrix 的支持,所以不需要额外引入依赖项。如果需要开启 订单服务端的hystrix服务,只需要在订单服务的配置文件配置feign-hystrix 进行激活Hystrix,无需在主启动类中添加注解 @EnableHystrix 或 @EnableHystrix 来开启Hystrix服务。订单服务 和 商品服务主启动类如下:

订单服务主启动类 OrderServerApplication

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableEurekaClient// 启动 eureka 客户端
@EnableFeignClients  // 启动 feign
public class OrderServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderServerApplication.class, args);
    }
}

商品服务主启动类 ProductServerApplication

@SpringBootApplication
@EnableEurekaClient// 启动 eureka 客户端
public class ProductServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(ProductServerApplication.class, args);
    }
}

4、开启openfeign在调用服务过程中开启hystrix支持

由于前面引入的spring-cloud-starter-openfeign依赖中已经集成了feign-hystrix,有了对 Hystrix 的支持,所以不需要额外引入依赖项。只需要在订单服务的 application.yml 配置文件中开启openfeign在调用服务过程中开启hystrix支持。

server:
  port: 9000
spring:
  application:
    name: order-service # 为当前订单服务命名为 order-service

# 配置eureka客户端信息
eureka:
  client:
    service-url:
      # 配置eureka客户端服务order-service的注册地址,与 eureka-server 中暴露地址要保持一致
      defaultZone: http://localhost:8000/eureka/
  instance:
    prefer-ip-address: true # 是否使用 IP 地址注册,默认 false
    # instance-id: order-service  # 实例 id,服务的唯一标识,会自动的找到order-service的ip和端口
    instance-id: ${spring.cloud.client.ip-address}:${server.port} # 如果想在控制页面看到服务地址与端口,可以将 instance-id 这样配置

feign:
  hystrix:
    enabled: true

5、修改订单服务配置文件

由于订单服务中引入的spring-cloud-starter-openfeign依赖中已经集成了feign-hystrix,有了对 Hystrix 的支持,所以不需要额外引入依赖项。如果需要开启 订单服务端的hystrix服务,只需要在订单服务的配置文件配置feign-hystrix 进行激活Hystrix,修改application.yml如下:

server:
  port: 9000
spring:
  application:
    name: order-service # 为当前订单服务命名为 order-service

# 配置eureka客户端信息
eureka:
  client:
    service-url:
      # 配置eureka客户端服务order-service的注册地址,与 eureka-server 中暴露地址要保持一致
      defaultZone: http://localhost:8000/eureka/
  instance:
    prefer-ip-address: true # 是否使用 IP 地址注册,默认 false
    # instance-id: order-service  # 实例 id,服务的唯一标识,会自动的找到order-service的ip和端口
    instance-id: ${spring.cloud.client.ip-address}:${server.port} # 如果想在控制页面看到服务地址与端口,可以将 instance-id 这样配置

feign:
  hystrix:
    enabled: true

6、进行测试

分别访问 http://localhost:9000/order/buy/1 和 http://localhost:9000/order/delete/1 查看浏览器结果如下:

到此这篇关于SpringCloud hystrix断路器与全局解耦全面介绍的文章就介绍到这了,更多相关SpringCloud hystrix断路器内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯