油盐微服务——声明式服务调用Feign

2023-10-27


对于前面的Ribbon和Hystrix的介绍,Spring Cloud Feign基于Netflix Feign实现,封装整合了以上两个工具,来简化开发。

因为我们看到对于RestTemplate,往往会使用Ribbon,并且形成了一套模版化的调用方法。在实际开发中,由于对于服务依赖的调用不止一处,往往一个借口会被多次调用,所以Feign在此基础上做了进一步的封装。

Feign快速入门

修改之前的服务消费者。
加入依赖

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

在application应用主类上加入@EnableFeignClients

@SpringBootApplication
@EnableFeignClients
public class Demo2Application {
    public static void main(String[] args) {
        SpringApplication.run(Demo2Application.class, args);
    }
}

定义HelloService:

@FeignClient("hello-service")
public interface HelloService {
    @RequestMapping("/hello")
    String hello();
}

注意,hello-service是服务提供者的spring.application.name。

Controller:

@RestController
@RequestMapping("/")
public class ConsumerController {
    @Autowired
    HelloService helloService;

    @RequestMapping("/f")
    public String hello() {
        return helloService.hello();
    }
}

最后同ribbon实现的服务消费者一样,需要在properties中加入服务注册中心。

server.port=9000
spring.application.name=eureka-client
#eureka服务注册中心地址
eureka.client.service-url.defaultZone=http://localhost:1111/eureka/

运行后发现服务仍然可用。
以声明式的方法,优雅而简单的实现了服务调用。

参数绑定

上一节展示的示例是不带参数的REST风格的绑定。在开始介绍Spring Cloud Feign的参数绑定之前,先拓展一下服务方,增加下面的接口定义。

@RestController
@EnableEurekaClient
public class HelloServerController {

    @RequestMapping(value = "/hello1",method = RequestMethod.GET)
    public String hello(@RequestParam String name){
            return "hello "+name;

    }

    @RequestMapping(value = "/hello2",method = RequestMethod.GET)
    public User hello(@RequestHeader String name, @RequestHeader Integer age){
        User user=new User(name, age);
        return user;
    }

    @RequestMapping(value = "/hello3",method = RequestMethod.POST)
    public String hello(@RequestBody User user){
        return "hello "+user.getName()+","+user.getAge();
    }
}

User对象定义如下,需要注意的是,必须要有User的默认构造函数,不然Feign会根据Json字符串转换User对象时抛出异常。

@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
    private String name;
    private Integer age;
}

完成了对“eureka-provider”的改造后,在服务消费者做如下改造,首先创建一个相同的User类。

然后,在HelloService接口中增加三个接口的绑定声明。

 @RequestMapping(value = "/hello1", method = RequestMethod.GET)
    String hello(@RequestParam("name") String name);

    @RequestMapping(value = "/hello2", method = RequestMethod.GET)
    User hello(@RequestHeader("name") String name, @RequestHeader("age") Integer age);

    @RequestMapping(value = "/hello3", method = RequestMethod.POST)
    String hello(@RequestBody User user);

注意,这里的@RequestParam@RequestHeader后面的参数value不能少,因为在Spring Mvc中,注解会根据参数名来作为默认值,但是在Feign中绑定参数必须通过value属性来指明具体参数名

最后在Controller里调用服务:

@RequestMapping("/f2")
    public String hello2(){
        StringBuilder stringBuilder=new StringBuilder();
        stringBuilder.append(helloService.hello("name1")).append("\n");
        stringBuilder.append(helloService.hello("name2",2)).append("\n");
        stringBuilder.append(helloService.hello(new User("name3",3))).append("\n");
        return stringBuilder.toString();
    }

继承特性

在上一节的内容编写代码的过程中,我们几乎完全可以从服务方提供的Controller依靠复制操作,构建出相应的服务客户端绑定借口。

既然存在这么多复制操作,Feign提供了继承特性来解决复制操作,减少编码量。
创建新的mvn工程:hello-service-api
在这里插入图片描述
创建完成后,写入User类和HelloSerivce:

@Data
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class User{
    private String name;
    private Integer age;
}



@RequestMapping("/refactor")
public interface HelloService {

    @RequestMapping(value = "/hello4", method = RequestMethod.GET)
    String hello(@RequestParam("name") String name);

