Spring Cloud Feign 介绍
Feign是一个声明式的Web服务客户端。这使得Web服务客户端的写入更加方便 要使用Feign创建一个界面并对其进行注释。它具有可插拔注释支持,包括Feign注释和JAX-RS注释。Feign还支持可插拔编码器和解码器。Spring Cloud添加了对Spring MVC注释的支持,并在Spring Web中使用默认使用的HttpMessageConverters。Spring Cloud集成Ribbon和Eureka以在使用Feign时提供负载均衡的http客户端。
说白了,就是封装了Http调用流程,微服务之间调用API更加方便!
Feign 设计图
使用Feign实现服务之间调用
Feign子项目搭建
接着上一篇再创建一个子项目consumer-feign
pom文件
引入feign所需的jar包即可
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
yml配置
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8800/eureka/,http://localhost:8810/eureka/
server:
tomcat:
uri-encoding: UTF-8
port: 10002
# servlet:
# context-path: /gbq_consumer
spring:
main:
allow-bean-definition-overriding: true #避免相同名字的Feign注册会导致重复注册
application:
name: consumer-feign
启动类
@SpringBootApplication
@EnableFeignClients
//@EnableDiscoveryClient
public class ConsumerFeignApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerFeignApplication.class, args);
}
}
Controller
@RestController
public class HiController {
@Autowired
private GetHello getHello;
@GetMapping("/hi")
public String sayHello(String name){
return getHello.sayHello(name);
}
@GetMapping("/test")
public User getPostUser(User user){
return getHello.getPostUser(user);
}
@GetMapping("/getUser")
public User getUser(User user){
return getHello.getUser(user);
}
}
此处写了三个方法,为的就是踩坑,填坑!具体坑我已经在代码注释中写明了!
GetHello接口类
@FeignClient(name = "provider",path = "gbq_provider")
//@FeignClient(name = "provider")
public interface GetHello {
//坑一
//@GetMapping 不支持
@RequestMapping(value = "/hello",method = RequestMethod.GET)
String sayHello(@RequestParam("name")String name);
//坑二 传递参数必须使用对应注解
@RequestMapping(value = "/getPostUser",method = RequestMethod.POST)
User getPostUser(@RequestBody User user);
//坑三 传递参数为复杂参数是请求方式即便设置为get,但仍然以post请求发送
@RequestMapping(value = "/getUser",method = RequestMethod.GET)
User getUser(@RequestBody User user);
}
User类
public class User {
private Integer id;
private String name;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
provider的Controller类
也就之前文章中创建的provider,provider-copy俩个子项目,为了一会更好的体现feign和ribbon整合实现负载均衡,所以俩个项目的Controller和上一篇一样,写一样的方法。
注意注释
@RestController
public class HelloController {
@Value("${server.port}")
private int port;
@Resource
private HelloService helloService;
@GetMapping("/hello")
public String sayHello(String name){
return "你好,cloud"+"name:"+name+"port:"+port;
}
@PostMapping("/getPostUser")
public User getPostUser(@RequestBody User user){
return user;
}
/**
* 此处就可以看到,我是使用get请求发送,却用了post接收
**/
@PostMapping("/getUser")
public User getUser(@RequestBody User user){
return user;
}
}
启动
此处因为我启动了俩个相同名称的提供者服务,也就是provider,provider-copy,请求的时候,会按照顺序请求!
这几个请求之间建议好好对比一下,你也可以在Feign调用接口类里边,多尝试不同请求方式,以及不同的参数格式,发送请求!
上一篇文章提到一个坑,就是配置了context-path或者server-path之后,就请求不到了,而feign解决了这个问题
@FeignClient(name = "provider",path = "gbq_provider") //配置这个path就可以了
feign结合ribbon进行服务之间调用
其实这个很简单。
feign结合ribbon子项目搭建
直接复制一份feign。
pom文件
加入ribbon即可
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
yml配置
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8800/eureka/,http://localhost:8810/eureka/
server:
tomcat:
uri-encoding: UTF-8
port: 10003
# servlet:
# context-path: /gbq_consumer
spring:
main:
allow-bean-definition-overriding: true #避免相同名字的Feign注册会导致重复注册
application:
name: consumer-feign-ribbon
启动类
@SpringBootApplication
@EnableFeignClients
//@EnableDiscoveryClient
public class ConsumerFeignRibbonApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerFeignRibbonApplication.class, args);
}
@Bean
@LoadBalanced
RestTemplate restTemplate(){
return new RestTemplate();
}
/**
* 配置随机负载策略,需要配置属性service-B.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule
*/
@Bean
public IRule ribbonRule() {
return new RandomRule();
}
}
其他类和feign子项目一样
启动
同样实现了负载均衡!