Feign远程接口调用

news2024/12/22 19:25:26

概述

目的:解决微服务调用问题。如何从微服务A调用微服务B提供的接口。

特性:

  • 声明式语法,简化接口调用代码开发。
  • 像调用本地方法一样调用其他微服务中的接口。
  • 集成了Eureka服务发现,可以从注册中心中发现微服务。
  • 集成了Spring Cloud LoadBalancer,提供客户端负载均衡。
  • 从调用发起方控制微服务调用的请求时间,防止服务雪崩。

使用Feign进行微服务调用

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

导入依赖

       <!--     springboot web start   -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--   引入nacos 注册中心依赖  注册服务   -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

        <dependency>
            <groupId>com.qf</groupId>
            <artifactId>common</artifactId>
        </dependency>

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

        <!--   引入nacos配置中心依赖     -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>
    </dependencies>

yml文件

spring:
  application:
    name: feign-demo #跟配置的前缀名字
  cloud:
    nacos:
      server-addr: 127.0.0.1:8848
      config:
        file-extension: yaml
  profiles:
    active: dev #跟配置的后缀 设备名匹配
logging:
  level:
    com.qf.feignconsumer.feign.UserFeignClient: debug
server:
  port: 9090
feign:
  client:
    config:
      default:
        # 建立连接的超时时间
        connectTimeout: 5000
        # 发送请求后等待接口响应结果的超时时间
        readTimeout: 3000

创建FeignClient接口

package com.qf.feignconsumer.feign;

import com.qf.common.entity.User;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@FeignClient("service-user")
public interface UserFeignClient {

    /**
     * 注意,如果少加了@RequestParam,会抛出如下异常
     * Caused by: java.lang.IllegalStateException: Method has too many Body parameters
     * @param pagenum
     * @param pagesize
     * @return
     * @throws InterruptedException
     */
    @GetMapping("/user/page")
    public List<User> getUserByPage(@RequestParam("pagenum") Integer pagenum,@RequestParam("pagesize")Integer pagesize) throws InterruptedException;

    @GetMapping("/user/getall")
    public List<User> getAll();

    @PostMapping("/user/update")
    public User updateUser(@RequestBody User user);

    @DeleteMapping("/user/delete/{id}")
    public User deleteUser(@PathVariable("id") Integer id);

}

使用主启动类

package com.qf.feignconsumer;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;

@SpringBootApplication
@EnableDiscoveryClient//注册到nacos中
@EnableFeignClients//注意:使用feign时 需要添加该注解
public class FeignApp9090 {
    public static void main(String[] args) {
        SpringApplication.run(FeignApp9090.class,args);
    }
}

FeignController

package com.qf.feignconsumer.controller;

import com.qf.common.entity.User;
import com.qf.common.vo.ResultVo;
import com.qf.feignconsumer.feign.ProviderFeigngClient;
import com.qf.feignconsumer.feign.UserFeignClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;


@RestController
public class FeignController {

    @Autowired
    UserFeignClient userFeignClient;
    @Autowired
    ProviderFeigngClient providerFeigngClient;

    @GetMapping("/u/test4")
    public ResultVo utest4() throws InterruptedException {
        List<User> userByPage = userFeignClient.getUserByPage(1, 2);
        return ResultVo.ok(1,"ok",userByPage);
    }




    @GetMapping("/echo")
    public ResultVo echo(String msg){
        String echo = providerFeigngClient.echo(msg);

        return ResultVo.ok(1,"asd",echo);
    }

    @GetMapping("/u/test1")
    public ResultVo utest1(){
        //使用feignclient发起微服务用
        List<User> users = userFeignClient.getAll();
        System.out.println(users);
        return ResultVo.ok(1,"ok",users);
    }

    @GetMapping("/u/test2")
    public ResultVo utest2(){
        //使用feignclient发起微服务用
        System.out.println("utest2");
        User user = new User(100, "luffy", "123");
        User user1 = userFeignClient.updateUser(user);
        return ResultVo.ok(1,"ok",user1);
    }

