1、开始之前
如题,本文记录的是Feign的基本使用,本文是在已经搭建了注册中心和服务提供方的基础上 进行的。阅读本文前可以看下这两篇博文。
为什么要使用Feign (引用)
Feign 旨在使编写 Java Http 客户端变得更容易。
前面在使用 Ribbon + RestTemplate 时,利用 RestTemplate 对 http 请求的封装处理,形成了一套模板化的调用方法。但是在实际开发中,由于对服务依赖的调用可能不止一处,往往一个接口会被多处调用,所以通常都会针对每个微服务自行封装一些客户端类来包装这些依赖服务的调用。
所以,Feign 在此基础上做了进一步的封装,由它来帮助我们定义和实现依赖服务接口的定义。使用 Feign 只需要创建一个接口并使用一个注解来配置它即可。这就类似于我们在 dao 层的接口上标注 @Mapper 注解一样。这样的话,即完成了对服务提供方的接口绑定,简化了使用 Spring Cloud Ribbon 时的开发量。
2、开始Feign
(1)项目初始化
使用Spring初始化平台或者idea的Spring Initializr进行项目的初始化建立,需要添加的依赖有web,Eureka Discovery Client和 Feign
初始化以后的pom文件为
<?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>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.10.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.demo</groupId>
<artifactId>service-consumer</artifactId>
<version>0.0.1</version>
<name>service-consumer</name>
<description>服务消费者</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Hoxton.SR11</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<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-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<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>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
(2)yml文件配置
server:
port: 9600
spring:
application:
name: service-consumer-feign
eureka:
instance:
ip-address: true
client:
register-with-eureka: true #需要去注册中心注册自己
fetch-registry: true #需要去注册中心获取其他服务的地址
serviceUrl:
#defaultZone: http://localhost:3000/eureka/
defaultZone: http://eureka2:3000/eureka/,http://eureka1:3000/eureka/ #eureka 注册中心的地址
(3)启动类注解
启动类上添加@EnableDiscoveryClient和@EnableFeignClients注解
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
@EnableDiscoveryClient
@EnableFeignClients
public class FeignApplication {
public static void main(String[] args) {
SpringApplication.run(FeignApplication.class, args);
}
}
(4)写Feign客户端
其实就是写成接口的形式以供controller或其他地方调用:(调用的服务是采用之前的例子)
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;
@FeignClient("server-provider") // 要调用服务的名字
public interface UserService {
@RequestMapping(value = "/user/getNameByUserId/{id}", method = RequestMethod.GET) // 要调用路径 和方式
public String getNameByUserId(@PathVariable("id") int id);
}
(5)调用Feign
这里沿用以前的方式写一个get接口 用浏览器访问
import com.demo.feign.service.UserService;
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;
import java.util.List;
@RestController
@RequestMapping("/users")
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/getNameByUserId/feign/{id}")
public String getNameByUserId(@PathVariable("id")int id){
String nameByUserId = userService.getNameByUserId(id);
System.out.println(nameByUserId);
return nameByUserId;
}
}
3、测试运行
测试的时候需要yml中配置测注册中心,和Feign客户端里写的服务生产者,我使用的注册中心和服务生产者都是在其他地方写过的,大家可以前去查看,或者使用自己的注册中心和服务提供者
加上Feign三个项目都要运行 然后访问开放的接口http://localhost:9600/users/getNameByUserId/feign/3
4、Ribbon使用(已实现)
在之前的博文中写了Ribbon的用法,但是在Feign中已经包含了Ribbon,其中默认的负载均衡方式为轮询
网上其他博客说 这个负载均衡的方式可以在yml配置文件中直接修改
server-provider: # 服务名
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # 负载均衡规则
但是我配置以后不能实现这个,测试的时候还是轮询的,我在项目找不到这个类com.netflix.loadbalancer.RandomRule,
所以有哪位知道这个问题出在什么地方,感谢留言指导。经过修改Spring boot版本和Spring Cloud版本才生效 不知道为什么 Spring Cloud好多组件不支持 2.4.0版本以上的Spring boot