一、简介

官网:https://spring.io/projects/spring-cloud-openfeign

文档:https://docs.spring.io/spring-cloud-openfeign/docs/current/reference/html/

配置:https://docs.spring.io/spring-cloud-openfeign/docs/current/reference/html/appendix.html

OpenFeign是一个显示声明式的WebService客户端。使用OpenFeign能让编写Web Service客户端更加简单。使用时只需定义服务接口,然后在上面添加注解。OpenFeign也支持可拔插式的编码和解码器。spring cloud对feign进行了封装,使其支持MVC注解和HttpMessageConverts。和eureka(服务注册中心)和ribbon组合可以实现负载均衡。在Spring Cloud中使用OpenFeign,可以做到使用HTTP请求访问远程服务,就像调用本地方法一样的,开发者完全感知不到这是在调用远程方法,更感知不到在访问HTTP请求,非常的方便。

OpenFeign 具有负载均衡功能,其可以对指定的微服务采用负载均衡方式进行消费、访问。之前老版本 Spring Cloud 所集成的 OpenFeign 默认采用了 Ribbon 负载均衡器。但由于Netflix 已不再维护 Ribbon,所以从 Spring Cloud 2021.x 开始集成的 OpenFeign 中已彻底丢弃Ribbon,而是采用 Spring Cloud 自行研发的 Spring Cloud Loadbalancer 作为负载均衡器

		<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!-- 使用openfeign 负载均衡 必须引入loadbalancer -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>

注意:负载均衡必须引入loadbalancer

二、使用

环境:

jdk:17

idea:2023.2

spring-boot:3.0.2

1、创建父工程

引入坐标

<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.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.0.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent> <groupId>com.mcode</groupId>
<artifactId>openfeign-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>openfeign-demo</name>
<url>http://maven.apache.org</url> <properties>
<java.version>17</java.version>
<spring-cloud.version>2022.0.0</spring-cloud.version>
<spring-cloud-alibaba.version>2022.0.0.0</spring-cloud-alibaba.version>
</properties> <modules>
<module>order-client</module>
<module>order-service</module>
</modules> <dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

2、创建order-service模块

导入坐标

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.mcode</groupId>
<artifactId>openfeign-demo</artifactId>
<version>1.0-SNAPSHOT</version>
</parent> <artifactId>order-service</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>order-service</name>
<description>order-service</description> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

配置application.yml


spring:
application:
name: order-service
cloud:
nacos:
discovery:
username: nacos
password: nacos
server-addr: localhost:8848
server:
port: 8081

配置启动类,启动Nacos注入

package com.mcode.orderservice;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient; @SpringBootApplication
@EnableDiscoveryClient
public class OrderServiceApplication { public static void main(String[] args) {
SpringApplication.run(OrderServiceApplication.class, args);
}
}

添加Order类,用来测试

package com.mcode.orderservice.bean;

import lombok.Data;

/**
* ClassName: Order
* Package: com.mcode.orderservice.bean
* Description:
*
* @Author: robin
* @Create: 2023/10/22 - 1:32 PM
* @Version: v1.0
*/
@Data
public class Order {
private Integer id;
private String orderNo;
private String productName;
}

添加OrderController控制器

package com.mcode.orderservice.controller;

import com.mcode.orderservice.bean.Order;
import org.springframework.web.bind.annotation.*; /**
* ClassName: OrderController
* Package: com.mcode.orderservice.controller
* Description:
*
* @Author: robin
* @Create: 2023/10/22 - 1:31 PM
* @Version: v1.0
*/
@RestController
@RequestMapping("/order")
public class OrderController { //方便后面的负载均衡测试
@Value("${server.port}")
public int port; @GetMapping("/{id}")
public Order getOrderById(@PathVariable("id") Integer id){
Order order = new Order();
order.setOrderNo("20201213");
order.setProductName("商品名称 端口:" + port);
order.setId(1);
return order;
}
}

3、创建order-client模块

