springcloud-04-feign

1、Feign简介 

Feign is a declarative web service client. It makes writing web service clients easier. To use Feign create an interface and annotate it. It has pluggable annotation support including Feign annotations and JAX-RS annotations. Feign also supports pluggable encoders and decoders. Spring Cloud adds support for Spring MVC annotations and for using the sameHttpMessageConverters used by default in Spring Web. Spring Cloud integrates Ribbon and Eureka to provide a load balanced http client when using Feign.

这是官网API中的介绍,主要是说Feign是一个声明式的web 服务客户端;它支持可插拔的注解,包含Feign注解和JAX-RS注解;并且支持可插拔的编码、解码;Spring Cloud增加了对Spring MVC注解的集成;Feign集成了Ribbon和Eureka来提供对http客户端的负载均衡。

说到Feign的功能是负载均衡,那必须和前一章的Ribbon进行比较一下:

        1、Fegin继承了Ribbon利用Ribbon维护了服务的服务列表信息,并且通过轮询实现了客户端的负载均衡。而Ribbon不同的是,通过fegin只需要定义服务绑定接口且以声明式的方法,优雅而简单的实现了服务调用。
        2、他们两个的共同点就是都是客户端的负载均衡。
        3、Ribbon是Ribbon+RestTemplate+服务名称时,利用了RestTemplate对http的封装进行负载均衡访问(这种访问需要知道服务名称,不是一种面向接口编程,也就诞生了Feign)。而 Fegin在此基础上做了异步封装,由他来帮助我们定义和实现依赖借口的定义(只需要添加一些注解就可以了)。
       4、Ribbon 是一个基于 HTTP 和 TCP 客户端的负载均衡器,声明式rest客户端feign。其实通过Feign封装了HTTP调用服务方法,使得客户端像调用本地方法那样直接调用方法,类似Dubbo中暴露远程服务的方式,区别在于Dubbo是基于私有二进制协议,而Feign本质上还是个HTTP客户端。

2、下面是用实例来说明:

pom:

<!-- fegin相关 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>

代码:

//@FeignClient(value="MICROSERVICECLOUD1-DEPT") 值开启这个就表示只有Feign来用,负载均衡服务名称为“MICROSERVICECLOUD1-DEPT”,
@FeignClient(value="MICROSERVICECLOUD1-DEPT",fallbackFactory=DeptClientServiceFallbackFactory.class)下面这个注解和Feign与Hystrix结合在一起使用的,也需要在yml里面开启(feign.hystrix. enabled: true)
public interface DeptClientService {

@RequestMapping(value="/dept/add",method=RequestMethod.POST)
public boolean add(@RequestBody Dept dept);


@RequestMapping(value="/dept/get/{id}",method=RequestMethod.GET)
public Dept get(@PathVariable("id") Long id);


@RequestMapping(value="/dept/list",method=RequestMethod.GET)
public List<Dept> list();
}
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients(basePackages="com.jrj.springcloud")
@ComponentScan(basePackages="com.jrj.springcloud")
public class DeptConsumerFegin_App {

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


}
@Autowired
private DeptClientService service;


@RequestMapping(value = "/consumer/dept/add", method = RequestMethod.POST)
public boolean add(@RequestBody Dept dept) {
return service.add(dept);
}
/**

 * 千万不要忘记在类上面新增@Component注解,大坑!!!

    这个是那个Hystrix有关系

 */
@Component
public class DeptClientServiceFallbackFactory implements FallbackFactory<DeptClientService>{
@Override
public DeptClientService create(Throwable cause) {
return new DeptClientService(){
@Override
public boolean add(Dept dept) {
return false;
}
@Override
public Dept get(Long id) {
return new Dept().setDeptno(id).setDname("服务正在降级处理").setDb_source("no this database mysql");
}
@Override
public List<Dept> list() {
return null;
}
};
}
}

需要注意的是:

fegin的两个坑是不支持:
                                     1、不支持@GetMapping这个注解
2、还有就是@PathVariable("id")Integer id 必须这样写,不能写成 @PathVariable Integer id
                     3、如果请求参数是复杂对象,即使指定了是get方法,fegin依然会以post方法进行发送。

在访问这个项目的时候可能会出现,timeout超时异常:null
原因是fegin集成了hystrix,他默认的时间是1秒钟,
我们可以通过设置这个就可以解决这个问题:把时间设置长一点
hystrix.command.default.execution.isolation.timeoutInMillseconds:
或者:
hystrix.command.default.execution.timeout.enabled:false
或者:
fegin.hystrix.enabled:false fegin禁用hytrix

3、Feign的一写其他操作

3.1、覆盖Feign默认值
3.2、手动创建Feign客户端
3.3、Feign Hystrix支持