    @RequestMapping(value = "/hello5", method = RequestMethod.GET)
    User hello(@RequestHeader("name") String name, @RequestHeader("age") Integer age);

    @RequestMapping(value = "/hello6", method = RequestMethod.POST)
    String hello(@RequestBody User user);
}

将工程打包放到本地库或者私库。

mvn clean package install解释:clean,清楚旧的构建;package打包项目;install:将项目安装到本地仓库这样就ok了。
然后将依赖引入pom.xml后,引入项目module即可。
在这里插入图片描述
注意:
这里使用多模块效果更好。
下面是代码重构后的版本。spring cloud脚手架地址https://github.com/BonjourMondo/SpringCloud在这里插入图片描述

服务提供者项目中,新增Controller并implements:

@RestController
public class RefactorHelloServerController  implements com.didiname.helloserviceapi.service.HelloService{

    @Override
    public String hello(String name) {
        return "hello,"+name;
    }

    @Override
    public User hello(String name, Integer age) {
        return new User(name,age);
    }

    @Override
    public String hello(User user) {
        return "hello,"+user.getName()+",age:"+user.getAge();
    }
}

在服务消费者项目中,新增Service:

@FeignClient("EUREKA-PROVIDER")
public interface RefactorConsumerService extends com.didiname.helloserviceapi.service.HelloService{
}

在Controller里加入:

@RequestMapping("/f3")
    public String hello3(){
        StringBuilder stringBuilder=new StringBuilder();
        stringBuilder.append(refactorConsumerService.hello("name4")).append("\n");
        stringBuilder.append(refactorConsumerService.hello("name5",5)).append("\n");
        stringBuilder.append(refactorConsumerService.hello(new com.didiname.helloserviceapi.dto.User("name6",6))).append("\n");
        return stringBuilder.toString();
    }

运行三个项目,得到结果。

继承特性优缺点

  • 优点:配合Maven私有库可以轻易的实现接口定义的共享,减少服务客户端的绑定配置。
  • 缺点:由于接口在构建期间就产生了依赖,所以接口变动会对项目构建产生影响。如果服务方修改了一个接口定义,会导致客户端工程的构建失败。所以,开发团队应该严格遵守开闭原则,进行前后版本的兼容。

Ribbon配置

Feign的客户端负载均衡是通过Ribbon来实现的,所以我们可以直接通过配置Ribbon客户端的方式来自定义各个服务器客户端调用的参数。
全局配置
比如修改客户端超时时间:

ribbon.ConnectTimeout=500
ribbon.ReadTimeout=500

制定服务配置
大多数情况下,我们对于服务调用的超时时间会根据服务的特性做一些调整,所以仅仅依靠默认的全局配置是不行的。

在使用Feign客户端的时间,我们使用了@FeignClient注解,并指定了name表明服务名。那么,我们就可以通过服务名来设置参数:

eureka-provider.ribbon.ConnectTimeout=500
eureka-provider.ribbon.ReadTimeout=500

重试机制
在Feign中默认实现了重试机制。以后有机会再详细了解 。

Hystrix配置

全局配置
Hystrix全局配置同Ribbon差不多,比如设置全局超时时间:
在这里插入图片描述

禁用Hystrix
指定命令配置
以后再了解。

服务降级配置
在服务消费方进行如下改造:

@FeignClient(value = "eureka-server",fallback = HelloServiceFallback.class)
@Service
public interface HelloService {
    @GetMapping(value = "/hello1")
    String hello(@RequestParam("name") String name);

    @GetMapping(value = "/hello2")
    User hello(@RequestHeader("name") String name, @RequestHeader("age") Integer age);

    @PostMapping(value = "/hello3")
    String hello(@RequestBody User user);
}

以及:

@Component
public class HelloServiceFallback implements HelloService {
    @Override
    public String hello(String name) {
        return "error"+name;
    }

    @Override
    public User hello(String name, Integer age) {
        return new User("未知",0);
    }

    @Override
    public String hello(User user) {
        return "未知";
    }
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

油盐微服务——声明式服务调用Feign 的相关文章

  • 负载均衡原理分析与源码解读

    上一篇文章一起学习了Resolver的原理和源码分析 本篇继续和大家一起学习下和Resolver关系密切的Balancer的相关内容 这里说的负载均衡主要指数据中心内的负载均衡 即RPC间的负载均衡 传送门 服务发现原理分析与源码解读 基于
  • 面试官问:微服务的4种部署策略有哪些,什么区别?

