Feign 是一个声明式 Web 服务客户端,要使用 Feign 创建一个接口并对其进行注释。它具有可插入的注释支持,Feign 还支持可插拔的编码器和解码器。Spring Cloud 集成了 Eureka、Spring Cloud CircuitBreaker 和 Spring Cloud LoadBalancer,在使用 Feign 时提供负载均衡的 http 客户端。
Feign 和OpenFegin 区别:
Feign是Spring Cloud组件中一个轻量级RESTful的HTTP服务客户端,Feign内置了Ribbon,用来做客户端负载均衡,去调用服务注册中心的服务。Feign的使用方式是:使用Feign的注解定义接口,调用接口,就可以调用服务注册中心的服务。
OpenFeign是Spring Cloud在Feign的基础上支持了SpringMVC的注解,如@RequestMapping等等。OpenFeign的@FeignClient可以解析SpringMVC的@RequestMapping注解下的接口,并通过动态代理的方式产生实现类,实现类中。
案例
pom文件增加 openfeign 依赖(eureka也必须要有)
<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>
启动类增加 @EnableFeignClients
//约定大于配置:如果配置文件配置了注册中心相关配置,则默认开启注册中心注解(@EnableEurekaClient)
@SpringBootApplication
@EnableFeignClients
public class EurekaClient3Application {
public static void main(String[] args) {
SpringApplication.run(EurekaClient3Application.class, args);
}
}
配置文件(完整版,openfeign 相关加了个日志的配置,开启 openfeign 的熔断,超时时间)
server:
port: 8083 #端口号
spring:
application:
name: ludb-client-3 #应用名称
eureka:
instance:
prefer-ip-address: true #是否使用IP地址注册(用于eureka展示)
instance-id: ${spring.cloud.client.ip-address}:${server.port} #当前客户端IP:端口
client:
service-url: #设置服务注册中心地址【向注册中心集群注册(注册两台是为了防止第一台宕机还可以挂在第2台上)】
defaultZone: http://ludb:ludb123@localhost:8761/eureka/,http://ludb:ludb123@localhost:8762/eureka/
registry-fetch-interval-seconds: 10 #表示10秒拉取一次服务注册信息,默认30秒
register-with-eureka: true #是否将自己注册到注册中心,默认true
#默认情况下大多数端点都没有通过 http 公开,我们公开了所有端点,以便SpringAdmin访问
management:
endpoint.health.show-details: always
endpoints:
web:
exposure:
include: '*'
#设置feign日志监控级别
logging:
level:
com.eurekaclient3.feign.FeignService: debug
feign:
circuitbreaker:
#开启feign的熔断处理
enabled: true
client:
config:
default:
#connectTimeout 防止由于服务器处理时间长而阻塞调用者。
connectTimeout: 5000
#readTimeout 从连接建立时开始应用,在返回响应时间过长时触发。
readTimeout: 5000
hystrix:
threadpool.default.coreSize: 10 #包裹默认的线程池
threadpool.messageMoveGroup.coreSize: 5 #包裹默认的线程池
command.default.execution.isolation.thread.timeoutInMilliseconds: 10000 #熔断超时
command.messageMoveCommand.execution.isolation.thread.timeoutInMilliseconds: 600000 #熔断超时
增加了一个 openfeign 的日志配置 (FeignLog.java)
package com.eurekaclient3.config;
import feign.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Logger.Level 您可以为每个客户端配置的对象告诉 Feign 要记录多少。选择是:
* NONE,无日志记录(默认)。
* BASIC, 只记录请求方法和 URL 以及响应状态码和执行时间。
* HEADERS, 记录基本信息以及请求和响应标头。
* FULL, 记录请求和响应的标头、正文和元数据。
*/
@Configuration
public class FeignLog {
@Bean
Logger.Level feignLoggerLevel() {
return Logger.Level.FULL;
}
}
openfeign 接口
@Component //注入IOC容器
@FeignClient(name = "LUDB-CLIENT-1", fallback = FeignImplService.class) //OpenFeign注解,取要掉用的服务名
public interface FeignService {
@RequestMapping(value = "/postUser")
ResponseEntity<Persion> postUser(@RequestBody Persion p);
}
openfeign 接口 实现类
@Component //注入IOC容器
public class FeignImplService implements FeignService {
@Override
public ResponseEntity<Persion> postUser(Persion p) {
return null;
}
}
controller
@RestController
public class ClientController {
@Autowired
private FeignService feignService;
@RequestMapping("/postFeign")
private String postFeign(){
Persion ps = new Persion();
ps.setUserName("卢大宝");
ResponseEntity<Persion> pp = feignService.postUser(ps);
Persion p = pp.getBody();
return p.getUserName();
}
}
被调用 controller
@RestController
public class OrderController {
@Value("${server.port}")
Integer port;
@RequestMapping("/postUser")
private Persion postUser(@RequestBody Persion p){
p.setUserName(p.getUserName() + port);
return p;
}
}
Eureka