SpringCloud开发学习总结(七)—— 声明式服务调用Feign(三)
Feign中的Ribbon配置
由于Spring Cloud Feign的客户端负载均衡是通过Spring Cloud Ribbon实现的,所以我们可以直接通过配置Ribbon客户端的方式来自定义各个服务客户端调用多个参数。
- 全局配置
全局配置的方法非常简单,直接使用ribbon.<key>=<value>的方式来设置ribbon的各项默认参数。例如,修改默认的客户端调用超时时间:
#请求连接的超时时间
ribbon.ConnectTimeout=500
#请求处理的超时时间
ribbon.ReadTimeout=2000
- 指定服务配置
大多数情况,我们对于服务的超时时间可能会不同的服务特性做一些调整,针对各个服务客户端进行个性化配置的方式与使用Spring Cloud Ribbon时的配置方式是一样的,都采用<client>.ribbon.key=value 的格式进行设置,其中<client>指的是 @FeignClient(value="HELLO-SERVICE")中的value值,在使用@FeignClient(value="HELLO-SERVICE")来创建Feign客户端的时候,同时也创建了一个名为HELLO-SERVICE的Ribbon客户端,具体配置如下:
HELLO-SERVICE.ribbon.ConnectTimeout=500
HELLO-SERVICE.ribbon.ReadTimeout=2000
HELLO-SERVICE.ribbon.OkToRetryOnAllOperations=true
#最多重试服务器的个数
HELLO-SERVICE.ribbon.MaxAutoRetriesNextServer=2
#每台服务器最多重试次数,首次调用除外
HELLO-SERVICE.ribbon.MaxAutoRetries=1
重试机制
在Spring Cloud Feign中默认实现了请求的重试机制,而上面标红的就是对HELLO-SERVICE客户端的配置内容就是对于请求超时以及重试机制的配置,我们可以通过修改之前的示例做一些验证。在hello-service应用的/hello接口实现中,增加一个随机延迟,比如:
package com.server.provide.web; import java.util.List;
import java.util.Random; import org.apache.catalina.servlet4preview.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.serviceregistry.Registration;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; @RestController
public class HelloController {
@Autowired
private Registration① registration; // 服务注册
@Autowired
private DiscoveryClient discoveryClient; // 服务发现客户端
private static final Logger log = LoggerFactory.getLogger(HelloController.class);
@RequestMapping("/hello")
public String hello(HttpServletRequest request) throws Exception {
//测试超时
int sleepTime = new Random().nextInt(3000);
log.info("sleepTime"+sleepTime);
Thread.sleep(sleepTime);
log.info(request.getRemoteAddr()+","+request.getLocalName()+","+registration.getServiceId()+","+serviceInstance().getServiceId());
return "hello I am provider";
} @RequestMapping("/hello1")
public String hello(@RequestParam String name) {
return "Hello "+name;
} @RequestMapping("/hello2")
public User hello(@RequestHeader String name,@RequestHeader Integer age) {
return new User(name,age);
} @RequestMapping("/hello3")
public String hello(@RequestBody User user) {
return "Hello "+user.getName()+","+user.getAge();
} /**
* 获取当前服务的服务实例
*
* @return ServiceInstance
*/
public ServiceInstance serviceInstance() {
List<ServiceInstance> list = discoveryClient.getInstances(registration.getServiceId());
if (list != null && list.size() > 0) {
return list.get(0);
}
return null;
} }
在feign-consumer应用中增加上文中提到的重试配置参数。其中HELLO-SERVICE.ribbon.MaxAutoRetries=1代表重试机制在失败一次后,先尝试访问第一次失败的实例一次,再次失败后才更换服务器访问,而更换服务访问的次数通过HELLO-SERVICE.ribbon.MaxAutoRetriesNextServer=2控制,代表会尝试更换两次服务进行重试。
最后,启动这些应用,并尝试访问几次http://localhost:8092/feign-consumer接口。当请求发生超时的时候,我们在服务提供者的控制台中会获得如下内容输出(由于sleepTime的随机性,并不一定每次相同):
Feign中的Hystrix配置
在Spring Cloud Feign中,除了引入了用于客户端负载均衡的Spring Cloud Ribbon之外,还引入了服务保护与容错的工具 Hystrix。本节中,将详细介绍如何在使用Spring Cloud Feign时配置Hystrix属性以及如何实现服务降级。
全局配置
对于Hystrix的全局配置同Spring Cloud Ribbon的全局配置一样,直接使用它的默认配置前缀hystrix.command.default就可以进行设置,比如设置全局的超时时间:
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=5000
另外,在对Hystrix进行配置之前,我们需要确认feign.hystrix.enabled参数没有被设置为false,否则该参数设置会关闭Feign客户端的Hystrix支持。而对于我们之前测试重拾机制时,对于Hystrix的超时时间控制除了可以使用上面的配置来增加熔断超时时间,也可以通过feign.hystrix.enabled=false来关闭Hystrix功能,或者使用hystrix,command.default.execution.timeout.enable=false来关闭熔断功能。
禁用Hystrix
上面我们提到了,在Spring Cloud Fegn中,可以通过feign.hystrix.enabled=false来关闭Hystrix功能。如果不想全局的关闭Hystrix支持,而只想针对某个服务客户端关闭Hystrix支持时,需要通过使用@Scope("prototype")注解为指定的客户端配置Feign.Builder实例,详细实现步骤如下:
构建一个关闭Hystrix的配置类
@Configuration
public class DisableHystrixConfiguration { @Bean
@Scope("prototype")
public Feign.Builder feignBuilder(){ return Feign.builder();
} }
在HelloService的@FeignClient注解中,通过configuration参数引入上面实现的配置
@FeignClient(name="feign-provide",configuration=DisableHystrixConfiguration.class)
public interface HelloService { @RequestMapping(value="/hello")
String hello();
@RequestMapping(value="/hello1",method=RequestMethod.GET)
String hello(@RequestParam("name") String name);
@RequestMapping(value="/hello2",method=RequestMethod.GET)
String hello(@RequestHeader("name") String name,@RequestHeader("age") Integer age);
@RequestMapping(value="/hello3",method=RequestMethod.POST)
String hello(@RequestBody User user); }
指定命令配置
配制方法也跟传统的Hystrix命令的参数配置相似,采用hystrix.command.<commandKey>作为前缀。而<commandKey>默认情况下会采用Feign客户端中的方法名②作为标识,所以,针对上一节介绍的尝试机制中对/hello接口的熔断超时时间的配置可以通过其方法名作为<commandKey>来进行配置:
hystrix.command.hello.execution.isolation.thread.timeoutInMilliseconds=5000
服务降级配置
Hystrix提供的服务降级是服务容错的重要功能,由于Spring Cloud Feign在定义服务客户端的时候与Spring Cloud Ribbon有很大差别,HystrixCommand定义被封装了起来,我们无法像之前介绍Spring Cloud Hystrix时,通过@HystrixCommand注解的fallback参数那样来制定具体的服务降级处理方法。但是,Spring Cloud Feign提供了另外一种简单的定义方式。
服务降级逻辑的实现只需要为Feign客户端的定义接口编写一个具体的接口实现类。比如为HelloService接口实现一个服务降级类HelloServiceFallback,其中每个重写方法的实现逻辑都可以用来定义相应的服务降级逻辑:
@Component
public class HelloServiceFallback implements HelloService { @Override
public String hello(String name) {
// TODO Auto-generated method stub
return "error";
} @Override
public String hello(User user) {
// TODO Auto-generated method stub
return "error";
} @Override
public String hello() {
// TODO Auto-generated method stub
return "error";
} @Override
public String hello(String name, Integer age) {
// TODO Auto-generated method stub
return "error";
} }
在服务接口HelloService中,通过@FeignClient注解的fallback属性③来制定对应的服务降级实现类。
@FeignClient(name="feign-provide",fallback=HelloServiceFallback.class) //configuration=DisableHystrixConfiguration.class,
public interface HelloService { @RequestMapping(value="/hello")
String hello();
@RequestMapping(value="/hello1",method=RequestMethod.GET)
String hello(@RequestParam("name") String name);
@RequestMapping(value="/hello2",method=RequestMethod.GET)
String hello(@RequestHeader("name") String name,@RequestHeader("age") Integer age);
@RequestMapping(value="/hello3",method=RequestMethod.POST)
String hello(@RequestBody User user); }
- 测试验证
我们启动服务注册中心和feign-consumer,但不启动feign-provide服务,发送GET请求到http://localhost:8092/feign-consumer2,由于没有启动feign-provide服务,会直接触发服务降级,得到下面输出:
注释一:Spring Cloud中提供的DiscoveryClient类,虽然有
ServiceInstance getLocalServiceInstance();方法,但是被标记为@Deprecated. 更为严重的是, Spring Cloud的Finchley版本中,getLocalServiceInstance方法从DiscoveryClient移除了,新版本中获取服务自身的ServiceInstance信息用registration.getServiceId()。
注释二:在使用指定命令配置的时候,需要注意,由于方法名很有可能重复,这个时候相同方法名的Hystrix配置会共用,所以在进行方法定义与配置的时候需要做好一定的规则。当然,也可以重写Feign.Builder的实现,并在应用主类中创建它的实例来覆盖自动化配置的HystrixFeign.Builder实现。
注释三:Feign对Hystrix的支持默认是关闭的,如果想开启对Hystrix的支持需要配置 feign.hystrix.enabled=true,并且需要把之前关闭Hystrix的配置类注释掉,方可开启服务降级功能,否则会报com.netflix.client.ClientException: Load balancer does not have available server for client:XXX。
SpringCloud开发学习总结(七)—— 声明式服务调用Feign(三)的更多相关文章
- SpringCloud 源码系列(6)—— 声明式服务调用 Feign
SpringCloud 源码系列(1)-- 注册中心 Eureka(上) SpringCloud 源码系列(2)-- 注册中心 Eureka(中) SpringCloud 源码系列(3)-- 注册中心 ...
- SpringCloud开发学习总结(七)—— 声明式服务调用Feign(一)
在实践的过程中,我们会发现在微服务架构中实现客户端负载均衡的服务调用技术Spring Cloud Ribbon<SpringCloud开发学习总结(四)—— 客户端负载均衡Ribbon> ...
- SpringCloud之声明式服务调用 Feign(三)
一 Feign简介 Feign是一种声明式.模板化的HTTP客户端,也是netflix公司组件.使用feign可以在远程调用另外服务的API,如果调用本地API一样.我们知道,阿里巴巴的doubbo采 ...
- 004声明式服务调用Feign & 断路器Hystrix
1.POM配置 和普通Spring Boot工程相比,添加了Eureka Client.Feign.Hystrix依赖和Spring Cloud依赖管理 <dependencies> &l ...
- Spring Cloud第七篇 | 声明式服务调用Feign
本文是Spring Cloud专栏的第七篇文章,了解前六篇文章内容有助于更好的理解本文: Spring Cloud第一篇 | Spring Cloud前言及其常用组件介绍概览 Spring Cloud ...
- 【Dalston】【第三章】声明式服务调用(Feign)
当我们通过RestTemplate调用其它服务的API时,所需要的参数须在请求的URL中进行拼接,如果参数少的话或许我们还可以忍受,一旦有多个参数的话,这时拼接请求字符串就会效率低下,并且显得好傻.那 ...
- 声明式服务调用Feign
什么是 Feign Feign 是种声明式.模板化的 HTTP 客户端(仅在 consumer 中使用). 什么是声明式,有什么作用,解决什么问题? 声明式调用就像调用本地方法一样调用远程方法;无 ...
- Spring Cloud 声明式服务调用 Feign
一.简介 在上一篇中,我们介绍注册中心Eureka,但是没有服务注册和服务调用,服务注册和服务调用本来应该在上一章就应该给出例子的,但是我觉得还是和Feign一起讲比较好,因为在实际项目中,都是使用声 ...
- Spring Cloud Feign 1(声明式服务调用Feign 简介)
Spring Cloud Feign基于Netflix Feign 同时整合了Spring Cloud Ribbon和Spring Cloud Hytrix,除了提供两者的强大功能外,它还提供了一种声 ...
- SpringCloud开发学习总结(七)—— 声明式服务调用Feign(二)
参数绑定 在上一章的示例中,我们使用Spring Cloud Feign实现的是一个不带参数的REST服务绑定.然而现实系统中的各种业务接口要比它复杂得多,我们有时会在HTTP的各个位置传入各种不同类 ...
随机推荐
- hibernate 的POJO状态
瞬时状态 刚new出来的对象,还没和session发生联系,或者delete之后的对象 持久化状态 用save,get等方法保存或获取到session中的对象,和数据保持一一对应的关系 脱管状态 对象 ...
- Remove FileUtil#copyMerge
[HADOOP-12967] Remove FileUtil#copyMerge - ASF JIRA https://issues.apache.org/jira/browse/HADOOP-129 ...
- 1250太小了 mysql 并发
SHOW VARIABLES LIKE '%connection%'; character_set_connection utf8mb4collation_connection utf8mb4_gen ...
- 关于div li 等标签之间自带间距
可以用float来清除标签之间的间距. ps :ul使用font-size:0 唯一的缺点就是要再次设置LI的font-size
- .Net线程池ThreadPool导致内存高的问题分析
最近写了一个WinFrom程序.此程序侦听TCP端口,接受消息处理,然后再把处理后的消息,利用线程池通过WebService发送出去(即一进一出). 在程序编写完成后,进行压力测试.用Fiddler提 ...
- 序列流、对象操作流、打印流、标准输入输出流、随机访问流、数据输入输出流、Properties(二十二)
1.序列流 * 1.什么是序列流 * 序列流可以把多个字节输入流整合成一个, 从序列流中读取数据时, 将从被整合的第一个流开始读, 读完一个之后继续读第二个, 以此类推.* 2.使用方式 * 整合两个 ...
- set built-in function
集合类型 集合对象是一组无序排列的可哈希的值,集合可以作为字典的键.因为集合是无序的,不可以为集合创建索引或执行切片操作,也没有键可以用来获取元素的值. 集合有两种不同的类型,可变集合和不可变集合.可 ...
- Oracle:通过oracle sql developer工具导入excel数据
我使用的是oracle sql developer3.1版本,以前developer2.×老版本的excel导入功能有问题. excel文件内容如下: 第一步:找到要导入的表,右键-->导入数据 ...
- hdu-5719 Arrange(组合数学)
题目链接: Arrange Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others) ...
- BZOJ1453: [WC2005]Dface双面棋盘
离线LCT维护MST,和3082的方法一样.然而比较码农,适合颓废的时候写. PS:线段树分治要好写得多,LCT比较自娱自乐. #include<bits/stdc++.h> using ...