    在项目迭代的过程中 不可避免需要 上线 上线对应着部署 或者重新部署 部署对应着修改 修改则意味着风险 目前有很多部署发布的技术 这儿将常见的做一个总结 上面所说难免有些抽象 举一个情景例子 加入你是微博项目负责人员 现在新版本较原来的老版
  • 乾坤微服务子项目图片资源加载失败

    一 背景 子项目单独运行时正常 放在乾坤上 img 加载图片时失败 二 分析原因 假设乾坤项目域名为 http www aaa com 子项目域名为 http www bbb com 项目实际运行时 图片的 html 写法为 img src
  • 油盐微服务——Spring Cloud简介

    文章目录 Spring Cloud简介 Spring boot 回顾 Spring Cloud简介 Spring Could是一个基于Spring Boot实现的微服务架构开发工具 它为微服务架构中涉及的配置管理 服务治理 断路器 智能路由
  • Eureka与Zookeeper的区别

    著名的CAP 理论指出 一个分布式系统不可能同时满足 C 一致性 A 可用性 和 P 分区容错性 由于分区容错性在是分布式系统中必须要保证的 因此我们只能在 A 和 C 之间进行权衡 在此 Zookeeper 保证的是 CP 而 Eurek
  • Admin监控&Sleuth链路追踪 &skywalking链路追踪

    Admin监控 Sleuth链路追踪 skywalking Sleuth Zipkin 一 Sleuth Zipkin介绍 二 搭建环境 三 Sleuth入门操作 四 Zipkin搭建及操作 五 RabbitMQ方式发送信息 六 Elast
  • 一直在说高并发,多少QPS才算高并发?

    高并发的四个角度 只说并发不提高可用就是耍流氓 可以从四个角度讨论这个问题 首先是无状态前端机器不足以承载请求流量 需要进行水平扩展 一般QPS是千级 然后是关系型数据库无法承载读取或写入峰值 需要数据库横向扩展或引入nosql 一般是千到
  • MQTT-java使用说明

    MQTT java使用说明 本文的资料下载 链接 https pan baidu com s 1OCfsQ NqcehKy86kYkA wg pwd 1234 提取码 1234 MQTT基本介绍 MQTT是一个客户端服务端架构的发布 订阅模
  • K8s微服务从0到1入门及命令实战

    写在前面 本文主要介绍k8s的核心概念 基础语法 常用命令和常用操作 Kubernetes介绍 Kubernetes是一种流行的开源容器编排和管理系统 它的目标是简化部署 扩展和管理容器化应用程序 Kubernetes最初由Google开发
  • 开源微服务如何选型?Spring Cloud、Dubbo、gRPC、Istio 详细对比

    不论您是一名开发者 架构师 CTO 如果您曾深度参与在微服务开发中 那么相信您一定有过开源微服务框架或体系选型的疑问 Apache Dubbo Spring Cloud gRPC 以及 Service Mesh 体系产品如 Istio 到底
  • 【业务功能篇78】微服务-前端后端校验- 统一异常处理-JSR-303-validation注解

    5 前端校验 我们在前端提交的表单数据 我们也是需要对提交的数据做相关的校验的 Form 组件提供了表单验证的功能 只需要通过 rules 属性传入约定的验证规则 并将 Form Item 的 prop 属性设置为需校验的字段名即可 校验的
  • Springboot项目在Jenkins+Docker中实现自动化部署

    Springboot项目在Jenkins Docker中实现自动化部署 一 环境准备 1 项目开发环境 2 Jenkins docker运行环境 二 Docker安装 三 Jenkins安装 四 创建一个Springboot项目 1 使用I
  • [qiankun]实战问题汇总

    qiankun 实战问题汇总 ERROR SyntaxError Cannot use import statement outside a module 问题分析 解决方案 子应用命名问题 问题分析 解决方案 jsonpFunction
  • 世界两万英尺范围内,均分布有运维体系架构

    几年前 Microsoft 与技术领先的社区专家合作发布了一本受欢迎的指导书 标题为 适用于容器化 NET 应用程序的 NET 微服务 深入探讨了构建分散式应用程序的原则 模式和最佳做法 其中包括一个功能齐全的微服务参考应用程序 展示了体系
  • 微服务项目之项目简介

