[SpringCloud教程]6. OpenFeign远程接口调用

813 阅读2分钟

OpenFeign是声明式方式定义Web服务的客户端(说白了就是将原有的url请求调用转化为本地方法调用一样方便快捷),并可通过集成Ribbon或Eureka实现负载均衡。

集成

  • 在SpringCloud案例项目里建立新模块 ms-consumer-eureka-openfeign,并在父pom里声明,该模块pom.xml如下
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.spz.demo</groupId>
        <artifactId>spring-cloud-demo</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <artifactId>ms-consumer-eureka-openfeign</artifactId>
    <packaging>jar</packaging>

    <description>消费者模块 - 使用Eureka注册中心 - 使用OpenFeign客户端</description>

    <dependencies>

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

        <!-- Eureka Client -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

        <dependency>
            <groupId>com.spz.demo</groupId>
            <artifactId>api-common</artifactId>
            <version>${project.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>true</filtering>
            </resource>
        </resources>
    </build>

</project>
  • application.properties 配置如下
server.port=7001

# Eureka
eureka.client.register-with-eureka=false
eureka.client.service-url.defaultZone=http://eureka6001:6001/eureka,http://eureka6002:6002/eureka,http://eureka6003:6003/eureka

# Feign 日志级别
logging.level.com.spz.demo.scloud.consumer.openfeign.service.IEurekaProviderService=debug

# Feign 超时配置
openfeign.connectTimeoutMs=1000
openfeign.readTimeoutMs=5000
  • 配置类OpenFeignConfiguration.java
package com.spz.demo.scloud.consumer.openfeign.config;

import com.netflix.ribbon.Ribbon;
import feign.Logger;
import feign.Request;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * OpenFeign 配置
 * @author spzmmd
 * @createTime 2021/04/12
 */
@Configuration
public class OpenFeignConfiguration {

    /**
     * 连接超时
     * 单位: ms
     */
    @Value("${openfeign.connectTimeoutMs}")
    private int connectTimeoutMs;

    /**
     * 读取超时
     * 单位: ms
     */
    @Value("${openfeign.readTimeoutMs}")
    private int readTimeoutMs;

    /**
     * 配置超时时间
     * @return
     */
    @Bean
    public Request.Options options() {
        return new Request.Options(connectTimeoutMs, readTimeoutMs);
    }

    /**
     * 配置OpenFeign输出什么日志, 方便调试
     * @return
     */
    @Bean
    public Logger.Level feignLoggerLevel() {
        return Logger.Level.FULL;
    }
}
  • 启动类 ConsumerOpenFeignApp.java
package com.spz.demo.scloud.consumer.openfeign;

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

@EnableFeignClients
@SpringBootApplication
public class ConsumerOpenFeignApp {
    public static void main(String[] args) {
        SpringApplication.run(ConsumerOpenFeignApp.class, args);
    }
}
  • 通过OpenFeign来实现微服务接口调用的方法是,将接口调用声明为一个个接口方法,如下代码
package com.spz.demo.scloud.consumer.openfeign.service;

import com.spz.demo.scloud.common.core.bean.RestBean;
import com.spz.demo.scloud.consumer.openfeign.config.OpenFeignConfiguration;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;

/**
 * Eureka 服务提供者 接口
 * 用于配置 Feign 接口
 * @author spzmmd
 * @createTime 2021/04/12
 */
@Component
@FeignClient(value = "MS-PROVIDER", configuration = OpenFeignConfiguration.class)
public interface IEurekaProviderService {

    @GetMapping(value = "/projectInfo")
    public RestBean projectInfo();

}
  • 测试用的控制器
package com.spz.demo.scloud.consumer.openfeign.controller;

import com.spz.demo.scloud.common.core.bean.RestBean;
import com.spz.demo.scloud.common.service.AppService;
import com.spz.demo.scloud.consumer.openfeign.service.IEurekaProviderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * 测试 openFeign
 * @author spzmmd
 * @createTime 2021/04/12
 */
@RestController
@RequestMapping("/openFeign")
public class OpenFeignTestController {

    // 使用OpenFeign,实现以接口调用的方式来进行网络请求
    @Autowired
    private IEurekaProviderService eurekaProviderService;

    /**
     * 服务远程调用测试 - 使用 openFeign
     * @return
     */
    @RequestMapping("/projectInfo")
    public RestBean appServiceProjectInfo(){
        RestBean restBean = eurekaProviderService.projectInfo();
        return restBean;
    }
}
  • 运行时,需要启动eureka-server(用于服务注册发现) 和两个ms-provider节点,用于测试OpenFeign方式调用微服务接口,而后启动ms-consumer-eureka-openfeign模块,不断访问如下地址:
http://localhost:7001/openFeign/projectInfo

正常应该分别返回两个服务的端口号(OpenFeign默认支持负载均衡)

{
  "code": 2000,
  "message": "MS-PROVIDER:8001: (基于Eureka注册中心)",
  "data": null
}

{
  "code": 2000,
  "message": "MS-PROVIDER:8002: (基于Eureka注册中心)",
  "data": null
}

交流&联系

  • QQ群 欢迎加入Java交流群(qq群号: 776241689 )

  • 欢迎关注公众号"后端技术学习分享"获取更多技术文章! PS:小到Java后端技术、计算机基础知识,大到微服务、Service Mesh、大数据等,都是本人研究的方向。我将定期在公众号中分享技术干货,希望以我一己之力,抛砖引玉,帮助朋友们提升技术能力,共同进步!

  • 博客

原创不易,转载请在开头著名文章来源和作者。如果我的文章对您有帮助,请点赞/收藏/关注鼓励支持一下吧❤❤❤❤❤❤