Feign远程接口调用

概述

目的:解决微服务调用问题。如何从微服务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:8848config:file-extension: yamlprofiles: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 {@AutowiredUserFeignClient userFeignClient;@AutowiredProviderFeigngClient 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 {@Beanpublic 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 {@Beanpublic 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.hqwc.cn/news/109523.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ZTMap是如何在相关政策引导下让建筑更加智慧化的?

近几年随着智慧楼宇概念的深入&#xff0c;尤其是在“十四五规划”“新基建”“数字经济”等相关战略和政策的引导下&#xff0c;智慧楼宇也迎来了快速发展期&#xff0c;对推动智慧城市系统的建设越来越重要。那么究竟什么是智慧楼宇呢&#xff1f;智慧楼宇其实就是整合楼宇内…

Linux:基础开发工具之Makefile和缓冲区的基本概念

文章目录 动静态库自动化构建代码缓冲区原理实现具体实现 动静态库 首先要知道什么是链接&#xff1a; C程序中&#xff0c;并没有定义printf的函数实现,且在预编译中包含的stdio.h中也只有该函数的声明,而没有定义函数的实现 系统把这些函数实现都被做到名为 libc.so.6 的库…

【计算机网络】传输层协议——TCP(下)

文章目录 1. 三次握手三次握手的本质是建立链接&#xff0c;什么是链接&#xff1f;整体过程三次握手过程中报文丢失问题为什么2次握手不可以&#xff1f;为什么要三次握手&#xff1f; 2. 四次挥手整体过程为什么要等待2MSL 3. 流量控制4. 滑动窗口共识滑动窗口的一般情况理解…

EasyX图形化界面

这里写目录标题 EasyX绘制简单的图形化窗口窗口坐标设置窗口属性实现基本绘图功能贴图原样贴图透明贴图认识素材 代码步骤 按键交互阻塞按键 鼠标交互 EasyX 绘制简单的图形化窗口 代码示例&#xff1a; while&#xff08;1&#xff09;&#xff1b; 可以防止闪屏 窗口坐标 …

matlab根轨迹绘制

绘制根轨迹目的就是改变系统的闭环极点&#xff0c;使得系统由不稳定变为稳定或者使得稳定的系统变得更加稳定。 在使用PID控制器的时候&#xff0c;首先要确定的参数是Kp&#xff0c;画成框图的形式如下&#xff1a; 也就是想要知道Kp对系统性能有哪些影响&#xff0c;此时就…

设计模式之代理模式的懂静态代理和动态代理

目录 1 概述1.1 如何实现&#xff1f;1.2 优点1.3 缺点1.4 适用场景 2 静态代理实现3 JDK 动态代理实现4 CGlib 动态代理实现5 总结 1 概述 代理模式&#xff08;Proxy Pattern&#xff09;是一种结构型设计模式&#xff0c;它的概念很简单&#xff0c;它通过创建一个代理对象来…

便捷又炸街!Mate 60的智感支付,是如何做到快速又安全的?

扫码支付已成为线下消费的主流付款方式&#xff0c;平时出门&#xff0c;手机一带&#xff0c;钱包拜拜&#xff01; 以微信支付为例&#xff0c;正常线下支付&#xff0c;手机解锁状态下&#xff1a; 第一步&#xff1a;找到微信APP&#xff1b; 第二步&#xff1a;打开右上…

合宙Air724UG LuatOS-Air LVGL API控件-窗口 (Window)

窗口 (Window) 分 享导出pdf 示例代码 win lvgl.win_create(lvgl.scr_act(), nil) lvgl.win_set_title(win, "Window title") -- close_btn lvgl.win_add_btn_right(win, "\xef\x80\x8d") -- --lvgl.obj_set_event_cb(cl…

Nacos注册中心

Nacos 安装 https://nacos.io/zh-cn/ 源码安装 第一步&#xff1a;利用Gitee获取nacos在github上的代码到自己的gitee仓库中 https://github.com/alibaba/nacos.git 第二步&#xff1a;下载源码到本地。 第三步&#xff1a;使用maven编译代码。 # 先切换到master分支 gi…

3 分钟,带你了解低代码开发

一、低代码平台存在的意义 传统软件开发交付链中&#xff0c;需求经过3次传递&#xff0c;用户→业务→架构师→开发&#xff0c;每一层传递都可能使需求失真&#xff0c;导致最终交付的功能返工。 业务的变化促使软件开发过程不断更新、迭代和演进&#xff0c;而低代码开发即是…

vi/vim编辑器

vi和vim区别 vi 和 vim 是常见的文本编辑器&#xff0c;以下是它们之间的区别&#xff1a; 功能和特性&#xff1a; vi 是最早的版本&#xff0c;是在早期Unix系统中广泛使用的编辑器。vi 相对较简单&#xff0c;功能主要集中在基本的文本编辑操作上&#xff0c;如插入、删除、…

Python二级 每周练习题18

练习一: 从键盘输入任意字符串&#xff0c;按照下面要求分离字符串中的字符: 1、分别取出该字符串的第偶数位的元素(提醒注意:是按照从左往右数的方式确定字符串的位置) 2、并依次存储到一个列表中; 3、输出这个列表。 答案: ninput(请输入任意字符串:) #创建变量n存放用户…