首页 > 其他分享 > Spring Cloud OpenFeign系列:简介和使用

Spring Cloud OpenFeign系列:简介和使用

时间:2023-10-22 16:36:05浏览次数:43  
标签:OpenFeign spring Spring springframework Cloud import org order cloud

目录

一、简介

官网: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

image

测试

image

四、配置说明

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

默认值

image

3、所有配置

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

五、负载均衡

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

更换负载均衡策略

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

image

image

image

image

注意:关闭之前的超时和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);
   }
}

image

五、对比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

标签:OpenFeign,spring,Spring,springframework,Cloud,import,org,order,cloud
From: https://www.cnblogs.com/vic-tory/p/17780620.html

相关文章

  • springboot整合swagger3.0
    pom文件中导入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId></dependency>application.yml中写入配置swagger:enable:tr......
  • springboot+vue学习(2)
    1、ref :为子组件指定一个索引ID,给元素或者组件注册引用信息。refs是一个对象,包含所有的ref组件。<divid="parent"><user-profileref="profile"></user-profile>(子组件)</div>varparent=newVue({el:'#parent'})//访问子组件varchild=parent.$ref......
  • Error creating bean with name 'org.springframework.web.servlet.handler.BeanNameU
    Errorcreatingbeanwithname'org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping':Instantiationofbeanfailed;nestedexceptionisorg.springframework.beans.BeanInstantiationException:Failedtoinstantiate[org.springframework......
  • springboot+vue学习
    最近遇到一个问题,在一个页面需要动态渲染页面内的表单,其中包括checkbox表单类型,并且使用Element组件UI时,此时v-model绑定的数据也是动态生成的例如:定义的data的form里面是空对象,需要动态生成里面的keyexportdefault{data(){return{form:{}......
  • Springboot基础
    接口测试工具:postman参数原始方法Springboot方式复杂实体参数数组实体参数日期参数JSON参数路径参数响应数据......
  • CloudFlareWarpMac解决方案优化
    https://1.1.1.1 cd/Applications/Cloudflare\WARP.app/Contents/Resources/   #执行下面的 warp-cliset-custom-endpoint 188.114.96.198:2408 #换成其他的engage.cloudflareclient.com域名也行 #禁用网络检查  warp-clidisable-connectivity-check......
  • Redis和Spring Boot:如何协作提高您的应用程序性能
    环境说明:Windows10+Idea2021.3.2+Jdk1.8+SpringBoot2.3.1.RELEASE前言Redis是一种高效的非关系型数据库,能够支持复杂的数据结构和操作。在SpringBoot应用中,集成Redis可以提供更好的性能和扩展性。本文将介绍如何在SpringBoot应用中集成Redis并使用其基本功能......
  • Spring Boot中的过滤器、拦截器、监听器技巧汇总:让你快速成为大神
    环境说明:Windows10+Idea2021.3.2+Jdk1.8+SpringBoot2.3.1.RELEASE前言在Web应用程序中,我们经常需要处理请求和响应。有时,我们需要应用于所有请求和响应的通用逻辑。这就是过滤器、拦截器和监听器的用武之地。它们可以帮助我们在请求和响应被处理之前或之后执行一些通用逻......
  • SpringBoot中给Tomcat添加过滤器
    SpringBoot中给Tomcat添加过滤器目录SpringBoot中给Tomcat添加过滤器一、引入二、Filter功能概述三、添加过滤器进行实操3.1、注解版3.2、配置版本四、原理探究4.1、解析过程4.2、如何添加到ServletContext中?五、总结一、引入JavaWeb组件Servlet提供了filter过滤功能,其功能是对......
  • SpringBoot——yaml配置文件
    yaml简介YAML是"YAMLAin'taMarkupLanguage"(YAML不是一种标记语言)。在开发的这种语言时,YAML的意思其实是:"YetAnotherMarkupLanguage"(是另一种标记语言)。设计目标,就是方便人类读写层次分明,更适合做配置文件使用.yaml或.yml作为文件后缀基本语法大小写敏感使......