介绍
Spring Cloud Feign 基于Netflix Feign 实现,整合了Spring Cloud Ribbon 和Spring Cloud Hystrix。
简单使用
#pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
消费者主类
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
@EnableFeignClients
@EnableDiscoveryClient
@SpringBootApplication
public class FeignConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(FeignConsumerApplication.class, args);
}
}
消费者Controller
package com.example.demo.controller;
import com.example.demo.service.HelloService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ConsumerController {
@Autowired HelloService helloService;
@RequestMapping("/feign-consumer")
public String helloConsumer() {
return helloService.hello();
}
@RequestMapping("/feign-consumer2")
public String helloConsumer2() {
StringBuilder sb = new StringBuilder();
sb.append(helloService.hello()).append("\n");
sb.append(helloService.hello("Abner")).append("\n");
sb.append(helloService.hello("Abner",24)).append("\n");
sb.append(helloService.hello(new User("Abner",24))).append("\n");
return sb.toString();
}
}
消费者Service接口
package com.example.demo.service;
import com.example.demo.controller.User;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;
@FeignClient(value = "hello-service")
public interface HelloService {
@RequestMapping("/hello")
public String hello();
@RequestMapping(value = "/hello1", method = RequestMethod.GET)
public String hello(@RequestParam("name") String name);
@RequestMapping(value = "/hello2", method = RequestMethod.GET)
public User hello(@RequestHeader("name") String name, @RequestHeader("age") Integer age);
@RequestMapping(value = "/hello3", method = RequestMethod.POST)
public String hello(@RequestBody User user);
}
关于继承
开发过程中可以发现消费者service接口和服务提供者Controller方法名和注解一模一样,大部分情况下可以采用接口共享的方式,但是接口变动就会对项目构建造成影响,比如服务提供方修改了接口,那会直接导致客户端消费者工程构建失败,所以不是很推荐这种做法。
Ribbon 配置
全局配置
ribbon.ConnectTimeout=500
ribbon.ReadTimeout=5000
指定服务配置
<client>.ribbon.key=value
例如:
HELLO-SERVICE.ribbon.ConnectTimeout=500
HELLO-SERVICE.ribbon.ReadTimeout=5000
...
Hystrix配置
全局配置
hystrix.command.default.execution.timeout.enabled=true
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=1000
配置类方式
package com.example.demo;
import feign.Feign;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
@Configuration
public class DisableHystrixConfiguration {
@Bean
@Scope("prototype")
public Feign.Builder feignBuilder(){
return Feign.builder();
}
}
使用
@FeignClient(value = "hello-service",configuration = DisableHystrixConfiguration.class)
指定命令配置方式
hystrix.command.<CommandKey>...
例如
hystrix.command.hello.execution.isolation.thread.timeoutInMilliseconds=5000
服务降级
package com.example.demo.service;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestParam;
@Component
public class HelloServiceFallback implements HelloService {
@Override
public String hello() {
return "error";
}
@Override
public String hello(@RequestParam("name") String name) {
return "error";
}
@Override
public User hello(@RequestHeader("name") String name, @RequestHeader("age") Integer age) {
return new User("未知", 0);
}
@Override
public String hello(@RequestBody User user) {
return "error";
}
}
降级类使用
@FeignClient(name="HELLO-SERVICE", fallback = HelloServiceFallback.class)
Feign日志配置
logging.level.com.didispace.web.HelloService=DEBUG