Feign是Netflix开发的声明式、模板化的HTTP客户端,其灵感来自Retrofit、 JAXRS-2.0以及WebSocket.Feign 可帮助我们更加便捷、优雅地调用HTTP API。
在SpringCloud中,使用Feign非常简单----创建一个接口,并在接口上添加一些注解,代码就完成了。Feign 支持多种注解,例如Feign自带的注解或者JAX-RS注解等。
Spring Cloud对Feign进行了增强,使Feign支持了Spring MVC注解,并整合了Ribbon和Eureka,从而让Feign的使用更加方便。
1--引入启动器(消费服务端)
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
2--覆盖默认配置
也可以不做任何配置
3--引导类启用feign ==== 4--内容已经封装好restTemplate了可以不再引入
package com.xiaoai.service;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.SpringCloudApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
//@SpringBootApplication
//@EnableDiscoveryClient //启用eureka客户端,@EnableEurekaClient也可以
//@EnableCircuitBreaker //开启熔断
@SpringCloudApplication //组合注解 相当于@SpringBootApplication、@EnableDiscoveryClient 、@EnableCircuitBreaker
@EnableFeignClients //启动feign组件
public class XiaoaiServiceConsumerApplication {
// @Bean
// @LoadBalanced //开启负载均衡
// public RestTemplate restTemplate(){
// return new RestTemplate();
// }
public static void main(String[] args) {
SpringApplication.run(XiaoaiServiceConsumerApplication.class, args);
}
}
5--定义一个接口
package com.xiaoai.service.client;
import com.xiaoai.service.pojo.User;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@FeignClient("service-provider") //声明一个接口是feign接口,参数为提供服务端的id,即注册时自己所取的名称
public interface UserClient {
@GetMapping("user/{id}") //和提供服务端控制器里的方法一样 ,路径可以手动补,不建议使用@RequestMapping注解在接口上定义
public User queryUserById(@PathVariable("id")Long id);
}
6--控制类方法内
package com.xiaoai.service.controller;
import com.netflix.hystrix.contrib.javanica.annotation.DefaultProperties;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.xiaoai.service.client.UserClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
@RestController
@RequestMapping("/consumer/user")
//@DefaultProperties(defaultFallback = "FalbackMethod") // 定义全局熔断方法
public class UserController {
// //-----------------------------------------------改造消费方,解决地址硬编码问题 启用ribbon负载均衡后
//// @Autowired
//// private RestTemplate restTemplate;
//
// @GetMapping
// @ResponseBody
// @HystrixCommand //声明熔断方法。使用全局默认方法,属性fallbackMethod = "queryUserByIdFalback"可以不用了,但注解还是要。
// public String queryUserById(@RequestParam("id")Long id){
// return this.restTemplate.getForObject("http://service-provider/user/"+id,String.class);
// }
//
// //熔断方法
// public String queryUserByIdFalback(Long id){ //熔断方法返回值必须和控制方法返回值一样
// return "queryUserByIdFalback熔断:服务器正忙,请稍后再试!";
// }
//
// //熔断方法
// public String FalbackMethod(){
// return "全局熔断:服务器正忙,请稍后再试!";
// }
//-----------------------------------------------feign的使用
@Autowired
private UserClient userClient;
@GetMapping
@ResponseBody
//@HystrixCommand //声明熔断方法。
public String queryUserById(@RequestParam("id")Long id){
return this.userClient.queryUserById(id).toString();
}
}
其底层是实例化自己集成的restTemlate,通过注解中的服务名称获取实例,通过路径远程调用提供服务端完成
feign自动集成ribbon负载均衡以及hystrix熔断。所以其也可以达到负载均衡的功能以及支持熔断。
feign默认关闭hystrix熔断,如果需要开启需要手动配置。如:在消费服务端的application配置文件中配置开启熔断。
feign:
hystrix:
enabled: true #开启Feign的熔断功能
feign自定义熔断方法
1--定义一个类实现feign接口,实现方法,方法即是熔断方法 缺点:当接口有多个方法时需要实现多个方法了
package com.xiaoai.service.client;
import com.xiaoai.service.pojo.User;
import org.springframework.stereotype.Component;
@Component
public class UserClientFallback implements UserClient{
@Override
public User queryUserById(Long id) {
User user = new User();
user.setUserName("服务器正忙,请稍后访问!");
return user;
}
}
2--feign接口注解引入实现类即熔断类
package com.xiaoai.service.client;
import com.xiaoai.service.pojo.User;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@FeignClient(value = "service-provider",fallback = UserClientFallback.class)
public interface UserClient {
@GetMapping("user/{id}") //和提供服务端控制器里的方法一样 ,路径可以手动补,不建议使用@RequestMapping注解在接口上定义
public User queryUserById(@PathVariable("id")Long id);
}
3--控制器方法一样
package com.xiaoai.service.controller;
import com.xiaoai.service.client.UserClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/consumer/user")
public class UserController {
//-----------------------------------------------feign的使用
@Autowired
private UserClient userClient;
@GetMapping
@ResponseBody
public String queryUserById(@RequestParam("id")Long id){
return this.userClient.queryUserById(id).toString();
}
}
关闭提供服务端访问相应url 如下:
小结
- 引入openFeign启动器
- 覆盖默认配置 (feign.hystrix.enable=true可以开启feign的熔断功能)
- 引导类上@EnableFeignClients启用
- 创建一个接口 ,使用注解@FeignClient value属性标识提供服务端名称 fallback="熔断方法.class"
- 在接口中定义一些方法,这些方法的书写方式跟之前服务提供端controller中方法类似。
- 可以创建熔断类实现feign接口,实现对应的方法,这些方法就是熔断方法