二.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服务会随机收到请求,并打印信息。