Feign远程调用结合fallback(Springboot包扫描)

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)
    
posted @ 2023-02-17 10:29  jentreywang  阅读(338)  评论(0编辑  收藏  举报