【SpringCloud】4.0 新一代负载均衡组件Open-feign

原先ribbon代码存在的问题:不规范,风格不统一,维护性比较差

什么是Feign

  • SpringCloud提供的伪http客户端(本质还是用http),封装了Http调用流程,更适合面向接口化,用Java接口注解的方式调用Http请求
  • 不用像Ribbon中通过封装HTTP请求报文的方式调用 Feign默认集成了Ribbon
  • Nacos支持Feign,可以直接集成实现负载均衡的效果

Ribbon和feign两个的区别和选择

  • 选择feign
  • 默认集成了ribbon
  • 写起来更加思路清晰和方便
  • 采用注解方式进行配置,配置熔断等方式方便

官方文档

https://spring.io/projects/spring-cloud-openfeign

接入 Open-feign (相关代码完整版放在本文最后部分)

在之前章节的基础上,online-edu\pom.xml增加依赖:

            <!-- 负载均衡-openfeign -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-openfeign</artifactId>
                <version>4.1.3</version>
            </dependency>

online-edu-order-service/pom.xml

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

online-edu-order-service/src/main/java/org/online_edu/OrderApplication.java


package org.online_edu;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication()
@MapperScan("org.online_edu.dao")
// 开启服务发现
@EnableDiscoveryClient
// 开启openfeign负载均衡支持
@EnableFeignClients
public class OrderApplication {

    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class, args);
    }

    @Bean
    @LoadBalanced
    public RestTemplate getRestTemplate() {
        return new RestTemplate();
    }
}

online-edu-order-service/src/main/java/org/online_edu/controller/VideoOrderController.java

package org.online_edu.controller;

import org.online_edu.domain.Video;
import org.online_edu.domain.VideoOrder;
import org.online_edu.service.VideoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;

@RestController
@RequestMapping("/api/v1/video_order")
public class VideoOrderController {

    /**
     * 服务对象
     */
    @Autowired
    private VideoService videoService;

    @RequestMapping("/find_by_id")
    public Object save(@RequestParam(name = "videoId") int videoId) {

        Video video = videoService.findById(videoId);
        VideoOrder videoOrder = new VideoOrder();
        if (video != null) {
            videoOrder.setServeInfo(video.getServeInfo());
            videoOrder.setVideoId(video.getId());
            videoOrder.setVideoTitle(video.getTitle());
            videoOrder.setCreateTime(new Date());
        }
        return videoOrder;
    }
}


online-edu-order-service/src/main/java/org/online_edu/service/VideoService.java

package org.online_edu.service;

import org.online_edu.domain.Video;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

@FeignClient(value = "online-edu-video-service")
public interface VideoService {
    @GetMapping(value = "/api/v1/video/find_by_id")
    Video findById(@RequestParam("videoId") int videoId);
}

online-edu-video-service/src/main/java/org/online_edu/controller/VideoController.java

package org.online_edu.controller;

import jakarta.servlet.http.HttpServletRequest;
import org.online_edu.domain.Video;
import org.online_edu.service.VideoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("api/v1/video")
public class VideoController {
    @Autowired
    private VideoService videoService;


    @RequestMapping("/find_by_id")
    public Video findById(@RequestParam(name = "videoId") int videoId, HttpServletRequest request) {
        Video video = videoService.findById(videoId);
        // 拿到服务端的id+端口
        video.setServeInfo(request.getServerName() + ":" + request.getServerPort());
        return video;
    }
}