导入坐标

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.mcode</groupId>
<artifactId>openfeign-demo</artifactId>
<version>1.0-SNAPSHOT</version>
</parent> <artifactId>order-client</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>order-client</name>
<description>order-client</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!-- 使用openfeign 必须引入loadbalancer -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

配置application.yml

spring:
application:
name: order-client
cloud:
nacos:
discovery:
username: nacos
password: nacos
server-addr: localhost:8848
server:
port: 8080

配置启动类,启动FeignClient和Nacos

package com.mcode.orderclient;

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
@EnableFeignClients
@EnableDiscoveryClient
public class OrderClientApplication { public static void main(String[] args) {
SpringApplication.run(OrderClientApplication.class, args);
}
}

添加Order类,用来测试

package com.mcode.orderclient.bean;

import lombok.Data;

/**
* ClassName: Order
* Package: com.mcode.orderclient.bean
* Description:
*
* @Author: robin
* @Create: 2023/10/22 - 1:32 PM
* @Version: v1.0
*/
@Data
public class Order {
private Integer id;
private String orderNo;
private String productName;
}

添加OrderService,用来定义Feign接口

package com.mcode.orderclient.service;

import com.mcode.orderclient.bean.Order;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.ResponseBody; /**
* ClassName: OrderService
* Package: com.mcode.orderclient.service
* Description:
*
* @Author: robin
* @Create: 2023/10/22 - 1:40 PM
* @Version: v1.0
*/
@FeignClient(value = "order-service",path = "order")
public interface OrderService {
@GetMapping("/{id}")
Order getOrderById(@PathVariable("id") Integer id);
}

添加OrderController用来测试

package com.mcode.orderclient.controller;

import com.mcode.orderclient.bean.Order;
import com.mcode.orderclient.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; /**
* ClassName: OrderController
* Package: com.mcode.orderclient.controller
* Description:
*
* @Author: robin
* @Create: 2023/10/22 - 1:38 PM
* @Version: v1.0
*/
@RestController
@RequestMapping("/order")
public class OrderController {
@Autowired
private OrderService orderService; @GetMapping("/{id}")
public Order getOrderById(@PathVariable("id") Integer id){
return orderService.getOrderById(id);
}
}

三、效果

Nacos

测试

四、配置说明

1、超时配置

全局超时配置

spring:
cloud:
openfeign:
client:
config:
default: # 全局设置
# 连接超时:client连接上service的时间阈值,起决定作用的是网络状况
connect-timeout: 1
# 读超时:client发出请求到接收到service的响应这段时间阈值,起决定作用的是service的业务逻辑
read-timeout: 1

局部超时配置

在全局设置的基础之上,若想单独对某些微服务单独设置超时时间,只需要将前面配置中的 default 修改为微服务名称即可。局部设置的优先级要高于全局设置的。

spring:
cloud:
openfeign:
client:
config:
default: # 全局设置
# 连接超时:client连接上service的时间阈值,起决定作用的是网络状况
connect-timeout: 1
# 读超时:client发出请求到接收到service的响应这段时间阈值,起决定作用的是service的业务逻辑
read-timeout: 1
order-service: # 局部配置
connect-timeout: 1
read-timeout: 2

2、Gzip压缩设置

OpenFeign 可对请求与响应进行压缩设置

spring:
cloud:
openfeign:
client:
config:
default:
connect-timeout: 1
read-timeout: 1
order-service:
connect-timeout: 1
read-timeout: 2
compression:
request:
enabled: true
min-request-size: 2048
mime-types: ["text/xml", "application/xml", "application/json"]
response:
enabled: true

默认值

3、所有配置

https://docs.spring.io/spring-cloud-openfeign/docs/current/reference/html/appendix.html

五、负载均衡

OpenFeign 的负载均衡器 Ribbon 默认采用的是轮询算法

更换负载均衡策略

工程启动三个实例,它们的端口号分别为8081、8082与8083

注意:关闭之前的超时和order-service模块添加端口查看

package com.mcode.orderclient.config;

