【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.3</spring-boot-dependencies.version>
        <spring-cloud-dependencies.version>2023.0.3</spring-cloud-dependencies.version>
        <spring-cloud-alibaba-dependencies.version>2023.0.1.2</spring-cloud-alibaba-dependencies.version>
        <org.mapstruct.version>1.6.0</org.mapstruct.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>4.1.4</version>
            </dependency>
            <!-- 负载均衡-openfeign -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-openfeign</artifactId>
                <version>4.1.3</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>3.5.7</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-generator -->
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-generator</artifactId>
                <version>3.5.7</version>
            </dependency>
            <!-- PostgreSQL的JDBC驱动 -->
            <!-- https://mvnrepository.com/artifact/org.postgresql/postgresql -->
            <dependency>
                <groupId>org.postgresql</groupId>
                <artifactId>postgresql</artifactId>
                <version>42.7.3</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>1.2.23</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>2.1.0</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>4.5.0-M2</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>33.3.0-jre</version>
            </dependency>
            <!-- Java必备工具库 -->
            <!-- https://mvnrepository.com/artifact/cn.hutool/hutool-all -->
            <dependency>
                <groupId>cn.hutool</groupId>
                <artifactId>hutool-all</artifactId>
                <version>5.8.32</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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容