什么是Feign
- Feign是一个声明式WebService客户端。使用Feign能让编写WebService客户端更加简单,它的使用方法是定义一个接口,然后在上面添加注解。不再需要拼接URL,参数等操作。Feign 组件就诞生了,它方便了服务之间的调用。
使用案例
- 在消费者工程中,引入依赖,配置feign
<!--配置feign-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
- 在消费者user-consumer工程中创建feign接口(只是普通接口,名字以UserClient为例)
/**
* Feign客户端入门
*/
@FeignClient(value = "user-provider") //声明Feign的客户端,value:填写生产者的名称
public interface UserClient {
//注意:此处的请求地址一定要和生产者请求的地址一样
@RequestMapping("/user/find/{id}")
public User findById(@PathVariable("id")Integer id);
}
在@FeignClient中的value值的由来(服务user-provider已经注册到Eureka),如图:
方法findById的由来,如图:
3. 在user-consumer消费者工程中创建ConsumerFeignController,在Controller中使用@Autowired注入FeignClient,代码如下
@RestController
@RequestMapping("feign")
public class ConsumerFeignController {
@Autowired
private UserClient userClient;
@RequestMapping("{id}")
public User findById(@PathVariable(value = "id")Integer id){
return userClient.findByUserId(id);
}
}
- 开启Feign,修改user-consumer消费者的启动类,在启动类上添加@EnableFeignClients注解,开启Feign,代码如下:
@SpringBootApplication
@EnableDiscoveryClient //开启eureka发现功能
@EnableCircuitBreaker //开启熔断器
@EnableFeignClients //开启Feign客户端
public class UserConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(UserConsumerApplication.class,args);
}
/***
* 将RestTemplate的实例放到Spring容器中
* @return
*/
@Bean
@LoadBalanced //开启负载均衡
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
- 测试,通过访问 http://localhost:18082/feign/2 得到了生产者的服务,查询到了指定id的数据
负载均衡
- Feign自身已经集成了Ribbon,因此使用Feign的时候,不需要额外引入依赖。
- Feign内置的ribbon默认设置了请求超时时长,默认是1000,可以修改
ribbon内部有重试机制,一旦超时,会自动重新发起请求。如果不希望重试可以关闭配置(生产者配置文件):
# 修改服务地址轮询策略,默认是轮询,配置之后变随机
user-provider:
ribbon:
#轮询
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRule
#随机算法
#NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
ConnectTimeout: 10000 # 连接超时时间
ReadTimeout: 2000 # 数据读取超时时间
MaxAutoRetries: 1 # 最大重试次数(第一个服务)
MaxAutoRetriesNextServer: 0 # 最大重试下一个服务次数(集群的情况才会用到)
OkToRetryOnAllOperations: false # 无论是请求超时或者socket read timeout都进行重试,一般设置为false