import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClients;
import org.springframework.cloud.loadbalancer.core.RandomLoadBalancer;
import org.springframework.cloud.loadbalancer.core.ReactorLoadBalancer;
import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier;
import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment; /**
* ClassName: OpenFeignConfig
* Package: com.mcode.orderclient.config
* Description:
*
* @Author: robin
* @Create: 2023/10/22 - 3:48 PM
* @Version: v1.0
*/
@Configuration
@LoadBalancerClients(defaultConfiguration = OpenFeignConfig.class)
public class OpenFeignConfig {
@Bean
public ReactorLoadBalancer<ServiceInstance> loadBalancer(Environment e, LoadBalancerClientFactory factory){
// 获取负载均衡客户端名称,即提供者服务名称
String name = e.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
// 从所有service实例中指定名称的实例列表中随机选择一个实例
// 参数1:获取指定名称的所有service实例列表
// 参数2:指定要获取的service服务名称
return new RandomLoadBalancer(factory.getLazyProvider(name, ServiceInstanceListSupplier.class),name);
}
}

五、对比Feign

Feign 的远程调用底层实现技术默认采用的是 JDK 的 URLConnection,同时还支持HttpClient 与 OkHttp。由于 JDK 的 URLConnection 不支持连接池,通信效率很低,所以生产中是不会使用该默认实现的。

Spring Cloud OpenFeign 中直接将默认实现变为了 HttpClient,同时也支持OkHttp。用户可根据业务需求选择要使用的远程调用底层实现技术。

spring.cloud.openfeign.httpclient 下有大量 HttpClient 的相关属性设置。其中可以发现spring.cloud.openfeign.httpclient.enabled 默认为 true。 在 spring.cloud.openfeign.okhttp.enabled 默认值为 false,表明默认没有启动 OkHttp。

从Spring Cloud OpenFeign 4开始,不再支持Feign Apache HttpClient 4。我们建议使用Apache HttpClient 5。

      httpclient:
hc5:
enabled: true

