微服务SpringCloud Alibaba组件OpenFeign 服务调用教程【详解hystrix熔断降级、Ribbon和loanbalancer负载均衡等 附有案例+示例代码】

二.OpenFeign 服务调用

2.1简介

微服务架构中使用OpenFeign进行服务调用,OpenFeign提供了一种简洁的方式来定义和处理服务间的调用。 OpenFeign作为一个声明式的、模块化的HTTP客户端,通过**「接口」的定义和「注解」**的使用,简化了微服务之间的通信调用。

2.2 OpenFeign使用案例

【yml文件配置】

server:
  port: 7780

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/smbms?useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull
    username: root
    password: sa123456
  application:
    name: bill-provider #注册中心注册服务名称
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848

mybatis-plus:
  type-aliases-package: com.hz.billprovider7780.pojo
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    map-underscore-to-camel-case: false #驼峰映射

【数据库相关依赖】

        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <scope>runtime</scope>
        </dependency>

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>
              mybatis-plus-boot-starter
             </artifactId>
            <version>3.5.1</version>
        </dependency>

【openfeign依赖】

(三个,依赖,版本号,org.springframework.cloud)

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

同时注意版本号:

(父工程里)

在这里插入图片描述

 <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>
           spring-cloud-dependencies
       </artifactId>
       <version>${spring-cloud.version}</version>
       <type>pom</type>
       <scope>import</scope>
 </dependency>

父工程里

在这里插入图片描述

由于OpenFeign版本比较高还需要导入loadbalancer依赖配合使用

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

【配置类开启openfeign注解】

在这里插入图片描述

【bil-provider-7780】

在这里插入图片描述

【BillService】

/**
 * @Author: weiyi
 * @Description:
 * @Date: 2025/2/8 11:22
 * @InterfaceName: BillService
 * @Version 1.0
 */


public interface BillService extends IService<Bill> {
    
    

    /**
     * @description:根据id,查询订单
     * @author: weiyi
     * @date: 2025/2/8 11:24
     * @param: [bill]
     * @return: com.hz.utils.ResultAJAX
     **/
    public ResultAJAX getBillById(Integer id);

}

【BillServiceImpl】

/**
 * @Author: weiyi
 * @Description:
 * @Date 2025/2/8 11:25
 * @ClassName BillServiceImpl
 * @Version 1.0
 */

@Service
public class BillServiceImpl extends ServiceImpl<BillMapper, Bill> implements BillService {
    
    

    @Override
    public ResultAJAX getBillById(Integer id) {
    
    
        Bill bill = this.getById(id);
        return ResultAJAX.success(bill);
    }
}

【实体类Bill】

@Data
@TableName("smbms_bill")
public class Bill {
    
    
	private Integer id;   //id 
	private String billCode; //账单编码 
	private String productName; //商品名称 
	private String productDesc; //商品描述 
	private String productUnit; //商品单位
	private BigDecimal productCount; //商品数量 
	private BigDecimal totalPrice; //总金额
	private Integer isPayment; //是否支付 
	private Integer providerId; //供应商ID 
	private Integer createdBy; //创建者
	private Date creationDate; //创建时间
	private Integer modifyBy; //更新者
	private Date modifyDate;//更新时间
}

【BillMapper】

/**
 * @Author: weiyi
 * @Description:
 * @Date: 2025/2/8 11:21
 * @InterfaceName: BillMapper
 * @Version 1.0
 */

@Mapper
public interface BillMapper extends BaseMapper<Bill> {
    
    
}

【BillServiceApi】

/**
 * @Author: weiyi
 * @Description: provider提供对外暴露的接口,供consumer调用
 * @Date 2025/2/8 11:29
 * @ClassName BillServiceApi
 * @Version 1.0
 */

@RestController
@RequestMapping("/bill")
@AllArgsConstructor
public class BillServiceApi {
    
    

    // @Autowired
    // private BillService billService;

    private final BillService billService;

    @GetMapping("/getBillId")
    public ResultAJAX getBillId(@RequestParam("id") Integer id) {
    
    
        System.out.println("this is 7780....."+id);
        return billService.getBillById(id);
    }




}

