SpringCloud学习6-如何创建一个服务消费者consumer (3)

总之,由于这个冲突,fallback必须制定一个随意不相干的url地址。等后面我学会怎么手动排除RequestMapping的时候就不用了。

接下来,直接调用FeignClient @Api @RestController @RequestMapping("/api/v1/users") public class UserController { private final UserClient userClient; @Autowired public UserController(UserClient userClient) { this.userClient = userClient; } @GetMapping("/feign") public List<UserVo> feign() { return userClient.list(); } @GetMapping("/feign-fallback") public String fallback() { return userClient.fallback(); } }

在provider-api里,我设计userClient.list()返回用户列表,userClient.fallback()随机报500. 这样,启动,访问两个api可以观察到服务降级了。

关于Feign,Hystrix,Ribbon的配置

我目前用到的配置有以下几种,不全,暂时有这些

#eureka客户端ribbon刷新时间 #默认30s ribbon.ServerListRefreshInterval: 5000 # ribbon默认配置 #ribbon.ConnectTimeout=250 #ribbon.ReadTimeout=1000 #ribbon.OkToRetryOnAllOperations=true #ribbon.MaxAutoRetriesNextServer=2 #ribbon.MaxAutoRetries=0 # feign日志配置, 指定某个service的日志级别 #logging.level.com.test.cloud.client.UserClient: info # ribbon全局默认连接和等待时间 ribbon.ConnectTimeout: 1000 ribbon.ReadTimeout: 10000 # ribbon指定service的连接和等待时间,注意service的名称要和在FeignClient注解里标注的内容一致, 要大写 PROVIDER-DEMO.ribbon.ConnectTimeout: 1000 PROVIDER-DEMO.ribbon.ReadTimeout: 1000 # feign全局开启hystrix支持,默认false feign.hystrix.enabled: true # hystrix全局默认超时时间 hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 5000 # hystrix指定request的单独设置超时时间, commandkey的组成为ClientClassName#methodName(ParamTypeClassName..) hystrix.command.UserClient#list().execution.isolation.thread.timeoutInMilliseconds: 5000

需要注意的是,需要理解几个超时的概念。即,需要明白hystrix是干啥的,ribbon又是干啥的,Feign如何把它们集成的。

Feign

OpenFeign可以配置超时,日志,序列化和反序列化,重试等。只要手动声明对应的bean即可。具体配置见

org.springframework.cloud.netflix.feign.FeignClientsConfiguration

值得注意的是,默认不会重试

@Bean @ConditionalOnMissingBean public Retryer feignRetryer() { return Retryer.NEVER_RETRY; }

以及,默认不会采用hystrix

@Configuration @ConditionalOnClass({ HystrixCommand.class, HystrixFeign.class }) protected static class HystrixFeignConfiguration { @Bean @Scope("prototype") @ConditionalOnMissingBean @ConditionalOnProperty(name = "feign.hystrix.enabled", matchIfMissing = false) public Feign.Builder feignHystrixBuilder() { return HystrixFeign.builder(); } }

需要引入hystrix class和配置

feign.hystrix.enabled: true Hystrix

有关具体原理信息,参见官网。个人简单理解,Hystrix为每个依赖的服务创建一个线程池,服务在线程池里执行,hystrix会有一些策略决定什么时候执行超时,还可以获得执行结果的成功率。于是可以指定一些策略,比如超时后中断线程,比如成功率在某一段时间低于阀值后拒绝服务执行。这样就像一个保险丝一样,当不满足我们设置的策略时,直接烧断了,从而起到保护服务资源的作用。当然,实现会更复杂,还有恢复机制。

所以,hystrix会有个超时的配置,决定线程执行时间。

# hystrix全局默认超时时间 hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 5000 # hystrix指定request的单独设置超时时间, commandkey的组成为ClientClassName#methodName(ParamTypeClassName..) hystrix.command.UserClient#list().execution.isolation.thread.timeoutInMilliseconds: 5000

在Feign集成Hystrix的时候,把ClientClassName#methodName(ParamTypeClassName..)设置成Hystrix的CommandKey, CommandKey就是hystrix执行策略的最小单位,比如对应某个http请求,对应这个请求的最长时间即我们设置的超时。

feign.Feign#configKey(java.lang.Class, java.lang.reflect.Method)

public static String configKey(Class targetType, Method method) { StringBuilder builder = new StringBuilder(); builder.append(targetType.getSimpleName()); builder.append('#').append(method.getName()).append('('); for (Type param : method.getGenericParameterTypes()) { param = Types.resolve(targetType, targetType, param); builder.append(Types.getRawType(param).getSimpleName()).append(','); } if (method.getParameterTypes().length > 0) { builder.deleteCharAt(builder.length() - 1); } return builder.append(')').toString(); }

Feign会把host当作groupkey, 这里则是我们的服务名。

当然,还有更多细节的配置,比如线程池,时间窗口大小等。见官网Configuration

Ribbon

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zwwsdw.html