Spring Cloud OpenFeign系列:简介和使用的更多相关文章

  1. Feign 系列(05)Spring Cloud OpenFeign 源码解析

    Feign 系列(05)Spring Cloud OpenFeign 源码解析 [TOC] Spring Cloud 系列目录(https://www.cnblogs.com/binarylei/p/ ...

  2. Spring Cloud 入门系列(一)

    前言 Spring Could作为目前最流行基于Java开发的构建微服务的完整框架.发现目前相关系列教程太少,本文是基于官网教程做的一套翻译. 何为Spring Cloud? Spring Cloud ...

  3. SpringCloud升级之路2020.0.x版-29.Spring Cloud OpenFeign 的解析(1)

    本系列代码地址:https://github.com/JoJoTec/spring-cloud-parent 在使用云原生的很多微服务中,比较小规模的可能直接依靠云服务中的负载均衡器进行内部域名与服务 ...

  4. spring cloud 入门系列四:使用Hystrix 实现断路器进行服务容错保护

    在微服务中,我们将系统拆分为很多个服务单元,各单元之间通过服务注册和订阅消费的方式进行相互依赖.但是如果有一些服务出现问题了会怎么样? 比如说有三个服务(ABC),A调用B,B调用C.由于网络延迟或C ...

  5. spring cloud 入门系列:总结

    从我第一次接触Spring Cloud到现在已经有3个多月了,当时是在博客园里面注册了账号,并且看到很多文章都在谈论微服务,因此我就去了解了下,最终决定开始学习Spring Cloud.我在一款阅读A ...

  6. 微服务&spring cloud架构系列汇总

    为了方便查找,把微服务&微服务架构之spring cloud架构系列文章按时间正序整理了一下,记录如下:   1. 微服务架构之spring cloud 介绍 2. 微服务架构之spring ...

  7. Spring Cloud OpenFeign使用教程

    文章目录 Spring Cloud OpenFeign Demo 怎么配置OpenFeignServer 怎么配置OpenFeignClient 多个参数传递问题 FeignClient的日志问题 多 ...

  8. 微服务生态组件之Spring Cloud OpenFeign详解和源码分析

    Spring Cloud OpenFeign 概述 Spring Cloud OpenFeign 官网地址 https://spring.io/projects/spring-cloud-openfe ...

  9. Spring Cloud Alibaba系列之分布式服务组件Dubbo

    本博客的例子代码可以在github找到下载链接:代码下载 SpringBoot.SpringCloud Alibaba系列博客专栏:链接 1.分布式理论 1.1.分布式基本定义 <分布式系统原理 ...

  10. Spring Cloud Config - RSA简介以及使用RSA加密配置文件

    简介 RSA非对称加密有着非常强大的安全性,HTTPS的SSL加密就是使用这种方法进行HTTPS请求加密传输的.因为RSA算法会涉及Private Key和Public Key分别用来加密和解密,所以 ...

随机推荐

  1. 【WALT】WALT入口 update_task_ravg() 代码详解

    目录 [WALT]WALT入口 update_task_ravg() 代码详解 代码展示 代码逻辑 ⑴ 判断是否进入 WALT 算法 ⑵ 获取 WALT 算法中上一个窗口的开始时间 ⑶ 如果任务刚初始 ...

  2. Leecode SQL

    618 学生地理信息报告 一所学校有来自亚洲.欧洲和美洲的学生.写一个查询语句实现对大洲(continent) 列的透视表操作,使得每个学生按照姓名的字母顺序依次排列在对应的大洲下面.输出的标题应依次 ...

  3. 解决github网站打不开

    方法一(此方法无效则选 方法二) 发现github经常打不开无法访问,最近尝试了下改host发现效果挺好,方法如下(windows电脑): 进入站长工具网站的域名解析网址:http://tool.ch ...

  4. H5 WebGL实现水波特效

    前言 零几年刚开始玩电脑的时候,经常在安装程序上看到一种水波特效,鼠标划过去的时候,就像用手在水面划过一样,感觉特别有意思.但是后来,就慢慢很少见过这种特效了.最近突然又想起了这种特效,于是开始折磨怎 ...

  5. 《最新出炉》系列入门篇-Python+Playwright自动化测试-7-浏览器的相关操作

    1.简介 上一篇已经将playwright的元素定位大法基本介绍的差不多了,但是在Web的UI自动化的测试中,我们通常需要使用一些方法来操作浏览器,今天就跟随学习了解一下.这一篇宏哥主要是介绍一下,在 ...

  6. 新版Google浏览器跨域Cookie解决方案

    一.前言 针对Chrome版本67及以上 不能将其他域的Cookie传递过来 注意,这个里面的SameSite不能设为null,设空的话,还是会走默认值Lax 其中,SameSite的值可以填3个:S ...

  7. 【持续更新】C/C++ 踩坑记录(一)

    未定义行为之 NULL dereference 下面这段代码中 is_valid() 解引用了空指针 str,我们的直觉是编译运行后将迎来 SIGSEGV,然而事情并非所期望的那样. /* * ub_ ...

  8. linux-服务操作和运行级别和关机重启

    服务操作: service  network   [] systemctl     [ disable(禁用)  enable(启用)]     network [] 中为操作命令 : 1.statu ...

  9. 缓存面试解析:穿透、击穿、雪崩,一致性、分布式锁、Redis过期,海量数据查找

    为什么使用缓存 在程序内部使用缓存,比如使用map等数据结构作为内部缓存,可以快速获取对象.通过将经常使用的数据存储在缓存中,可以减少对数据库的频繁访问,从而提高系统的响应速度和性能.缓存可以将数据保 ...

  10. 记一次MySql灾难性事件

    2023年8月8日,本来系一个风和日丽的夏天中的平凡一天,但这种平凡,注定住佢一定唔平凡,唉...现在回忆起都阵阵咁痛!!! 重要嘅事情讲三次,唔好手贱,唔好手贱,唔好手贱 事日,如常上班,本人系一名 ...