需求
一个应用通过接口,调用另一个应用的接口。使用OpenFeign来实现接口调用。
说明
通过OpenFeign(本文接下来简称Feign)调用远程接口,需要Eureka注册中心的支持。
OpenFeign调用接口的逻辑如下:
- 提供接口的应用(A),将自身注册到Eureka服务器(注册中心);应用A需要给自己起一个应用名称;
- 调用接口的应用(B),从Eureka读取所有已注册服务的信息;
- B应用的Feign客户端,通过服务的应用名称,从已注册服务的信息中,找到应用A(对应的IP地址和端口号),从而调用A的接口。
本文主要内容
本文主要讲述,如何配置一个注册中心(Eureka),Feign的配置,以及使用Feign来调用接口。
主要包含三个部分:
- 配置Eureka注册中心(单体,非集群);
- 配置提供接口的应用,注册到Eureka:提供被调用的接口;
- 配置调用接口的应用,从Eureka获取到被调用方地址:调用接口。
Eureka服务器
1. 依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
2. 配置(application.properties)
此配置为单体服务器配置,非集群配置。
server.port=8761
# 主机名,不配置的时候将根据操作系统的主机名获取。
eureka.instance.hostname=localhost
# 不将自身注册到注册中心。是否将自己注册到注册中心,默认为true。单个Eureka服务器,不需要注册自身,配置为false;如果是Eureka集群,则需要注册自身,即配置为true。
eureka.client.registerWithEureka=false
# 是否从注册中心获取服务注册信息,默认为true。
eureka.client.fetchRegistry=false
# 注册中心对外暴露的注册地址
eureka.client.serviceUrl.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka/
3. 开启Eureka服务器
在 Application 启动类上,添加注解 @EnableEurekaServer
.
示例代码:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@EnableEurekaServer
@SpringBootApplication
public class EurekaServerDemoApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerDemoApplication.class, args);
}
}
FeignServer
提供接口的应用,可以通过Feign来调用接口。
1. 依赖
- Eureka Discovery Client
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
2. 配置(application.properties)
server.port=8081
# 应用名称
spring.application.name=feign-server
# 使用 ip地址:端口号 注册
eureka.instance.prefer-ip-address=true
eureka.instance.instance-id=${spring.cloud.client.ip-address}:${server.port}
# 注册中心地址
eureka.client.service-url.defaultZone=http://localhost:8761/eureka/
3. 提供接口
package com.example.feign.server.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("feign_server_path")
public class FeignServerController {
@GetMapping("hello")
public String hello() {
return "hello feign server!";
}
@GetMapping("data")
public String getData() {
return "来自FeignServer的数据!";
}
}
Feign客户端
通过Feign,调用FeignServer应用的接口。
1. 依赖
需要引入两个依赖:
- Eureka Discovery Client
- OpenFeign
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
注意:需要通过 <dependencyManagement>
和 <properties>
,管理 spring cloud 版本。如果项目中已经添加,则无需再额外修改。
<dependencyManagement>
<dependencies>
<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>
<properties>
<spring-cloud.version>2021.0.8</spring-cloud.version>
</properties>
2. 配置(application.properties)
server.port=8082
# 不将自身注册到Eureka注册中心。本配置为是否将自己注册到注册中心,默认为true。
eureka.client.registerWithEureka=false
# 注册中心地址
eureka.client.service-url.defaultZone=http://localhost:8761/eureka/
3. 开启Feign客户端
在 Application 启动类上,添加注解 @EnableFeignClients
.
示例代码:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
@EnableFeignClients
@SpringBootApplication
public class FeignClientDemoApplication {
public static void main(String[] args) {
SpringApplication.run(FeignClientDemoApplication.class, args);
}
}
4. 定义接口(与FeignServer对应)
注解 @FeignClient
:表示Feign接口。
value:Feign所调用的应用的应用名称。
path:Feign所调用的应用的对应Controller的接口路径,即 Controller 上 @RequestMapping 中的接口路径。
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
@FeignClient(value = "feign-server", path = "feign_server_path")
public interface FeignInvocationService {
@GetMapping("data")
String getFeignServerData();
}
5. 调用Feign接口
像调用本地方法一样,调用Feign接口。
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.example.feign.client.feign.FeignInvocationService;
@RestController
@RequestMapping("feign_client")
public class FeignClientController {
@GetMapping("hello")
public String hello() {
return "hello feign client!";
}
@Autowired
private FeignInvocationService feignInvocationService;
@GetMapping("feign_server_data")
public String getFeignServerData() {
return "通过FeignClient调用:" + feignInvocationService.getFeignServerData();
}
}