spring cloud学习--feign

简单示例

增加feign maven依赖

<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-feign</artifactId>
        </dependency>

修改主类

//激活erueka中的DiscoveryClient实现
//自动化配置,创建DiscoveryClient接口针对Eureka客户端的EurekaDiscoveryClient实例
@EnableFeignClients
@EnableDiscoveryClient
@SpringBootApplication
public class EurekaServerApplication {

	public static void main(String[] args) {
		SpringApplication.run(EurekaServerApplication.class, args);
	}
}

通过@FeignClient注解绑定服务

//不区分大小写
@FeignClient("eureka-client")
public interface HelloService
{
    @RequestMapping(value = "/hello", method = RequestMethod.GET)
    String index();
}

调用服务

RestController
public class ConsumerController
{
    @Autowired
    HelloService helloService;

    @RequestMapping(value = "/feign-consumer", method = RequestMethod.GET)
    public String helloController()
    {
        return helloService.index();
    }
}

参数绑定

增加User类

public class User
{
    private String name;
    private Integer age;

    public User()
    {

    }

    public User(String name, Integer age)
    {
        this.name = name;
        this.age = age;
    }

    public String getName()
    {
        return name;
    }

    public void setName(String name)
    {
        this.name = name;
    }

    public Integer getAge()
    {
        return age;
    }

    public void setAge(Integer age)
    {
        this.age = age;
    }

    @Override
    public String toString()
    {
        return "User{" + "name='" + name + '\'' + ", age=" + age + '}';
    }
}

在提供的服务中增加FeignController类和下面的User类

@RestController
public class FeignController
{
    @RequestMapping(value = "/hello1", method = RequestMethod.GET)
    public String hello(@RequestParam String name)
    {
        return "Hello " + name;
    }

    @RequestMapping(value = "/hello2", method = RequestMethod.GET)
    public User hello(@RequestHeader String name, @RequestHeader Integer age)
    {
        return new User(name, age);
    }

    @RequestMapping(value = "/hello3", method = RequestMethod.POST)
    public String hello(@RequestBody User user)
    {
        return "Hello " + user.getName() + ", " + user.getAge();
    }
}

增加HelloService类

//不区分大小写
@FeignClient("eureka-client")
public interface HelloService
{
    @RequestMapping(value = "/hello", method = RequestMethod.GET)
    String hello();

    @RequestMapping(value = "/hello1", method = RequestMethod.GET)
    String hello(@RequestParam("name") String name);

    @RequestMapping(value = "/hello2", method = RequestMethod.GET)
    User hello(@RequestHeader("name") String name, @RequestHeader("age") Integer age);

    @RequestMapping(value = "/hello3", method = RequestMethod.POST)
    String hello(@RequestBody User user);

增加ConsumerController类

@RestController
public class ConsumerController
{
    @Autowired
    HelloService helloService;

    @RequestMapping(value = "/feign-consumer", method = RequestMethod.GET)
    public String helloConsumer()
    {
        return helloService.hello();
    }

    @RequestMapping(value = "/feign-consumer2", method = RequestMethod.GET)
    public String helloConsumer2()
    {
        StringBuilder sb = new StringBuilder();
        sb.append(helloService.hello()).append("\n");
        sb.append(helloService.hello("zhangsan")).append("\n");
        sb.append(helloService.hello("zhangsan", 20)).append("\n");
        sb.append(helloService.hello(new User("zhangsan", 20))).append("\n");
        return sb.toString();
    }
}

调用http://localhost:9001/feign-consumer2返回

hello world! Hello zhangsan User{name='zhangsan', age=20} Hello zhangsan, 20

feign中ribbon配置

feign中包含ribbon,其客户端负载均衡是通过ribbon实现的

ribbon全局配置

直接使用ribbon.=方式配置参数

ribbon.ConnectTimeout=500
ribbon.ReadTimeout=5000

指定服务配置

<服务名>.ribbon.=

HELLO-SERVICE.ribbon.ConnectTimeout=500
HELLO-SERVICE.ribbon.ReadTime=2000
HELO-SERVICE.ribbon.OkToRetryOnAllOperations=true
HELLO-SERVICE.ribbon.MaxAutoRetriesMextServer=2
HELLO-SERVICE.ribbon.MaxAutoRetries=1

feign中Hystrix配置

feign中包含了Hystrix断路器

全局配置

直接使用前缀hystrix.command.default进行配置,eg:

hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=5000

开启和关闭feign中hystrix断路器功能

feign.hystrix.enabled=true/false

开启和关闭熔断功能

hystrix.command.default.execution.timeout.enabled=true/false

指定客户端配置