    @GetMapping("/u/test3")
    public ResultVo utest3(){
        //使用feignclient发起微服务用
        System.out.println("utest3");
        User user1 = userFeignClient.deleteUser(100);
        return ResultVo.ok(1,"ok",user1);
    }


}

日志配置类

package com.qf.feignconsumer.config;

import feign.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class FeignConfig {
    @Bean
    public Logger.Level liver(){
        /*
         * NONE:默认的,不显示任何日志
         * BASIC:仅记录请求方法、RUL、响应状态码及执行时间
         * HEADERS:除了BASIC中定义的信息之外,还有请求和响应的头信息
         * FULL:除了HEADERS中定义的信息之外,还有请求和响应的正文及元数据
         */
        return Logger.Level.FULL;
    }
}

提供服务方的controller

package com.qf.userprovider.controller;

import com.qf.common.entity.User;
import org.springframework.web.bind.annotation.*;

import java.util.Arrays;
import java.util.List;

@RestController
@RequestMapping("/user")
public class UserController {

    @GetMapping("/page")
    public List<User> getUserByPage(@RequestParam("pagenum") Integer pagenum,@RequestParam("pagesize")Integer pagesize) throws InterruptedException {
        User user = new User(1, "zhangsan1", "1234567");
        User user2 = new User(2, "lisi", "12345");
        Thread.sleep(5000);
        List<User> users = Arrays.asList(user, user2);
        return users;
    }




    @GetMapping("/getall")
    public List<User> getAll(){
        User user1 = new User(1, "zhangsan", "12345677");
        User user2 = new User(2, "lisi", "asdasdaas");

        List<User> users = Arrays.asList(user1, user2);

        return users;
    }


    @PostMapping("/update")
    public User updateUser(@RequestBody User user){

        System.out.println(user);
        //根据id更新用户
        user.setPassword("88889888");

        return user;
    }


    @DeleteMapping("/delete/{id}")
    public User deleteUser(@PathVariable("id") Integer id){

        System.out.println("要删除用户的id="+id);
        //去数据库里删除

        User luffy = new User(id, "luffy", "12345");

        return luffy;

    }


}

Feign负载均衡

注册中心中观察,发现Micro1微服务在Eureka注册中心中有两个服务节点

在这里插入图片描述

当发起feign调用时,究竟调用的是哪个节点呢?

@RestController
@RequestMapping("/user")
public class UserController {

    @Value("${server.port}")
    String port;

    @GetMapping("/findAll")
    List<User> findAll(){
        System.out.println(port);
        try {
            TimeUnit.SECONDS.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        List<User> users = Arrays.asList(new User(1,"zhangsan", "123456", 29), new User(2,"lisi", "12345", 19));
        return users;
    }

}

Feign使用的是轮询负载均衡算法,当有多个节点时,采用轮询的方式依次调用。

Feign调用超时时间设置

feign:
  client:
    config:
      default:
        # 建立连接的超时时间
        connectTimeout: 5000
        # 发送请求后等待接口响应结果的超时时间
        readTimeout: 10000

将微服务的接口响应时间延长,观察接口调用,超时抛异常