完整代码如下:
online-edu\pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.online_edu</groupId>
    <artifactId>online-edu</artifactId>
    <version>1.0-SNAPSHOT</version>

    <modules>
        <module>online-edu-common</module>
        <module>online-edu-video-service</module>
        <module>online-edu-user-service</module>
        <module>online-edu-order-service</module>
        <module>online-edu-generator</module>
    </modules>
    <!-- 一般来说父级项目的packaging都为pom,packaging默认类型jar类型-->
    <packaging>pom</packaging>

    <properties>
        <java.version>21</java.version>
        <maven.compiler.source>21</maven.compiler.source>
        <maven.compiler.target>21</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <!-- **************************** 分布式核心 **************************** -->
        <spring-boot-dependencies.version>3.3.4</spring-boot-dependencies.version>
        <spring-cloud-dependencies.version>2023.0.5</spring-cloud-dependencies.version>
        <spring-cloud-alibaba-dependencies.version>2023.0.3.2</spring-cloud-alibaba-dependencies.version>
        <spring-cloud-starter-loadbalancer.version>4.2.1</spring-cloud-starter-loadbalancer.version>
        <spring-cloud-starter-openfeign.version>4.2.1</spring-cloud-starter-openfeign.version>
        <!-- **************************** 分布式核心 **************************** -->
        <!-- **************************** 数据库依赖 **************************** -->
        <mybatis-plus-spring-boot3-starter.version>3.5.10.1</mybatis-plus-spring-boot3-starter.version>
        <mybatis-plus-generator.version>${mybatis-plus-spring-boot3-starter.version}</mybatis-plus-generator.version>
        <postgresql.version>42.7.5</postgresql.version>
        <druid-spring-boot-3-starter.version>1.2.24</druid-spring-boot-3-starter.version>
        <pagehelper-spring-boot-starter.version>2.1.0</pagehelper-spring-boot-starter.version>
        <!-- **************************** 数据库依赖 **************************** -->
        <!-- **************************** 工具类 **************************** -->
        <org.mapstruct.version>1.6.0</org.mapstruct.version>
        <commons-collections4.version>4.5.0-M3</commons-collections4.version>
        <guava.version>33.4.5-jre</guava.version>
        <hutool-all.version>5.8.36</hutool-all.version>
        <!-- **************************** 工具类 **************************** -->
    </properties>
    <!--锁定版本-->
    <dependencyManagement>
        <dependencies>
            <!-- **************************** 分布式核心 **************************** -->
            <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-dependencies -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot-dependencies.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-dependencies -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud-dependencies.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!-- https://mvnrepository.com/artifact/com.alibaba.cloud/spring-cloud-alibaba-dependencies -->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>${spring-cloud-alibaba-dependencies.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-loadbalancer -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-loadbalancer</artifactId>
                <version>${spring-cloud-starter-loadbalancer.version}</version>
            </dependency>
            <!-- 负载均衡-openfeign -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-openfeign</artifactId>
                <version>${spring-cloud-starter-openfeign.version}</version>
            </dependency>
            <!-- **************************** 分布式核心 **************************** -->

            <!-- **************************** 数据库依赖 **************************** -->
            <!-- MyBatis-Plus启动器,增强版MyBatis,提供更高效的操作和动态SQL能力 -->
            <!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-spring-boot3-starter -->
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-spring-boot3-starter</artifactId>
                <version>${mybatis-plus-spring-boot3-starter.version}</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-generator -->
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-generator</artifactId>
                <version>${mybatis-plus-generator.version}</version>
            </dependency>
            <!-- PostgreSQL的JDBC驱动 -->
            <!-- https://mvnrepository.com/artifact/org.postgresql/postgresql -->
            <dependency>
                <groupId>org.postgresql</groupId>
                <artifactId>postgresql</artifactId>
                <version>${postgresql.version}</version>
            </dependency>
            <!-- Druid组件 -->
            <!-- https://mvnrepository.com/artifact/com.alibaba/druid-spring-boot-3-starter -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid-spring-boot-3-starter</artifactId>
                <version>${druid-spring-boot-3-starter.version}</version>
            </dependency>

            <!-- https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper-spring-boot-starter -->
            <dependency>
                <groupId>com.github.pagehelper</groupId>
                <artifactId>pagehelper-spring-boot-starter</artifactId>
                <version>${pagehelper-spring-boot-starter.version}</version>
            </dependency>

            <!-- **************************** 数据库依赖 **************************** -->

            <!-- **************************** 工具类 **************************** -->
            <!-- 一个用于在 Java Bean 之间转换的代码生成工具。-->
            <!-- 官网:https://mapstruct.org/ -->
            <!-- https://mvnrepository.com/artifact/org.mapstruct/mapstruct -->
            <dependency>
                <groupId>org.mapstruct</groupId>
                <artifactId>mapstruct</artifactId>
                <version>${org.mapstruct.version}</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/org.mapstruct/mapstruct-processor -->
            <dependency>
                <groupId>org.mapstruct</groupId>
                <artifactId>mapstruct-processor</artifactId>
                <version>${org.mapstruct.version}</version>
            </dependency>
            <!--         commons-lang3:  通用的、可复用的 Java 组件,已其他包引入-->
            <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->

            <!--(Map、List、Set集合全覆盖)集合开发工具-->
            <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-collections4 -->
            <dependency>
                <groupId>org.apache.commons</groupId>
                <artifactId>commons-collections4</artifactId>
                <version>${commons-collections4.version}</version>
            </dependency>
            <!-- Java增强器,像Java Next版本-->
            <!-- 集合 [collections] 、缓存 [caching] 、原生类型支持 [primitives support] 、
            并发库 [concurrency libraries] 、通用注解 [common annotations] 、
            字符串处理 [string processing] 、I/O 等等-->
            <!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
            <dependency>
                <groupId>com.google.guava</groupId>
                <artifactId>guava</artifactId>
                <version>${guava.version}</version>
            </dependency>
            <!-- Java必备工具库 -->
            <!-- https://mvnrepository.com/artifact/cn.hutool/hutool-all -->
            <dependency>
                <groupId>cn.hutool</groupId>
                <artifactId>hutool-all</artifactId>
                <version>${hutool-all.version}</version>
            </dependency>
            <!-- JSON序列化和反序列化 :已由别的包引入-->
            <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
            <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
            <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
            <!-- **************************** 工具类 **************************** -->

        </dependencies>
    </dependencyManagement>
    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                    <configuration>
                        <addResources>true</addResources>
                    </configuration>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>