  • 构建一个关闭Hystrix的配置
@Configuration
public class DisableHystrixConfiguration
{
    @Bean
    @Scope("prototype")
    public Feign.Builder feignBuilder()
    {
        return Feign.builder();
    }
}
  • 在@FeignClient注解的类中,通过configuration参数引入实现的配置
@FeignClient(name="HELLO-SERVICE", configuration=DisableHystrixConfiguration.class)
public interface HelloService
{
    ...
}

服务降级

与单独使用Hystrix服务降级有很大区别

  • 创建服务接口的实现类
@Component
public class HelloServiceFallback implements HelloService
{

    @Override
    public String hello()
    {
        return "error";
    }

    @Override
    public String hello(String name)
    {
        return "error";
    }

    @Override
    public User hello(String name, Integer age)
    {
        return new User("none", 0);
    }

    @Override
    public String hello(User user)
    {
        return "error";
    }
}
  • 在服务接口中通过@FeignClient注解的fallback属性来指定对应服务降级的实现类
//不区分大小写
@FeignClient(value = "eureka-client", configuration = DisableHystrixConfiguration.class, fallback =
        HelloServiceFallback.class)
public interface HelloService
{
    @RequestMapping(value = "/hello", method = RequestMethod.GET)
    String hello();

    @RequestMapping(value = "/hello1", method = RequestMethod.GET)
    String hello(@RequestParam("name") String name);

    @RequestMapping(value = "/hello2", method = RequestMethod.GET)
    User hello(@RequestHeader("name") String name, @RequestHeader("age") Integer age);

    @RequestMapping(value = "/hello3", method = RequestMethod.POST)
    String hello(@RequestBody User user);
}

请求压缩

Feign支持对请求和响应进行GZIP压缩

feign.compression.request.enabled=true
feign.compression.response.enabled=true

自定义请求压缩规则

#开启请求压缩
feign.compression.request.enable=true
#限制压缩请求类型
feign.compression.request.mime-types=text/xml,application/xml,application/json
#限制大小,只有超过这个大小,才会执行压缩,默认值为2048
feign.compression.request.min-request-size=2048

日志配置

Feign在构建背@FeignClient注解修饰的服务客户端是,会为每一个客户端都创建一个feign.Logger实例

配置feign.Logger

logging.level.<被注解接口的完整路径>,eg:

logging.levle.com.example.web.HelloService=DEBUG

创建全局日志级别的Bean

Feign客户端默认的Logger.level对象定义为NONE级别,该级别不会记录任何Feign调用过程中的信息,故添加上面的配置无法实现对DEBUG日志的输出

//激活erueka中的DiscoveryClient实现
//自动化配置,创建DiscoveryClient接口针对Eureka客户端的EurekaDiscoveryClient实例
@EnableFeignClients
@EnableDiscoveryClient
@SpringBootApplication
public class EurekaServerApplication {

	@Bean
	Logger.Level feignLoggerLevel()
	{
		return Logger.Level.FULL;
	}
	
	public static void main(String[] args) {
		SpringApplication.run(EurekaServerApplication.class, args);
	}
}

指定客户端的配置类实现

@Configuration
public class FullLogConfiguration
{
    @Bean
    Logger.Level feignLoggerLevel()
    {
        return Logger.Level.FULL;
    }
}
  • 在@FeignClient注解中的属性configuration中使用
@FeignClient(name="HELLO-SERVICE", configuration=FullLogConfiguration.class)
public interface HelloService
{
    ...
}

日志级别分裂

  • NONE : 不记录任何信息
  • BASIC :仅记录请求方法、URL以及响应状态码和执行时间
  • HEADERS: 除了记录BASIC级别的信息之外,还会记录请求和响应的头信息
  • FULL:记录所有请求与响应的明细,包括头信息、请求体、元数据等
posted @ 2018-09-11 10:51  [烟火里的尘埃]  阅读(382)  评论(0编辑  收藏  举报