    @GetMapping("/findAll")
    List<User> findAll(){
        System.out.println(port);
        try {
            TimeUnit.SECONDS.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        List<User> users = Arrays.asList(new User(1,"zhangsan", "123456", 29), new User(2,"lisi", "12345", 19));
        return users;
    }

添加全局异常处理

@RestControllerAdvice
public class ExHandler {

    @ExceptionHandler(Exception.class)
    public String handleEx(Exception e){
        return e.getMessage();
    }

}

Feign配置日志

添加一个配置类

@Configuration
public class FeignConfig {

    @Bean
    public Logger.Level liver(){
        /*
         * NONE:默认的,不显示任何日志
         * BASIC:仅记录请求方法、RUL、响应状态码及执行时间
         * HEADERS:除了BASIC中定义的信息之外,还有请求和响应的头信息
         * FULL:除了HEADERS中定义的信息之外,还有请求和响应的正文及元数据
         */
        return Logger.Level.FULL;
    }
}

yml文件中为FeignClient接口配置日志级别

logging:
  level:
    com.qf.feign.XXXClient: debug

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

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

相关文章

SpringBoot:返回响应,统一封装

说明 接口的返回响应&#xff0c;封装成统一的数据格式&#xff0c;再返回给前端。 返回响应&#xff0c;统一封装实体&#xff0c;数据结构如下。 代码 package com.example.core.model;import io.swagger.v3.oas.annotations.media.Schema; import lombok.*;/*** 返回响应…

英飞凌TC3xx--深度手撕HSM安全启动(四)--TC3xx HSM使能和配置技巧

上一章,我们简单聊了下英飞凌TC3xx的HSM的系统框架、相关UCB、Host和HSM通信模块。今天着重分析HSM的使能。 1. 系统引入HSM的思考 为什么要增加HSM 信息安全方面考虑,系统的安全启动、ECU之间安全数据的交互、ECU内部的敏感信息保存 TC3xx使能HSM后,HSM的代码应该…

spring aop源码解析

spring知识回顾 spring的两个重要功能&#xff1a;IOC、AOP&#xff0c;在ioc容器的初始化过程中&#xff0c;会触发2种处理器的调用&#xff0c; 前置处理器(BeanFactoryPostProcessor)后置处理器(BeanPostProcessor)。 前置处理器的调用时机是在容器基本创建完成时&#xff…

安防监控系统/视频云存储/视频AI智能分析:人形检测算法应用汇总

随着人工智能的飞速发展&#xff0c;TSINGSEE青犀智能AI算法功能也日渐丰富&#xff0c;除了常见的人脸、工服、安全帽检测以外&#xff0c;人形检测算法的应用也十分广泛&#xff0c;主要可以应用在以下场景&#xff1a; 1、安防监控系统 人形检测算法可以应用于监控摄像头中…

ChatGPT OpenAI 针对HR与财务岗位一键核对工资表差异

HR人力资源与财务部门关于奖金的计算,两个部门计算的结果有差异如何将差异内容显示。 如何快速找出不相同的单元格。 我们给ChatGPT来提出需求来解决。 prompt: 请写出一个VBA程序找出E3:E12单元格区域与E16:E25单元格区域中不相同的单元格,并填充为红色背景显示,请写出完…

23062QTday1

自己制作一个登录界面 头文件&#xff1a; #ifndef WIDGET_H #define WIDGET_H#include <QWidget>#include <QApplication>#include <QLineEdit> #include <QLabel> #include <QMovie> class Widget : public QWidget {Q_OBJECTpublic:Widget(…

概率统计笔记:从韦恩图的角度区分 条件概率和联合概率

联合概率&#xff1a;两个或多个事件同时发生的概率。用 P(A∩B) 或 P(A,B) 表示 条件概率&#xff1a;在已知某个事件发生的条件下&#xff0c;另一个事件发生的概率。用P(A∣B) 表示在事件 B 发生的条件下&#xff0c;事件 A 发生的概率。 不难发现联合概率的样本空间更大&am…

多线程|多进程|高并发网络编程

一.多进程并发服务器 多进程并发服务器是一种经典的服务器架构&#xff0c;它通过创建多个子进程来处理客户端连接&#xff0c;从而实现并发处理多个客户端请求的能力。 概念&#xff1a; 服务器启动时&#xff0c;创建主进程&#xff0c;并绑定监听端口。当有客户端连接请求…

华为云云耀云服务器L实例评测 | 搭建docker环境

目录 &#x1f352;docker的概念 &#x1f352;Docker 的优点 &#x1fad0;1、快速&#xff0c;一致地交付您的应用程序 &#x1fad0;2、响应式部署和扩展 &#x1fad0;3、在同一硬件上运行更多工作负载 &#x1f352;云耀云服务器L实例 &#x1fad0;产品优势 &#x1f95d…

如何使用反 CSRF 令牌保护您的网站和 Web 应用程序

防止跨站点请求伪造攻击 (CSRF/XSRF)的最常见方法是使用反 CSRF 令牌&#xff0c;该令牌只是一个唯一值集&#xff0c;然后由 Web 应用程序需要。CSRF 是一种客户端攻击&#xff0c;可用于将用户重定向到恶意网站、窃取敏感信息或在用户会话中执行其他操作。幸运的是&#xff0…

组件自定义事件学习笔记

组件自定义事件_绑定 JS中有内置事件比如click&#xff0c;keyup。内置事件是给标签使用的&#xff0c;而自定义事件是给组件使用的。 子组件给父组件传递数据有两种方式 App父组件&#xff0c;School和Student是子组件。 子组件给父组件传递函数类型的props实现&#xff…

【深度学习】 Python 和 NumPy 系列教程(廿五):Matplotlib详解:3、多子图和布局:subplot()函数

目录 一、前言 二、实验环境 三、Matplotlib详解 1、2d绘图类型 2、3d绘图类型 3、多子图和布局 1. subplot()函数 简单示例 一、前言 Python是一种高级编程语言&#xff0c;由Guido van Rossum于1991年创建。它以简洁、易读的语法而闻名&#xff0c;并且具有强大的功能…

【Redis】深入理解 Redis 持久化机制 —— RDB 和 AOF

文章目录 一、Redis 的持久化二、RDB 持久化机制2.1 对 RBD 的认识RDB 的概念RDB 持久化机制的优缺点RDB 的相关配置 2.2 RDB 的触发时机2.2 RDB 的触发时机自动触发手动触发&#xff1a;SAVE 和 BGSAVE 2.3 RDB 文件的处理保存 RDB 文件压缩 RDB 文件校验 RDB 文件 三、AOF 持…

Python如何查看内存泄漏

在python中&#xff0c;当一个变量不被引用的时候就会触发垃圾回收机制从而被从内存中删除&#xff0c;但有时一个不注意可能就会出现内存泄漏问题。 Python中可能的会出现内存泄露的情况 (1) 循环引用&#xff1a;当两个或多个对象相互引用&#xff0c;造成的循环引用进而导…

Pytorch学习:torch.argmax(input, dim, keepdim=False)详解

torch.argmax() 返回输入中所有元素的最大值的索引&#xff0c;与torch.max()中返回(values, indices)中的indices类似&#xff0c;它也常被用于深度学习中的分类问题。 在下面程序中&#xff0c;使用torch.argmax() import torcha torch.tensor([[1, 2, 3, 4],[4, 1, 2, 3]…

5个免费的3D钣金CAD软件

作为一名咨询顾问&#xff0c;我一直在寻找能够满足大客户需求的最佳 CAD 软件。 但我知道并不是每个人都在寻找劳斯莱斯式的钣金设计解决方案。 有时你只想要一些简单的东西&#xff0c;而且最好是免费的。 例如&#xff0c;如果你正在设计简单的折叠钣金零件&#xff0c;则只…

Linux安装filebeat

相关链接 主⻚&#xff1a; https://www.elastic.co/cn/products/beats/filebeat 下载&#xff1a; wget https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-7.5.1-linux-x86_64.tar.gz 百度云链接&#xff1a;https://pan.baidu.com/s/1MLshk_VyZZTmKhZvlS…

基于SpringBoot的一套强大后台管理系统

概述 一个功能强大而完善的后台管理系统框架&#xff0c;用户可基于此框架进行二次开发&#xff0c;定制成符合自己的需求的后台管理系统&#xff01; 详细 运行截图&#xff1a; 项目结构&#xff1a; 详细说明&#xff1a; 环境说明&#xff1a; jdk1.8mavenMySQL5.7 项…

Vue框架--Vue过滤器

下面&#xff0c;我们一起来看看Vue中的过滤器。 过滤器&#xff1a; 定义&#xff1a;对要显示的数据进行特定格式化后再显示&#xff08;适用于一些简单逻辑的处理&#xff09;。 语法&#xff1a; 1.注册过滤器&#xff1a;Vue.filter(name,callback) 或 ne…

分享一个springboot+uniapp开发的线上马拉松报名小程序源码 lw 调试

&#x1f495;&#x1f495;作者&#xff1a;计算机源码社 &#x1f495;&#x1f495;个人简介&#xff1a;本人七年开发经验&#xff0c;擅长Java、Python、PHP、.NET、微信小程序、爬虫、大数据等&#xff0c;大家有这一块的问题可以一起交流&#xff01; &#x1f495;&…