    目录 项目模式 技术栈 项目架构图 模块 主模块 项目模式 电商模式 市面上有5种常见的电商模式 B2B B2C C2B C2C O2O 1 B2B模式 B2B Business to Business 是指 商家与商家建立的商业关系 如
  • 如果老板要求你的系统接入春晚大流量活动,你会心慌慌吗?

    目录 回头看看 原始系统技术架构 基于CDN的活动静态页面缓存方案 基于Nginx Tomcat Redis的多级缓存方案 超高并发写请求RocketMQ削峰填谷方案 系统限流防雪崩体系架构方案 今天给大家分享一个话题 就是如果要是你老板突
  • 【微服务架构设计】微服务不是魔术:处理超时

    微服务很重要 它们可以为我们的架构和团队带来一些相当大的胜利 但微服务也有很多成本 随着微服务 无服务器和其他分布式系统架构在行业中变得更加普遍 我们将它们的问题和解决它们的策略内化是至关重要的 在本文中 我们将研究网络边界可能引入的许多棘
  • 10 微服务流程规范篇:高速迭代的研发过程需要怎样的规范?

    上一课时 我讲解了微服务质量保障体系的全景概览 本课时我主要讲解流程规范 高速迭代的研发过程需要怎样的规范呢 业务流程阶段 众所周知 产品研发是为业务服务的 在深入讲解产品研发流程之前 我们先整体看下业务流程 分为 3 个阶段 产品研发阶段
  • spring security oauth2 动态切换角色或者岗位,更新redis缓存

    1 切换角色或者岗位后更新缓存token 获取token 并更新token 特别要注意token中的内容 accessToken getAdditionalInformation put SecurityConstants DETAILS
  • 微服务常见的配置中心简介

    微服务架构中 常见的配置中心包括以下几种 Spring Cloud Config Spring Cloud Config是官方推荐的配置中心解决方案 它支持将配置文件存储在Git SVN等版本控制系统中 通过提供RESTful API 各个

随机推荐

  • 全民农场服务器维护,全民农场1月22日更新了什么_全民农场1月22日更新维护内容介绍_游戏堡...

    全民农场今日更新之后将上线非常多精彩的活动内容 下面小编就为大家介绍一下全民农场1月22日更新维护内容 全民农场 将于1月22日12 00 18 30不停机更新 快来看看新的农场消息 1 全新惊喜一周活动开启 1月22日更新后 1月28日
  • HTTP抓包利器Fiddler基础及进阶教程(二)---- 手机端抓包+强制全局代理

    本文将进一步介绍Fiddler在移动端抓包的方法 一 配置Fiddler 二 查看当前IP 方式有很多种 选择运行 输入 cmd 在输入Ipconfig 三 验证是否配置成功 将上一步拿到的 IP Fiddler端口号 组成的链接用浏览器打
  • 读书笔记(2018年3月)-《卓有成效的管理者》总结

    1 善用时间 有效的管理者知道他们的时间用在什么地方 他们所能控制的时间非常有限 他们会有系统地工作 来善用这有限的时间 1 记录时间 记录时间耗用的实际情形 2 诊断时间 做有系统的时间管理 首先要找出什么事根本不必做 这些事做了也完全浪
  • Windows Server 2016抓取明文密码

    临时禁止Windows Defender REG ADD HKEY LOCAL MACHINE SOFTWARE Policies Microsoft Windows Defender v DisableAntiSpyware t REG
  • 原 QNetworkAccessManager实现curl上传表单文件

    心酸的过程我就不说了 直接上菜 如何用Qt实现 curl F file task plist http www fatjb com uploadfile QFile file m sTaskPlistPath if file exists
  • 【C++11多线程】线程的创建与结束:thread

    文章目录 1 普通函数作为线程函数 1 1 thread 1 2 join 1 3 detach 1 4 joinable 2 函数对象作为线程函数 3 lambda表达式作为线程函数 4 类成员函数作为线程函数 5 向线程函数传递参数 1
  • 构建一个简单的以太坊+IPFS+React.js去中心化应用DApp

    我们为什么要构建这个 在以太坊区块链上存储大量数据是非常昂贵的 根据以太坊的黄皮书 它是大约20 0000gas 256bit 8字节 1字 基于02 28 2018 gas价格为4gwei gas 请参阅 https ethgasstat
  • 多目标跟踪2021总结

