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; }