5-Spring cloud之Feign的使用——服务器上实操

news2024/11/18 11:21:17

5-Spring cloud之Feign的使用——服务器上实操

  • 1. 前言
  • 2. 搭建Feign
    • 2.1 添加子模块——`dog-api`
      • 2.1.1 子模块结构
      • 2.1.2 pom文件
      • 2.1.3 核心接口DogClientApi
    • 2.2 添加子模块——`dog-consumer-feign-80`
      • 2.2.1 子模块结构
      • 2.2.2 pom文件
      • 2.2.3 yml文件
      • 2.2.4 主启动类
      • 2.2.5 controller
    • 2.3 测试看效果(本地单机)
    • 2.4 测试看效果(服务器看负载均衡)
    • 2.5 关于Feign自定义负载均衡
  • 3. 注意问题以及常见问题
    • 3.1 注意问题
    • 3.2 遇到的问题
      • 3.2.1 feign.FeignException: status 404 reading DogClientApi#
  • 4. 总结Feign
    • 4.1 什么是Feign?为什么要使用Feign?
      • 4.1.1 什么是Feign?
      • 4.1.2 为什么要使用Feign?
      • 4.1.3 Feign 和 Ribbon
    • 4.2 Feign依赖注入原理
    • 4.3 自动装载和动态代理机制源码剖析

1. 前言

  • 前几篇文章,有需要的自行查看
    • 1-Eureka服务注册与发现以及Eureka集群搭建(实操型).
    • 2-Spring cloud之Eureka快速剔除失效服务
    • 3-Spring cloud之搭建Ribbon负载均衡——服务器上实操(上)
    • 4-Spring cloud之搭建Ribbon负载均衡——服务器上实操(下)
  • 本篇文章是在续前缘,……

2. 搭建Feign

2.1 添加子模块——dog-api

2.1.1 子模块结构

  • 如下:
    在这里插入图片描述

2.1.2 pom文件

  • 核心配置

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

    在这里插入图片描述

  • 完整文件

    <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>com.liu.susu</groupId>
            <artifactId>dog-cloud-parent</artifactId>
            <version>1.0-SNAPSHOT</version>
        </parent>
    
        <artifactId>dog-api</artifactId>
        <packaging>jar</packaging>
    
        <name>dog-api</name>
        <url>http://maven.apache.org</url>
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        </properties>
    
        <dependencies>
    
            <dependency>
                <groupId>com.liu.susu</groupId>
                <artifactId>dog-po</artifactId>
                <version>${project.version}</version>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-feign</artifactId>
            </dependency>
    
        </dependencies>
    </project>
    
    

2.1.3 核心接口DogClientApi

  • 如下:
    在这里插入图片描述

    package com.liu.susu.api;
    
    import com.liu.susu.pojo.Dog;
    import org.springframework.cloud.netflix.feign.FeignClient;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    
    import java.util.List;
    
    /**
     * @Description
     * @Author susu
     */
    @FeignClient(value = "DOG-PROVIDER")
    public interface DogClientApi {
    
        @RequestMapping(value = "/dog/hello",method = RequestMethod.GET)
        String hello();
    
        @RequestMapping(value = "/dog/getDogByNum/{dogNum}",method = RequestMethod.GET)
        Object getDogByNum(@PathVariable("dogNum") Long dogNum);
    
        @RequestMapping("/dog/getAllDog")
        List<Dog> getAllDog();
    
    }
    
    

2.2 添加子模块——dog-consumer-feign-80

2.2.1 子模块结构

  • 如下:
    在这里插入图片描述

