Feign远程调用结合fallback(Springboot包扫描)
微服务项目中,各微服务模块间互相调用,通常使用HTTP协议调用,为了优雅和快速调用服务,通常使用HTTP客户端,如Feign
为各服务编写Feign客户端应当是一次编写重复调用的过程,因此Feign客户端应当作为一个独立工具包引入,在这种情况下,讨论Feign的远程调用及其fallback的熔断机制
项目基本架构
nacos集群
#2023-02-16T20:21:18.756
192.168.8.103:8845
192.168.8.103:8846
192.168.8.103:8847
nacos服务列表
userSercvice - 用户信息查询服务
orderService - 订单查询服务,调用了userServcie
nginx负载均衡nacos集群
将三个nacos负载均衡到 http://nacos-cluster:8848 上
upstream nacos-cluster {
server 127.0.0.1:8845;
server 127.0.0.1:8846;
server 127.0.0.1:8847;
}
server {
listen 8848;
server_name localhost;
location /nacos {
proxy_pass http://nacos-cluster;
}
}
feigh-api
SpringCloud微服务模块,但是没有启动类
win下获取文件夹目录结构可以使用 tree 命令, /f 表包含文件
tree /f
└─cn
└─itcast
└─feign
├─clients
│ UserClient.java
│
├─fallback
│ UserClientFallback.java
│
└─pojo
User.java
UserClient.java
// 包含一个HTTP请求 /user/{id} 返回实体类User
// 包含一个fallback=UserClientFallback.class
@FeignClient(value = "userService", fallback = UserClientFallback.class)
public interface UserClient {
@GetMapping("/user/{id}")
User findById(@PathVariable("id") Long id);
}
UserClientFallback.java
注意:这里@Component 是为了让外部的SpringBoot项目能够扫描到 UserClientFallback
而不是feign-api 这个项目扫描到(没有启动类扫描不到啦)
// 一个简单的fallback,返回一个id=0的空User对象
@Component
public class UserClientFallback implements UserClient {
private static final User USER_FALLBACK = new User(0L, null, null);
@Override
public User findById(Long id) {
return USER_FALLBACK;
}
}
pom.xml
父pom包含了SpringBoot
<parent>
<artifactId>cloud-demo</artifactId>
<groupId>cn.itcast.demo</groupId>
<version>1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>cn.itcast.feign</groupId>
<artifactId>feign-api</artifactId>
order-service
SpringCloud微服务模块结构
└─cn
└─itcast
└─order
│ OrderApplication.java(SpringBootApplication启动类)
│
├─mapper
│ OrderMapper.java
│
├─pojo
│ Order.java
│
├─service
│ OrderService.java
│
└─web
OrderController.java
引用feign-api
pom.xml
<!--my.feign.api.module-->
<dependency>
<groupId>cn.itcast.feign</groupId>
<artifactId>feign-api</artifactId>
<version>1.0</version>
</dependency>
application.yaml
必须开启
# feign
feign:
hystrix: # 配置服务降级(熔断)
enabled: true
使用UserClient
-
OrderApplication.java - 启动类
-
// 完整的包扫描路径,包含当前order-service微服务中的包,和feign-api模块下的包路径 @SpringBootApplication(scanBasePackages = {"cn.itcast.order", "cn.itcast.feign"}) @EnableFeignClients(clients = {UserClient.class}) // 开启FeignClient,指定要使用的类 public class OrderApplication {}
-
OrderService.java - 使用
-
@Service public class OrderService { // 引入Feign客户端 @Resource private UserClient userClient; // 调用 public Order queryOrderById(Long orderId) { // 1.查询订单 Order order = orderMapper.findById(orderId); // 2. Feign 发送请求 User user = userClient.findById(order.getUserId()); // 3. 封装 order.setUser(user); // 4.返回 return order; } }
效果 Feign.log.level=BASIC
-
熔断
-
{"id":102,"price":209900,"name":"雅迪 yadea 新国标电动车","num":1,"userId":2,"user":{"id":0,"username":null,"address":null}} ------------------------------------------------------ 02-17 10:23:10:307 DEBUG 10036 --- [nio-8080-exec-3] c.i.order.mapper.OrderMapper.findById : ==> Preparing: select * from tb_order where id = ? 02-17 10:23:10:307 DEBUG 10036 --- [nio-8080-exec-3] c.i.order.mapper.OrderMapper.findById : ==> Parameters: 102(Long) 02-17 10:23:10:308 DEBUG 10036 --- [nio-8080-exec-3] c.i.order.mapper.OrderMapper.findById : <== Total: 1 02-17 10:23:10:309 DEBUG 10036 --- [x-userService-5] cn.itcast.feign.clients.UserClient : [UserClient#findById] ---> GET http://userService/user/2 HTTP/1.1 02-17 10:23:12:313 DEBUG 10036 --- [x-userService-5] cn.itcast.feign.clients.UserClient : [UserClient#findById] <--- ERROR HttpHostConnectException: Connect to 192.168.8.103:8081 [/192.168.8.103] failed: Connection refused: connect (2003ms)
-
正常
-
{"id":102,"price":209900,"name":"雅迪 yadea 新国标电动车","num":1,"userId":2,"user":{"id":2,"username":"文二狗","address":"陕西省西安市"}} ------------------------------------------------------ 02-17 10:22:15:165 DEBUG 10036 --- [nio-8080-exec-7] c.i.order.mapper.OrderMapper.findById : ==> Preparing: select * from tb_order where id = ? 02-17 10:22:15:165 DEBUG 10036 --- [nio-8080-exec-7] c.i.order.mapper.OrderMapper.findById : ==> Parameters: 102(Long) 02-17 10:22:15:166 DEBUG 10036 --- [nio-8080-exec-7] c.i.order.mapper.OrderMapper.findById : <== Total: 1 02-17 10:22:15:167 DEBUG 10036 --- [x-userService-4] cn.itcast.feign.clients.UserClient : [UserClient#findById] ---> GET http://userService/user/2 HTTP/1.1 02-17 10:22:15:329 DEBUG 10036 --- [x-userService-4] cn.itcast.feign.clients.UserClient : [UserClient#findById] <--- HTTP/1.1 200 (160ms)