如果Hystrix在类路径上,feign.hystrix.enabled=true,Feign将用断路器包装所有方法。还可以返回com.netflix.hystrix.HystrixCommand这样就可以使用无效模式(调用.toObservable().observe()或异步使用(调用.queue()))。

要在每个客户端基础上禁用Hystrix支持创建一个带有“原型”范围的香草Feign.Builder,例如:

@Configuration
public class FooConfiguration {
    @Bean
	@Scope("prototype")
	public Feign.Builder feignBuilder() {
		return Feign.builder();
	}
}
警告
在Spring Cloud达尔斯顿发布之前,如果Hystrix在类路径Feign中默认将所有方法包装在断路器中。这种默认行为在Spring Cloud达尔斯顿改变了赞成选择加入的方式。

3.4、Feign Hystrix回退

Hystrix支持回退的概念:当电路断开或出现错误时执行的默认代码路径。要为给定的@FeignClient启用回退,请将fallback属性设置为实现回退的类名。

@FeignClient(name = "hello", fallback = HystrixClientFallback.class)
protected interface HystrixClient {
    @RequestMapping(method = RequestMethod.GET, value = "/hello")
    Hello iFailSometimes();
}

static class HystrixClientFallback implements HystrixClient {
    @Override
    public Hello iFailSometimes() {
        return new Hello("fallback");
    }
}

如果需要访问导致回退触发的原因,可以使用@FeignClient内的fallbackFactory属性。

@FeignClient(name = "hello", fallbackFactory = HystrixClientFallbackFactory.class)
protected interface HystrixClient {
	@RequestMapping(method = RequestMethod.GET, value = "/hello")
	Hello iFailSometimes();
}

@Component
static class HystrixClientFallbackFactory implements FallbackFactory<HystrixClient> {
	@Override
	public HystrixClient create(Throwable cause) {
		return new HystrixClientWithFallBackFactory() {
			@Override
			public Hello iFailSometimes() {
				return new Hello("fallback; reason was: " + cause.getMessage());
			}
		};
	}
}
警告
在Feign中执行回退以及Hystrix回退的工作方式存在局限性。当前返回com.netflix.hystrix.HystrixCommandrx.Observable的方法目前不支持回退。

3.4.1Feign和@Primary

当使用Feign与Hystrix回退时,在同一类型的ApplicationContext中有多个bean。这将导致@Autowired不起作用,因为没有一个bean,或者标记为主。要解决这个问题,Spring Cloud Netflix将所有Feign实例标记为@Primary,所以Spring Framework将知道要注入哪个bean。在某些情况下,这可能是不可取的。要关闭此行为,将@FeignClientprimary属性设置为false。

@FeignClient(name = "hello", primary = false)
public interface HelloClient {
	// methods here
}

3.5、Feign继承支持

Feign通过单继承接口支持样板apis。这样就可以将常用操作分成方便的基本界面。

UserService.java
public interface UserService {

    @RequestMapping(method = RequestMethod.GET, value ="/users/{id}")
    User getUser(@PathVariable("id") long id);
}
UserResource.java
@RestController
public class UserResource implements UserService {

}
UserClient.java
package project.user;

@FeignClient("users")
public interface UserClient extends UserService {

}
注意
通常不建议在服务器和客户端之间共享接口。它引入了紧耦合,并且实际上并不适用于当前形式的Spring MVC(方法参数映射不被继承)。

3.6、Feign请求/响应压缩

您可以考虑为Feign请求启用请求或响应GZIP压缩。您可以通过启用其中一个属性来执行此操作:

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

Feign请求压缩为您提供与您为Web服务器设置的设置相似的设置:

feign.compression.request.enabled=true
feign.compression.request.mime-types=text/xml,application/xml,application/json
feign.compression.request.min-request-size=2048

这些属性可以让您对压缩介质类型和最小请求阈值长度有选择性。

3.7、Feign日志记录

为每个创建的Feign客户端创建一个记录器。默认情况下,记录器的名称是用于创建Feign客户端的接口的完整类名。Feign日志记录仅响应DEBUG级别。

application.yml
logging.level.project.user.UserClient: DEBUG

您可以为每个客户端配置的Logger.Level对象告诉Feign记录多少。选择是:

  • NONE,无记录(DEFAULT)。

  • BASIC,只记录请求方法和URL以及响应状态代码和执行时间。

  • HEADERS,记录基本信息以及请求和响应标头。

  • FULL,记录请求和响应的头文件,正文和元数据。


参考文章有如下:

https://blog.csdn.net/jeson0725/article/details/70226292

http://www.ccblog.cn/97.htm







猜你喜欢

转载自blog.csdn.net/wojiao228925661/article/details/80865735