2.2.2 pom文件

  • 如下:
    在这里插入图片描述
    在这里插入图片描述

    <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>com.liu.susu</groupId>
            <artifactId>dog-cloud-parent</artifactId>
            <version>1.0-SNAPSHOT</version>
        </parent>
    
        <artifactId>dog-consumer-feign-80</artifactId>
        <packaging>jar</packaging>
    
        <name>dog-consumer-feign-80</name>
        <url>http://maven.apache.org</url>
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>com.liu.susu</groupId>
                <artifactId>dog-api</artifactId>
                <version>${project.version}</version>
            </dependency>
    
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <scope>test</scope>
            </dependency>
    
            <!--下面这几个,版本同${spring-boot.version}-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <!--热部署  版本同${spring-boot.version}-->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>springloaded</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-devtools</artifactId>
            </dependency>
    
            <!--引入Feign相关依赖-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-feign</artifactId>
            </dependency>
    
            <!-- 因为feign内集成了ribbon,所以spring-cloud-starter-ribbon依赖可以不加-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-eureka</artifactId>
            </dependency>
    <!--        <dependency>-->
    <!--            <groupId>org.springframework.cloud</groupId>-->
    <!--            <artifactId>spring-cloud-starter-ribbon</artifactId>-->
    <!--        </dependency>-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-config</artifactId>
            </dependency>
    
        </dependencies>
    
    </project>
    
    

2.2.3 yml文件

  • 和单独使用ribbon时一样,如下:
    在这里插入图片描述

    server:
      port: 80
    
    spring:
      application:
        name: dog-consumer-feign
    
    eureka:
      client:  # 客户端注册进eureka服务列表内
        register-with-eureka: false  # false表示不向注册中心注册自己
        service-url:
          defaultZone: http://IP1:2886/eureka/,http://IP2:2886/eureka,http://IP3.175:2886/eureka/
    

2.2.4 主启动类

  • 如下:
    在这里插入图片描述
    package com.liu.susu;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
    import org.springframework.cloud.netflix.feign.EnableFeignClients;
    
    @SpringBootApplication
    @EnableEurekaClient
    /**
     * 在该注解中添加 FeignClient 的所在包,以便Spring容器能够扫描到所有的FeignClient,并进行托管。
     * 后面我们便可以使用 @Autowired 注解自动导入了
     */
    @EnableFeignClients(basePackages = {"com.liu.susu.api"}) //开启Fiegn功能
    public class DogConsumerFeignApp
    {
        public static void main( String[] args ) {
    
            SpringApplication.run(DogConsumerFeignApp.class, args);
            System.out.println( "Hello feign!" );
        }
    }
    
    

2.2.5 controller

  • 这里的路径可以随便定义,但是API下的必须与服务提供者的路径一致
    在这里插入图片描述

    package com.liu.susu.controller;
    
    import com.liu.susu.api.DogClientApi;
    import com.liu.susu.pojo.Dog;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.RestController;
    
    import java.util.List;
    
    /**
     * @Description
     * @Author susu
     */
    @RestController
    public class DogConsumerFeignController {
    
        @Autowired
        private DogClientApi dogClientApi;
    
        //http://localhost:80/consumer/dog/hello
        @RequestMapping(value = "/consumer/dog/hello")
        public String hello(){
            System.out.println("hello========");
            return dogClientApi.hello();
        }
    
        @RequestMapping(value = "/consumer/dog/getDogByNum/{dogNum}",method = RequestMethod.GET)
        public Object getDogByNum(@PathVariable("dogNum") Long dogNum){
            return dogClientApi.getDogByNum(dogNum);
        }
    
        @RequestMapping("/consumer/dog/getAllDog")
        List<Dog> getAllDog(){
            return dogClientApi.getAllDog();
        }
    
    
    }
    
    

2.3 测试看效果(本地单机)

  • 启动,服务提供者8001 和 feign80,如下
    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述