    11年it研发经验 从一个会计转行为算法工程师 学过C c java android php go js python CNN神经网络 四千多篇博文 三千多篇原创 只为与你分享 共同成长 一起进步 关注我 给你分享更多干货知识 目录 SOT
  • CLI 命令行实用程序开发基础

    CLI 命令行实用程序开发基础 代码传送门 GoOnline平台 1 概述 CLI Command Line Interface 实用程序是Linux下应用开发的基础 正确的编写命令行程序让应用与操作系统融为一体 通过shell或scrip
  • 【笔试&面试】关于动态链接库

    动态链接库英文为DLL 是Dynamic Link Library 的缩写形式 DLL是一个包含可由多个程序同时使用的代码和数据的库 DLL不是可执行文件 动态链接提供了一种方法 使进程可以调用不属于其可执行代码的函数 函数的可执行代码位于
  • 关闭windows defender安全中心的方法

    windows defender 安全中心 真的是shit 灵敏度太高了 一般的绿软都会被杀 而且是不提示直接删除 想反悔都没办法 并且 Windows Defender Antivirus 导致资源使用率高或系统出现其他问题引起间歇性的卡
  • Python 数据分析测试6 之 分组数据的 柱状图显示

    Time 2020 08 06 Author Xiaohong 运行环境 OS Windows 10 Python 3 7 功能 导入1份文件 以鞋部位分组 求得记录数 及累计缴库量 效果如下 1 以鞋部位分组 求得记录数 2 以鞋部位分组
  • 华为OD机试真题- 篮球比赛-2023年OD统一考试(B卷)

    题目描述 篮球 5V5 比赛中 每个球员拥有一个战斗力 每个队伍的所有球员战斗力之和为该队伍的总体战斗力 现有10个球员准备分为两队进行训练赛 教练希望2个队伍的战斗力差值能够尽可能的小 以达到最佳训练效果 给出10个球员的战斗力 如果你是
  • 学习STM32 SPI学习与应用

    认识一下SPI SPI的全称是 Serial Peripheral Interface 意为串行外围接口 SPI接口主要应用在EEPROM FLASH 实时时钟 AD转换器 还有数字信号处理器和数字信号解码器之间 SPI是一种高速的 全双工
  • 中大型企业选择云服务器还是传统服务器自建机房成本核算

    中大型企业自建机房还是选择阿里云服务器或腾讯云服务器 企业上云是趋势 大型企业自己购买服务器自建机房还是使用云服务器更省钱 自建机房一次性投入 但是云服务器每年都需要续费 云服务器吧从机房部署 容灾备份 安全可靠 运维及成本等方面来全方位对
  • Flask学习笔记(十三)数据库基本操作

    数据库基本操作 在Flask SQLAlchemy中 插入 修改 删除操作 均由数据库会话管理 会话用db session表示 在准备把数据写入数据库前 要先将数据添加到会话中然后调用commit 方法提交会话 数据库会话是为了保证数据的一
  • vue项目中自动拉取更新Iconfont(阿里巴巴图标库)

    在vue项目中使用 iconfont图标库 网上的栗子很多 这边就随手给一个 点这里 上面的解决了 那我就很苦恼 我每次添加 或删除 或更新图标库 需要重新下载 自己手动去覆盖吗 我是拒绝的 so 自动覆盖就很有必要了 贴一下我的iconf
  • Linux通过Nginx部署Vue项目

    Vue Springboot前后端项目分离开发 我们在部署的时候就需要将两者分开来部署 vue部署 由于我们是通过Linux nginx的方式来部署vue 因此在你的linux中需要安装nginx nginx的安装方式不多说 直接解压ngi
  • 网络安全期末复习

    前言 本文用于网络安全课期末复习资料 都是从老师上课讲的ppt和课本总结的 可能不太全 后面有一部分习题 填空和简答 如果需要word版可以找我要 目录 知识点 信息安全属性 网络防御模型 密码体制 数字证书与公钥基础设施 PKI 防火墙
  • 油盐微服务——声明式服务调用Feign

    文章目录 Feign快速入门 参数绑定 继承特性 Ribbon配置 Hystrix配置 对于前面的Ribbon和Hystrix的介绍 Spring Cloud Feign基于Netflix Feign实现 封装整合了以上两个工具 来简化开发