</project>

online-edu-order-service/pom.xml

 <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.online_edu</groupId>
        <artifactId>online-edu</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <artifactId>online-edu-order-service</artifactId>

    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.online_edu</groupId>
            <artifactId>online-edu-common</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

        <!--        <dependency>-->
        <!--            <groupId>com.alibaba.cloud</groupId>-->
        <!--            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>-->
        <!--        </dependency>-->
        <!-- 添加nacos客户端——服务注册 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-spring-boot3-starter</artifactId>
        </dependency>
        <!-- PostgreSQL的JDBC驱动 -->
        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-3-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
    </dependencies>
</project>

运行:


image.png

Post传输对象

online-edu-order-service/src/main/java/org/online_edu/controller/VideoOrderController.java

    @PostMapping("/save")
    public void save(@RequestBody Video video) {
        videoService.save(video);
    }

online-edu-order-service/src/main/java/org/online_edu/service/VideoService.java

    @PostMapping(value = "/api/v1/video/save")
    int save(@RequestBody Video video);

online-edu-video-service/src/main/java/org/online_edu/controller/VideoController.java

    /**
     * 测试 feign 调用 使用post方法传输对象
     *
     * @param video
     * @return
     */
    @PostMapping("/save")
    public Object save(@RequestBody Video video) {
        int rows = videoService.save(video);
        System.out.println(video.getTitle());
        HashMap<String, Object> map = new HashMap<>();
        map.put("row", rows);
        return map;
    }

online-edu-video-service/src/main/java/org/online_edu/service/VideoService.java


    int save(Video video);

online-edu-video-service/src/main/java/org/online_edu/service/impl/VideoServiceImpl.java

    /**
     * @param video
     * @return
     */
    @Override
    public int save(Video video) {
        return 1;
    }

运行:
Header中的Content-Type设置成application/json

image.png

image.png

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容