• Spring Cloud:三【详细】


    目录

    Http客户端Feign

    Feign的使用

    Feign自定义配置

    第一种方式

    第二种方式

    Feign的优化

    Feign最佳实践方式

    实现一

    实现二


    Http客户端Feign

    RestTemplate缺点是,url不统一,编写困难,可读性差,参数复杂难以维护。

    这时我们可以使用Feign来代替RestTemplate。

    Feign是一个声明式的http客户端。

    Feign的使用

    1、引入依赖spring-cloud-starter-openfeign

    1. <dependency>
    2. <groupId>org.springframework.cloudgroupId>
    3. <artifactId>spring-cloud-starter-openfeignartifactId>
    4. dependency>

    2、在启动类上添加注解@EnableFeignClients

    3、定义Feign接口

    1. @FeignClient("user-server")
    2. public interface UserClient {
    3. @GetMapping("/user/{id}")
    4. User findById(@PathVariable("id")Long id);
    5. }

    4、修改Service类中的代码

    1. @Service
    2. public class OrderService {
    3. @Autowired
    4. private OrderMapper orderMapper;
    5. @Autowired
    6. private userClient userClient;
    7. public Order queryOrderById(Long orderId){
    8. Order order = orderMapper.findById(orderId);
    9. Long userId = order.getUserId();
    10. User user = userClient.getById(userId);
    11. order.setUser(user);
    12. return order;
    13. }
    14. }

    访问地址发现可以正常调用其他模块的方法。

    需要注意的是Feign内部也是实现了负载均衡。内部集成了Ribbon

    Feign自定义配置

    Feign可以使用自定义配置去覆盖原始默认配置。可以修改的配置如下图

    通常我们只需要修改日志级别(默认为NONE,什么也不打印)

    第一种方式

    修改配置文件

    1. feign:
    2. client:
    3. config:
    4. default: #defaule就是全局配置,如果是写具体服务名,则是针对某个微服务的配置
    5. loggerLevel: FULL

    除了打印SQL语句还打印了其他信息

    第二种方式

    添加配置类

    1. public class FeignClientConfiguration {
    2. @Bean
    3. public Logger.Level feignLogLevel(){
    4. return Logger.Level.BASIC;
    5. }
    6. }

    不需要添加配置注解。如果在启动类上添加如下信息,表示全局生效

    @EnableFeignClients(defaultConfiguration = FeignClientConfiguration.class)

    如果在Client类上添加如下信息,表示局部生效

    1. @FeignClient(value = "user-server",configuration= FeignClientConfiguration.class)
    2. public interface UserClient {
    3. @GetMapping("/user/{id}")
    4. User findById(@PathVariable("id")Long id);
    5. }

    Feign的优化

    Feign的优化点在于更换默认使用的底层客户端实现,默认使用是URLConnection,它不支持连接池。

    可以使用以下两种客户端实现

    • HttpClient:支持连接池
    • OKHttp:支持连接池

    其次优化点在于日志打印,一般我们不需要打印任何多余的日志,日志级别采用NONE即可,在调试的时候可以选择BASIC。

    更改底层客户端实现:

    引入依赖,去配置文件中配置连接池

    1. <dependency>
    2. <groupId>io.github.openfeigngroupId>
    3. <artifactId>feign-httpclientartifactId>
    4. dependency>
    1. feign:
    2. client:
    3. config:
    4. default: #defaule就是全局配置,如果是写具体服务名,则是针对某个微服务的配置
    5. loggerLevel: NONE
    6. httpclient:
    7. enabled: true # 引入依赖后,需要手动配置开启httpClient
    8. max-connections: 200 # 最大连接数
    9. max-connections-per-route: 50 # 每个路径最大连接数

    Feign最佳实践方式

    一:由于Client就是发送Http请求所以请求路径和Controller的完全一样,因此给Client和Controller定义统一接口,让Client和Controller去继承和实现这个接口。所有的方法都写在父类接口中。

    二:将FeignClient抽取为独立模块,把接口有关的POJO和默认配置放入独立模块中,其他服务需要调用Client时直接引入依赖调用

    缺点:当模块A只需要模块B中的一两个方法时,仍然需要将所有方法都引入模块A中。

    实现一

    首先创建一个模块里面定义API接口

    1. public interface UserAPI {
    2. @GetMapping("/user/{id}")
    3. User findById(@PathVariable("id")Long id);
    4. }

    在订单模块下引入feign-api模块,并编写Client类

    1. <dependency>
    2. <groupId>com.zmtgroupId>
    3. <artifactId>feign-apiartifactId>
    4. <version>1.0version>
    5. dependency>
    1. @FeignClient("user-server")
    2. public interface UserClient extends UserAPI {
    3. }

    在用户模块下引入fegin-api依赖并编写Controller类

    1. @RestController
    2. @RequestMapping("/user")
    3. public class UserController implements UserAPI {
    4. @Autowired
    5. private UserService userService;
    6. @Override
    7. public User findById(Long id) {
    8. return null;
    9. }
    10. }

    缺点:耦合度高、父接口中的参数列表中的映射关系不会被继承

    实现二

    仍然是创建一个feign-api模块,将其他模块中的Client类移动到feign-api模块中,其次移动相关配置类与实体类

    在订单模块中引入feign-api模块

    1. <dependency>
    2. <groupId>xxxxxgroupId>
    3. <artifactId>feign-apiartifactId>
    4. <version>1.0version>
    5. dependency>

    将原来模块中文件导入修改为feign-api中的路径即可

    但是有一个问题,在订单模块中无法注入UserClient对象,因为OrderApplication中无法扫描另一个模块中的包。为了解决这个问题,有两种方案,一种是在启动类上添加包扫描,另一种是在启动类上指定客户端字节码文件。

    1. // 方法一
    2. @EnableFeignClients(basePackages = "cn.itcast.feign.clients")
    3. // 方法二(推荐)
    4. @EnableFeignClients(clients = {UserClient.class})

    启动观察:

  • 相关阅读:
    python---字符串
    css吃豆豆动画
    【无标题】
    Modelsim的仿真之路(Memory小技能)
    FPGA - 7系列 FPGA内部结构之Clocking -04- 多区域时钟
    【文本检测与识别白皮书-3.2】第二节:基于注意力机制和CTC的场景文本识别方法的对比
    Pandas DataFrame 的可视化工具大全
    iNFTnews|为什么说NFT门票是音乐行业的未来?
    基础:types of keys
    SpringBoot整合Flowable
  • 原文地址:https://blog.csdn.net/zmbwcx/article/details/134095135