【bill-consumer-7790】

在这里插入图片描述

【api包下的BillService】

/**
 * @Author: weiyi
 * @Description: 调用provider对外暴露的接口
 * @Date: 2025/2/8 14:55
 * @InterfaceName: BillService
 * @Version 1.0
 */
// value后跟的是注册中心服务名
@FeignClient(value = "bill-provider",path = "/bill")
public interface BillService {
    
    

    @GetMapping("/getBillId")
    public ResultAJAX getBillId(@RequestParam("id") Integer id);
}

【BillServiceController】

/**
 * @Author: weiyi
 * @Description: 调用服务提供者对外暴漏的接口
 * @Date 2025/2/8 11:33
 * @ClassName BillServiceController
 * @Version 1.0
 */

@RestController
@RequestMapping("/bill")
public class BillServiceController {
    
    

    @Resource
    private BillService billService;

    @GetMapping("/getId")
    public ResultAJAX getId(Integer id) {
    
    
        return billService.getBillId(id);
    }


}

在这里插入图片描述

启动bill-provider-7780,再启动7790

在这里插入图片描述

http://localhost:7790/bill/getId?id=1

在这里插入图片描述

整体思路:
  在provider里面根据id查询订单,将接口暴漏在外面,供consumer调用,

在这里插入图片描述

=========

【传单个对象】

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

测试
在这里插入图片描述

2.3 hystrix熔断降级

(在consumer中降级)

引入依赖

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

使用fallback进行服务降级

在yml配置文件中开启服务降级:

feign: #开启熔断处理
  circuitbreaker:
      enabled: true

编写BillServiceFallback实现BillService
在这里插入图片描述

/**
 * @Author: weiyi
 * @Description: 降级处理
 * @Date 2025/2/8 
 * @ClassName BillServiceFallback
 * @Version 1.0
 */

@Component
public class BillServiceFallback implements BillService {
    
    
    @Override
    public ResultAJAX getBillId(Integer id) {
    
    
        //降级处理
        System.out.println("降级处理...");
        return ResultAJAX.error("请求失败");
    }

    @Override
    public ResultAJAX getBill(BIllVo billVo) {
    
    

        //降级处理
        System.out.println("降级处理...");
        return ResultAJAX.error("请求失败");
    }
}

修改接口中@FeignClient

在这里插入图片描述

测试:(provider宕机)

在这里插入图片描述

在这里插入图片描述

2.4 负载均衡Ribbon

ribbon负载均衡Ribbon(负载均衡)注意:2021版本已经不支持ribbon

SpringCloud 从 2020.0.1 版本开始,移除了 Ribbon 组件,使⽤Spring Cloud LoadBalancer 组件来代替 Ribbon 实现客户端负载均衡

2.5 loadbalancer负载均衡

在consumer中引入jar文件

<!--客户端负载均衡loadbalancer-->
<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>
     spring-cloud-starter-loadbalancer
    </artifactId>
</dependency>

注意:复制一份provider,将两个provider服务名改为一致,端口号不一致,consumer中调用服务(一个provider两个实例)

在这里插入图片描述

在这里插入图片描述

consumer下的 config包中添加配置类RandomLoadBalancerConfig,实现随机策略

/**
 * @Author: weiyi
 * @Description: 负载均衡配置  随机策略
 * @Date 2025/2/8 
 * @ClassName RandomLoadBalancerConfig
 * @Version 1.0
 */
public class RandomLoadBalancerConfig {
    
    

    @Bean
    ReactorLoadBalancer<ServiceInstance> randomLoadBalancer(
            Environment environment, LoadBalancerClientFactory
            loadBalancerClientFactory) {
    
    
        String name =
                environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
        return new RandomLoadBalancer(loadBalancerClientFactory
                .getLazyProvider(name, ServiceInstanceListSupplier.class),
                name);
    }
}

在BillServive中配置注解

// 负载均衡
@LoadBalancerClient(name="bill-provider", configuration = RandomLoadBalancerConfig.class)

在这里插入图片描述

测试:

http://localhost:7790/bill/getId?id=1

多请求几次,在控制台就会发现7780服务和7781服务会随机收到请求,并打印信息。