目录
1 简介
2 入门案例与分析
2.1 入门案例
2.2 分析Feign的特点
3 Feign 支持负载均衡
4 Feign 支持熔断器
5 配置请求与响应压缩
6 配置日志
前面学习中,使用RestTemplate进行远程调用的方式如下:
String baseUrl = "http://user-service/user/findById?id="+ id;
User user = restTemplate.getForObject(baseUrl, User.class)
目标:使用Feign替代RestTemplate发送Rest请求,使之更符合面向接口化的编程习惯。
实现步骤
1 导入依赖feign的starter :
org.springframework.cloud
spring-cloud-starter-openfeign
2 启动引导类加@EnableFeignClients注解
@SpringCloudApplication
@EnableFeignClients//开启Feign功能
public class ConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class,args);
}
}
3 编写FeignClient接口,使用SpringMVC的注解
FeignClient接口写在工程的service层下:
//声明当前接口是feign客户端的接口,并指定feign调用的服务名为user-service
@FeignClient("user-service")
public interface UserService {
/**
* 接口定义的方法,采用SpringMVC的注解 @RequestMapping
* Feign会通过动态代理,帮我们生成该接口的实现类
* Feign会根据注解帮我们逆向生成URL地址然后请求
* 在Controller中注入UserService接口,直接调用,无需实现类
*/
@RequestMapping("/user/findById")
User findById(@RequestParam("id") Integer id);
}
4 在Controller中注入Feign接口,直接调用,无需实现类
/**
* 通过feign客户端发送请求
*/
@RestController
@DefaultProperties(defaultFallback = "defaultFallBackMethod")
public class FeignConsumerController {
//注入Feign客户端的接口,直接调用
@Autowired
private UserService userService;
@RequestMapping("/feign_consumer/{id}")
public User consumerSendRequest(@PathVariable("id") Integer id){
return userService.findById(id);
}
}
5 测试
http://localhost:8080/feign_consumer/2
哪里需要http调用,就把这个feign接口(整合了某个具体的http调用)注入到哪里,并且这个feign接口上标注了“服务名”以及“被调用服务的上下文”,一旦这些内容发生改动,只需要改一次feign接口即可,而不用每次都跑到具体的方法里面一个个去修改url地址了
同一个服务下的不同方法调用都放到了一起,便于管理,而不是零散的状态。
可读性更好,更有层次感。
# 连接超时时长:必须都要大于服务响应时间,否则一旦设置了熔断则会触发服务降级
ribbon.ConnectTimeout: 6000
# 读取数据超时时长:必须都要大于服务响应时间,否则一旦设置了熔断则会触发服务降级
ribbon.ReadTimeout: 6000
# 当前服务器的重试次数【针对请求】
ribbon.MaxAutoRetries: 0
# 重试多少次服务【针对服务】
ribbon.MaxAutoRetriesNextServer: 0
# 是否对所有的请求方式都重试
ribbon.OkToRetryOnAllOperations: false
Feign本身也集成Hystrix熔断器,服务降级方法实现步骤:
1 在配置文件application.yml中开启feign熔断器支持 :
feign.hystrix.enabled: true # 开启Feign的熔断功能
2 实现FeignClient客户端接口,在实现类中编写FallBack处理类
/**
* feign客户端接口的实现类:直接作为服务降级的处理类
*/
@Component
public class UserServiceImpl implements UserService {
@Override
public User findById(Integer id) {
User user = new User();
user.setUsername("服务降级处理!");
return user;
}
}
3 在@FeignClient注解中,指定FallBack处理类
//声明当前接口是feign客户端的接口,并指定feign调用的服务名为user-service
//该注解会生成接口的动态代理实现类,并将其注入到spring容器中
//fallback属性:指定服务降级的处理类
@FeignClient(value = "user-service",fallback = UserServiceImpl.class)
public interface UserService {
/**
* 接口定义的方法,采用SpringMVC的注解 @RequestMapping
* Feign会通过动态代理,帮我们生成该接口的实现类
* Feign会根据注解帮我们逆向生成URL地址然后请求
* 在Controller中注入UserService接口,直接调用,无需实现类(如果要用熔断,则需要写实现类)
*/
@RequestMapping("/user/findById")
User findById(@RequestParam("id") Integer id);
}
4 测试
http://localhost:8080/feign_consumer/1
feign:
compression:
# 开启请求压缩
request:
enabled: true
#开启压缩的阈值,默认2048kb
min-request-size: 2048
#压缩的数据类型
mime-types: text/xml, application/xml, application/json
# 开启响应压缩
response:
enabled: true
级别 | 说明 |
---|---|
NONE | 不做任何记录 |
BASIC | 只记录输出Http 方法名称、请求URL、返回状态码和执行时间 |
HEADERS | 记录输出Http 方法名称、请求URL、返回状态码和执行时间 和 Header 信息 |
FULL | 记录Request 和Response的Header,Body和一些请求元数据 |
Feign配置日志步骤:
1 在application.yml配置文件中开启日志级别配置
#com.lmy.service 包下的日志级别都为Debug
logging.level.com.lmy.service: debug
2 编写配置类,定义日志级别bean
/**
* Feign客户端接口的配置类
*/
@Configuration
public class FeignConfiguration {
/**
* 注入日志级别的配置到spring容器中
*/
@Bean
public Logger.Level loggerLevel(){
//配置显示全部的日志信息
return Logger.Level.FULL;
}
}
3 在接口的@FeignClient中指定配置类
//声明当前接口是feign客户端的接口,并指定feign调用的服务名为user-service
//该注解会生成接口的动态代理实现类,并将其注入到spring容器中
//fallback属性:指定服务降级的处理类
//configuration属性:指定当前feign客户端的配置类
@FeignClient(value = "user-service",
fallback = UserServiceImpl.class,
configuration = FeignConfiguration.class)
public interface UserService {
/**
* 接口定义的方法,采用SpringMVC的注解 @RequestMapping
* Feign会通过动态代理,帮我们生成该接口的实现类
* Feign会根据注解帮我们逆向生成URL地址然后请求
* 在Controller中注入UserService接口,直接调用,无需实现类(如果要用熔断,则需要写实现类)
*/
@RequestMapping("/user/findById")
User findById(@RequestParam("id") Integer id);
}
4 测试