2.4 测试看效果(服务器看负载均衡)

  • 首先,将本地的8001停掉,启动服务器上的其中3台8001,如下:
    在这里插入图片描述
  • 然后重新访问,看效果(可见,可访问,并且自带负载均衡,默认是轮询
    http://localhost/consumer/dog/getDogByNum/1
    
    在这里插入图片描述

2.5 关于Feign自定义负载均衡

  • 用法同只用ribbon时,一样的用法,如下:
    在这里插入图片描述
    在这里插入图片描述
  • 更多负载的详细配置,请看上篇文章吧:
    4-Spring cloud之搭建Ribbon负载均衡——服务器上实操(下).

3. 注意问题以及常见问题

3.1 注意问题

  • 注意 DogClientApi 的注入问题,启动类上下面注解包路径要对,否则注入不上,如下:
    @EnableFeignClients(basePackages = {"com.liu.susu.api"}) //开启Fiegn功能
    //@EnableFeignClients(basePackages = {"com.liu.susu"}) 可以往上,被包括就行
    
    在这里插入图片描述
    在这里插入图片描述

3.2 遇到的问题

3.2.1 feign.FeignException: status 404 reading DogClientApi#

  • 问题描述:
    feign.FeignException: status 404 reading DogClientApi#getDogByNum(Long); content:
    {"timestamp":1688683822011,"status":404,"error":"Not Found","message":"Not Found","path":"/consumer/dog/getDogByNum/1"}
    
    在这里插入图片描述
  • 问题原因
    DogClientApi 里的映射路径和 服务提供者的controller里的映射路径不一致。
    • 看一下服务提供者的controller里的路径
      在这里插入图片描述
    • 再看一下DogClientApi里的路径
      在这里插入图片描述
  • 解决问题:
    去掉DogClientApi里的路径 /consumer,如下:
    在这里插入图片描述
  • 然后重新启动,问题已解决
    在这里插入图片描述

4. 总结Feign

4.1 什么是Feign?为什么要使用Feign?

4.1.1 什么是Feign?

  • Feign是一个声明式WebService客户端,使用Feign能让编写WebService客户端更加简单(只需要创建一个接口,然后上面加上注解@FeignClient(value = "DOG-PROVIDER")即可),即:Feign的主要目标是降低大家使用Http API的复杂性。
  • 其实,Feign底层依赖于Java的动态代理机制,对原生Java Socket或者Apache HttpClient进行封装,实现了基于Http协议的远程过程调用。当然,Feign还在此基础上实现了负载均衡、熔断等机制。
  • Feign自带负载均衡配置项,因为它集成了Ribbon

4.1.2 为什么要使用Feign?

  • 使用Feign可以使得编写Web Service客户端变得更加简单、方便、快捷,提高代码的可读性、可维护性、可靠性和可用性。比如:
    • 声明式的API:通过定义接口并注解它,Feign可以自动构造出符合该接口定义的Web Service客户端,使得客户端代码更加简洁、易读、易维护。像调用本地方法即可,从而提高了编码效率。
    • 集中管理 Http 请求方法,代码边界更加清晰。
    • 支持负载均衡:Feign内置了负载均衡功能( Ribbon),可以根据配置的负载均衡策略,自动选择可用的服务实例进行请求,从而提高系统的可用性和可靠性。
    • 支持熔断器:Feign还支持熔断器功能,可以在服务不可用或超时的情况下,自动降级或熔断服务,从而保证系统的稳定性和可用性。

4.1.3 Feign 和 Ribbon

  • Feign 是一个声明式的 Web Service客户端,它将服务调用抽象为接口定义,可以使得客户端代码更加简洁、易读、易维护;
    Feign还内置了负载均衡和熔断器等功能。
  • 而 Ribbon 是一个客户端负载均衡器,它通过配置负载均衡策略来选择可用的服务实例进行请求。

4.2 Feign依赖注入原理

  • @EnableFeignClients 注解是开启 Fiegn 功能的关键,通常会在该注解中添加FeignClient 的所在包,以便 Spring 容器能够扫描到所有的FeignClient,并进行托管。后面我们便可以使用@Autowired注解自动导入了。
    在这里插入图片描述
    在这里插入图片描述

4.3 自动装载和动态代理机制源码剖析

  • 更多源码以及原理分析,可以参考下面的文章
    Feign底层原理分析-自动装载&动态代理.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/726978.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux里git的使用

git的使用 一.前置要求1.git的安装2.注册Gitee并创建仓库 二.git三板斧 一.前置要求 1.git的安装 2.注册Gitee并创建仓库 然后记住下面的网址。 之后将仓库克隆到云服务器里。记得输入gitee的账号和密码。 查看目录&#xff0c;可以发现仓库已经在目录里了。 进入目录&#xf…

python毕设课设大作业《火车票分析助手》程序

在PyCharm中运行《火车票分析助手》即可进入如图1所示的系统主界面。 图1 系统主界面 具体的操作步骤如下&#xff1a; &#xff08;1&#xff09;在主界面“车票查询”选项卡中依次输入&#xff0c;出发地、目的地以及出发时间&#xff0c;然后单击“查询”按钮&#xff0c;…

十九、Jenkins版本构建完成,触发自动化测试

十九、Jenkins版本构建完成&#xff0c;触发自动化测试 1.构建后操作-Build other projects 2.关联自动化测试工程 这样版本构建完成&#xff0c;就会执行自动化测试

金九银十跳槽涨薪Java面试题!568页真题+答案解析,大厂都在考

2023年一半又过去了&#xff0c;各大企业的招聘也又开始大量放岗了&#xff0c;各位苟着的小伙伴们要抓住机会了&#xff01; 但很多小伙伴对面试不够了解&#xff0c;不知道如何准备&#xff0c;对面试环节的设置以及目的不了解&#xff0c;尤其是面试题还很难&#xff0c;有些…

RocketMQ5.0--事务消息

RocketMQ5.0–事务消息 一、事务消息概览 RocketMQ事务消息的实现原理基于两阶段提交和定时事务状态回查来决定消息最终是提交还是回滚&#xff0c;消费者可以消费事务提交的消息&#xff0c;如下图所示。事务消息的作用&#xff1a;确保本地业务与消息在一个事务内&#xff0…

成功解决:java file outside of source root

前言 我复制一个很小项目的代码&#xff0c;然后重新命名后。用IDEA打开&#xff0c;发现.java文件的左下方有个橘色的标志。 1、问题文件 这里显示 Java file outside of source root。 查阅资料发现&#xff1a;这个问题是指Java文件不在源代码根目录之内。这可能会导致…

使用pytest命令行实现环境切换

目录 前言 pytest_addoption(parser, pluginmanager) 在conftest.py文件中定义命令行参数 获取命令行参数 设置不同环境的全局变量 定义测试类及测试方法 测试验证 前言 在自动化测试过程中经常需要在不同的环境下进行测试验证&#xff0c;所以写自动化测试代码时需要考…

Android12之IBinder中[[clang::lto_visibility_public]]作用(一百六十)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

MySQL自治平台建设的内核原理及实践(上)

总第565篇 2023年 第017篇 本文整理自美团技术沙龙第75期的主题分享《美团数据库攻防演练建设实践》&#xff0c;系超大规模数据库集群保稳系列&#xff08;内含4个议题的PPT及视频&#xff09;的第4篇文章。 本文作者在演讲后根据同学们的反馈&#xff0c;补充了很多技术细节&…

如何绘制「UML类图」

一、UML类图简介 类图以反映类的结构(属性、操作)以及类之间的关系为主要目的&#xff0c;描述了软件系统的结构&#xff0c;是一种静态建模方法。类图用来描述系统中有意义的概念&#xff0c;包括具体的概念、抽象的概念、实现方面的概念等&#xff0c;是对现实世界中事物的抽…

设计模式--------结构型模式

结构型模式 结构型模式描述如何将类或对象按某种布局组成更大的结构。它分为类结构型模式和对象结构型模式&#xff0c;前者采用继承机制来组织接口和类&#xff0c;后者釆用组合或聚合来组合对象。 由于组合关系或聚合关系比继承关系耦合度低&#xff0c;满足“合成复用原则”…

web 页面布局:(三)position 坐标系布局

web 页面布局&#xff1a;&#xff08;三&#xff09;position 坐标系布局 页面坐标系position 设置fixedrelativeabsolutesticky 应用场景 页面坐标系 因为所有文本内容&#xff0c;是从左向右读&#xff0c;自上而下读&#xff0c;和书写习惯&#xff0c;读书习惯一致&#…

惊呆了!这个银行管理技巧也太厉害了吧

在金融行业&#xff0c;蓄电池监控是一项至关重要的任务。随着金融机构的数字化转型和依赖电力的增加&#xff0c;蓄电池成为保障金融系统正常运行的关键组成部分。 因此&#xff0c;对蓄电池的状态进行监控和维护&#xff0c;确保其高效可靠地工作&#xff0c;对金融行业的稳定…

深度学习06-pytorch从入门到精通

文章目录 概述环境准备安装cuda和cudnn安装pytorch 基础张量定义numpy转换数学函数随机数计算函数矩阵处理函数 自动梯度案例计算图 torchvision模块TransformsDataSetDataLoader自定义数据集 nn模块nn.ModuleCNN图像处理层nn.Conv2dnn.AvgPool2d和nn.MaxPool2dnn.Linearnn.Bat…

TransFuse

方法 Transformer分支 将不同尺度的特征图 t 0 、 t 1 和 t 2 t^0、t^1和t^2 t0、t1和t2保存起来&#xff0c;之后与对应的CNN分支的特征图融合。 CNN分支 以基于ResNet的模型为例&#xff0c;模型通常有五个块&#xff0c;每个块对特征图进行两倍下采样。我们获取第 4( g 0…

vue父组件调用子组件的Form表单校验

需求1&#xff1a;父组件调用子组件的表单验证方法&#xff0c;验证成功&#xff0c;继续进行接下来的操作&#xff0c;验证失败&#xff0c;提示用户并返回。 需求2&#xff1a;父组件校验多个子组件的表单验证方法&#xff0c;验证成功&#xff0c;继续进行接下来的操作&…

cookie/session/token(持续更新)

1.cookie 1.1概念 cookie是服务器产生的保存在客户端的一小段文本信息,格式是字典形式,键值对形式 cookie有两类: 1.会话级cookie:保存在内存,随浏览器关闭自动消息 2.持久化cookie:保存在硬盘,浏览器关闭不会直接消失,生命周期取决于失效时间 1.2如何查看cookie以及格式…

vue3+vite+element pro + pnpm 创建的monorepo项目

vue3+vite+element pro + pnpm 创建的monorepo项目 欢迎使用河码桌面技术说明界面欢迎使用河码桌面 欢迎使用河码桌面,河码桌面是一个基于vue3+vite+element pro + pnpm 创建的monorepo项目,项目采用的是类操作系统的web界面,操作起来简单又方便,符合用户习惯,又没有操作…

GlusterFs部署及使用

目录 一、部署和使用 1. clusterfs服务器初始化 2. 部署glusterfs 3. 创建volume 4. 客户端挂载和使用 5. k8s使用glusterfs作为后端存储&#xff08;静态供给glusterfs存储&#xff09; 5.1 集群所有节点安装glusterfs客户端 5.2 k8s创建资源对象使用glusterfs存储 5.…

Spring Boot 中的声明式事务是什么,如何使用

Spring Boot 中的声明式事务是什么&#xff0c;如何使用 简介 在数据库操作中&#xff0c;事务是一组操作的集合&#xff0c;这些操作在一个逻辑单元内执行&#xff0c;如果其中任何一个操作失败&#xff0c;则整个事务都会被回滚&#xff0c;使得数据库回到事务执行之前的状…