Feign简介
Feign是一个声明式的Web服务客户端,使用Feign可使得Web服务客户端的写入更加方便。
它具有可插拔注释支持,包括Feign注解和JAX-RS注解、Feign还支持可插拔编码器和解码器、Spring Cloud增加了对Spring
MVC注释的支持,并HttpMessageConverters在Spring Web中使用了默认使用的相同方式。Spring
Cloud集成了Ribbon和Eureka,在使用Feign时提供负载平衡的http客户端。
spring cloud中的feign自带负载均衡?
feign
Feign是一个声明式的Web Service客户端,它使得编写Web Serivce客户端变得更加简单。我们只需要使用Feign来创建一个接口并用注解来配置它既可完成。它具备可插拔的注解支持,包括Feign注解和JAX-RS注解。Feign也支持可插拔的编码器和解码器。Spring Cloud为Feign增加了对Spring MVC注解的支持,还整合了Ribbon和Eureka来提供均衡负载的HTTP客户端实现。
在Spring cloud有两种服务调用方式,一种是ribbon+restTemplate,另一种是feign,鉴于feign注解化更方便使用,先讲解feign.
Feign RestTemplate 对比
RestTemplate传送更多的参数时,相当不方便
Feign在参数上非常灵活,本身自带负载均衡
使用Feign
1.加入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
2.启动文件加入enableFeignClients
@EnableEurekaClient
@SpringBootApplication
@EnableFeignClients
public class FeignMovieApplication {
public static void main(String[] args) {
SpringApplication.run(FeignMovieApplication.class, args);
}
}
3.FeignClient接口
spring-boot-user是我的一个微服务的名称:对应的地址是http://192.168.1.105:7900/
@FeignClient("spring-boot-user")
public interface UserFeignClient {
// 两个坑:1. @GetMapping不支持 2. @PathVariable得设置value
@RequestMapping(value="/simple/{id}", method=RequestMethod.GET)
public User findById(@PathVariable("id") Long id);
@RequestMapping(value="/user", method=RequestMethod.POST)
public User postUser(@RequestBody User user);
}
4.调用
@RestController
public class MovieController {
@Autowired
private UserFeignClient userFeignClient;
@GetMapping("/movie/{id}")
public User findById(@PathVariable("id") Long id) {
return this.userFeignClient.findById(id);
}
}
application.yml
#port
server.port = 7600
#spring
spring.application.name=spring-boot-movie-feign
#localhost
#user.userServicePath=http://localhost:7900/simple/
#eureka
eureka.client.healthcheck.enable=true
eureka.client.serviceurl.defaultzone=http://localhost:8761/eureka
eureka.instance.preferIpAddress=true
测试:
http://192.168.1.105:7600/movie/1
RestTemplate三种方式使用
① 直接使用RestTemplate,固定URL
@GetMapping("/say")
public String say(){
RestTemplate restTemplate = new RestTemplate();
String str = restTemplate.getForObject("http://localhost:8081/hello",String.class);
return "say "+str;
}
② 注入LoadBalancerClient通过应用名获取URL
@Autowired
private LoadBalancerClient loadBalancerClient;
@GetMapping("/say")
public String say(){
ServiceInstance serviceInstance = loadBalancerClient.choose("CLIENT");
RestTemplate restTemplate = new RestTemplate();
String url = String.format("http://%s:%s/hello",serviceInstance.getHost(),serviceInstance.getPort());
String str = restTemplate.getForObject(url,String.class);
}
③配置RestTemplate,URL直接使用应用名
@Component
public class RestTemplateConfig {
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
@Autowired
private RestTemplate restTemplate;
@GetMapping("/say")
public String say(){
String response = restTemplate.getForObject("http://CLIENT/hello",String.class);
return "say "+response;
}