OpenFeign
1.使用Feign访问其他服务
1.依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
2.在服务调用模块启动类上加上@EnableFeignClients注解
@SpringBootApplication
@EnableDiscoveryClient
@EnableCircuitBreaker
@EnableFeignClients(basePackages = "com.fengke.feign")//指定feign接口所在的包。如果 feign结构和启动类在同一个模块下可以不加,不过如果feign接口在另外一个依赖进来的模块中的话必须加上。建议都加上
public class UserConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(UserConsumerApplication.class,args);
}
}
3.定义Feign接口
加上要访问服务提供方的接口如下:
http://user-server/user/findList?id=3 //其中的user-server代表提供方的服务名
则需要定义如下接口和方法 。注意在接口上加FeignClient 并且指定服务名
//声明当前类是一个Feign客户端,指定服务名为user-server
@FeignClient("user-server")
public interface UserFeign {
//要访问这样的接口 http://user-server/user/findList?id=3
@RequestMapping("/user/findList")
public List<User> findList(@RequestParam("id") Integer id);
@RequestMapping("/user/findById") //http://user-server/user/findById?id=3
public List<User> findById(@RequestParam("id") Integer id);
}
注意如果是 http://user-server/user/3 一定要记得在方法参数上加上@PathVariable注解
@GetMapping("/user/{id}")
public User findById(@PathVariable(name = "id") Integer id); //注意PathVariable的name属性必须写上
注意不要再接口上加@RequestMapping 加了会导致后期日志输出问题甚至甚至fallback启动不了
4.使用Feign访问接口
@RestController
public class UserController {
@Autowired
private UserFeign userFeign;
@RequestMapping("/findList")
public List<User> findList(Integer id){
List<User> list = userFeign.findList(id);
System.out.println(list);
log.error("hhh");
return list;
}
}
2.Feign配置
1.负载均衡配置
Feign中本身已经集成了Ribbon依赖和自动配置所以不需要在额外引入Ribbon
Fegin内置的ribbon默认设置了请求超时时长,默认是1000,我们可以通过手动配置来修改这个超时时长:
ribbon:
ReadTimeout: 2000 # 读取超时时长
ConnectTimeout: 1000 # 建立链接的超时时长
因为ribbon内部有重试机制,一旦超时,会自动重新发起请求。如果不希望重试,可以添加配置:
ribbon:
ConnectTimeout: 1000 # 连接超时时长
ReadTimeout: 2000 # 数据通信超时时长
MaxAutoRetries: 0 # 当前服务器的重试次数
MaxAutoRetriesNextServer: 0 # 重试多少次服务
OkToRetryOnAllOperations: false # 是否对所有的请求方式都重试
2.Hystrix熔断配置
#####0.开启熔断
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
启动类开启Hystrix 加@EnableCircuitBreaker
@EnableCircuitBreaker
public class ConsumerApplication {
#####1.开启熔断
feign:
hystrix:
enabled: true # 开启Feign的熔断功能
2.创建一个失败处理类实现要进行降级处理的Feign接口
注意在类上加@Component注解
@Component
public class UserFeignFallback implements UserFeign {
@Override
public List<User> findList(@RequestParam("id") Integer id) {
return Arrays.asList(new User(500,"服务降级了"));
}
}
在FeignClient注解的fallback属性上指定feign接口使用的降级处理类
@FeignClient(name = "user-server",fallback = UserFeignFallback.class)
public interface UserFeign {
//User user = restTemplate.getForObject("http://user-server/user/"+id, User.class);
@GetMapping("/user/{id}") //http://user-server/user/1
public User findById(@PathVariable(name = "id") Integer id);
@GetMapping("/user/findAll")// http://user-server/user/findAll
public List<User> findAll();
}
####3.请求压缩
Spring Cloud Feign 支持对请求和响应进行GZIP压缩,以减少通信过程中的性能损耗。通过下面的参数即可开启请求 与响应的压缩功能:
feign:
compression:
request:
enabled: true # 开启请求压缩
response:
enabled: true # 开启响应压缩
同时,我们也可以对请求的数据类型,以及触发压缩的大小下限进行设置:
feign:
compression:
request:
enabled: true # 开启请求压缩
mime-types: text/html,application/xml,application/json # 设置压缩的数据类型
min-request-size: 2048 # 设置触发压缩的大小下限
4.配置开启Feign日志
1.开启日志配置
logging:
level:
com.fengke: debug
#####2. 编写Feign配置类,定义日志级别
@Configuration
public class FeignConfig {
@Bean
Logger.Level feignLoggerLever(){
return Logger.Level.FULL;
}
}
这里指定的Level级别是
- FULL,Feign支持4种级别:
- NONE:不记录任何日志信息,这是默认值。
- BASIC:仅记录请求的方法,URL以及响应状态码和执行时间
- HEADERS:在BASIC的基础上,额外记录了请求和响应的头信息
- FULL:记录所有请求和响应的明细,包括头信息、请求体、元数据。
#####3.在Feign客户端中配置Feign配置类
@FeignClient(name = "user-server",fallback = UserFeignFallback.class,configuration = FeignConfig.class)
public interface UserFeign {
@RequestMapping("/user/findList")
public List<User> findList(@RequestParam("id") Integer id);
}
4.测试
3.Feign拦截器
可以对通过Feign发生的请求进行拦截,常用于微服务间调用时的认证。
####3.1定义拦截器
定义一个类实现RequestInterceptor
@Component
public class FeignInterceptor implements RequestInterceptor {
@Override
public void apply(RequestTemplate requestTemplate) {
//获取当前线程中的请求对象
ServletRequestAttributes servletRequestAttributes=
(ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = servletRequestAttributes.getRequest();
System.out.println(request);
//判断是否有token这个头,如果有,就把这个头添加到feign发起的请求头上
String token = request.getHeader("token");
if(!StringUtils.isEmpty(token)){
requestTemplate.header("token",token);
}
}
}
如果该类和使用Feign发生请求的代码在同一个模块中上面代码就可以进行拦截。如果不是在同一个模块需要在
调用Feign去访问的模块中增加下面的代码
@Bean
public FeignInterceptor feignInterceptor(){
return new FeignInterceptor();
}
3.2配置隔离策略为信号量
#hystrix 配置
hystrix:
command:
default:
execution:
isolation:
strategy: SEMAPHORE #隔离策略,默认是Thread, 可选Thread|SEMAPHORE