文档章节

spring cloud gateway集成hystrix实战

go4it
 go4it
发布于 2018/06/10 20:41
字数 754
阅读 372
收藏 14

本文主要研究一下spring cloud gateway如何集成hystrix

maven

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

添加spring-cloud-starter-netflix-hystrix依赖,开启hystrix

配置实例

hystrix.command.fallbackcmd.execution.isolation.thread.timeoutInMilliseconds: 5000
spring:
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
      routes:
      - id: employee-service
        uri: lb://employee-service
        predicates:
        - Path=/employee/**
        filters:
        - RewritePath=/employee/(?<path>.*), /$\{path}
        - name: Hystrix
          args:
            name: fallbackcmd
            fallbackUri: forward:/fallback
  • 首先filter里头配置了name为Hystrix的filter,实际是对应HystrixGatewayFilterFactory
  • 然后指定了hystrix command的名称,及fallbackUri,注意fallbackUri要以forward开头
  • 最后通过hystrix.command.fallbackcmd.execution.isolation.thread.timeoutInMilliseconds指定该command的超时时间

fallback实例

@RestController
@RequestMapping("/fallback")
public class FallbackController {

    @RequestMapping("")
    public String fallback(){
        return "error";
    }
}

源码解析

GatewayAutoConfiguration

spring-cloud-gateway-core-2.0.0.RC2-sources.jar!/org/springframework/cloud/gateway/config/GatewayAutoConfiguration.java

@Configuration
@ConditionalOnProperty(name = "spring.cloud.gateway.enabled", matchIfMissing = true)
@EnableConfigurationProperties
@AutoConfigureBefore(HttpHandlerAutoConfiguration.class)
@AutoConfigureAfter({GatewayLoadBalancerClientAutoConfiguration.class, GatewayClassPathWarningAutoConfiguration.class})
@ConditionalOnClass(DispatcherHandler.class)
public class GatewayAutoConfiguration {
    //......
	@Configuration
	@ConditionalOnClass({HystrixObservableCommand.class, RxReactiveStreams.class})
	protected static class HystrixConfiguration {
		@Bean
		public HystrixGatewayFilterFactory hystrixGatewayFilterFactory(DispatcherHandler dispatcherHandler) {
			return new HystrixGatewayFilterFactory(dispatcherHandler);
		}
	}  
    //......
}

引入spring-cloud-starter-netflix-hystrix类库,就有HystrixObservableCommand.class, RxReactiveStreams.class,便开启HystrixConfiguration

HystrixGatewayFilterFactory

spring-cloud-gateway-core-2.0.0.RC2-sources.jar!/org/springframework/cloud/gateway/filter/factory/HystrixGatewayFilterFactory.java

/**
 * Depends on `spring-cloud-starter-netflix-hystrix`, {@see http://cloud.spring.io/spring-cloud-netflix/}
 * @author Spencer Gibb
 */
public class HystrixGatewayFilterFactory extends AbstractGatewayFilterFactory<HystrixGatewayFilterFactory.Config> {

	public static final String FALLBACK_URI = "fallbackUri";

	private final DispatcherHandler dispatcherHandler;

	public HystrixGatewayFilterFactory(DispatcherHandler dispatcherHandler) {
		super(Config.class);
		this.dispatcherHandler = dispatcherHandler;
	}

	@Override
	public List<String> shortcutFieldOrder() {
		return Arrays.asList(NAME_KEY);
	}

	public GatewayFilter apply(String routeId, Consumer<Config> consumer) {
		Config config = newConfig();
		consumer.accept(config);

		if (StringUtils.isEmpty(config.getName()) && !StringUtils.isEmpty(routeId)) {
			config.setName(routeId);
		}

		return apply(config);
	}

	@Override
	public GatewayFilter apply(Config config) {
		//TODO: if no name is supplied, generate one from command id (useful for default filter)
		if (config.setter == null) {
			Assert.notNull(config.name, "A name must be supplied for the Hystrix Command Key");
			HystrixCommandGroupKey groupKey = HystrixCommandGroupKey.Factory.asKey(getClass().getSimpleName());
			HystrixCommandKey commandKey = HystrixCommandKey.Factory.asKey(config.name);

			config.setter = Setter.withGroupKey(groupKey)
					.andCommandKey(commandKey);
		}

		return (exchange, chain) -> {
			RouteHystrixCommand command = new RouteHystrixCommand(config.setter, config.fallbackUri, exchange, chain);

			return Mono.create(s -> {
				Subscription sub = command.toObservable().subscribe(s::success, s::error, s::success);
				s.onCancel(sub::unsubscribe);
			}).onErrorResume((Function<Throwable, Mono<Void>>) throwable -> {
				if (throwable instanceof HystrixRuntimeException) {
					HystrixRuntimeException e = (HystrixRuntimeException) throwable;
					if (e.getFailureType() == TIMEOUT) { //TODO: optionally set status
						setResponseStatus(exchange, HttpStatus.GATEWAY_TIMEOUT);
						return exchange.getResponse().setComplete();
					}
				}
				return Mono.error(throwable);
			}).then();
		};
	}
    //......
}

这里创建了RouteHystrixCommand,将其转换为Mono,然后在onErrorResume的时候判断如果HystrixRuntimeException的failureType是FailureType.TIMEOUT类型的话,则返回GATEWAY_TIMEOUT(504, "Gateway Timeout")状态码。

RouteHystrixCommand

	//TODO: replace with HystrixMonoCommand that we write
	private class RouteHystrixCommand extends HystrixObservableCommand<Void> {

		private final URI fallbackUri;
		private final ServerWebExchange exchange;
		private final GatewayFilterChain chain;

		RouteHystrixCommand(Setter setter, URI fallbackUri, ServerWebExchange exchange, GatewayFilterChain chain) {
			super(setter);
			this.fallbackUri = fallbackUri;
			this.exchange = exchange;
			this.chain = chain;
		}

		@Override
		protected Observable<Void> construct() {
			return RxReactiveStreams.toObservable(this.chain.filter(exchange));
		}

		@Override
		protected Observable<Void> resumeWithFallback() {
			if (this.fallbackUri == null) {
				return super.resumeWithFallback();
			}

			//TODO: copied from RouteToRequestUrlFilter
			URI uri = exchange.getRequest().getURI();
			//TODO: assume always?
			boolean encoded = containsEncodedParts(uri);
			URI requestUrl = UriComponentsBuilder.fromUri(uri)
					.host(null)
					.port(null)
					.uri(this.fallbackUri)
					.build(encoded)
					.toUri();
			exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, requestUrl);

			ServerHttpRequest request = this.exchange.getRequest().mutate().uri(requestUrl).build();
			ServerWebExchange mutated = exchange.mutate().request(request).build();
			return RxReactiveStreams.toObservable(HystrixGatewayFilterFactory.this.dispatcherHandler.handle(mutated));
		}
	}
  • 这里重写了construct方法,RxReactiveStreams.toObservable(this.chain.filter(exchange)),将reactor的Mono转换为rxjava的Observable
  • 这里重写了resumeWithFallback方法,针对有fallbackUri的情况,重新路由到fallbackUri的地址

Config

	public static class Config {
		private String name;
		private Setter setter;
		private URI fallbackUri;

		public String getName() {
			return name;
		}

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

		public Config setFallbackUri(String fallbackUri) {
			if (fallbackUri != null) {
				setFallbackUri(URI.create(fallbackUri));
			}
			return this;
		}

		public URI getFallbackUri() {
			return fallbackUri;
		}

		public void setFallbackUri(URI fallbackUri) {
			if (fallbackUri != null && !"forward".equals(fallbackUri.getScheme())) {
				throw new IllegalArgumentException("Hystrix Filter currently only supports 'forward' URIs, found " + fallbackUri);
			}
			this.fallbackUri = fallbackUri;
		}

		public Config setSetter(Setter setter) {
			this.setter = setter;
			return this;
		}
	}

可以看到Config校验了fallbackUri,如果不为null,则必须以forward开头

小结

spring cloud gateway集成hystrix,分为如下几步:

  • 添加spring-cloud-starter-netflix-hystrix依赖
  • 在对应route的filter添加name为Hystrix的filter,同时指定hystrix command的名称,及其fallbackUri(可选)
  • 指定该hystrix command的超时时间等。

doc

© 著作权归作者所有

共有 人打赏支持
go4it
粉丝 77
博文 885
码字总数 793059
作品 0
深圳
私信 提问
微服务网关Spring Cloud Gateway的应用实战

今天和大家聊一下微服务网关 Spring Cloud Gateway。Spring Cloud Gateway 是 Spring Cloud 的一个全新项目,该项目是基于Spring 5.0、Spring Boot 2.0 和Project Reactor 等组件技术,Sprin...

aoho
02/12
0
0
Spring Cloud Gateway初体验

版权声明:本文为博主原创文章,欢迎转载,转载请注明作者、原文超链接 ,博主地址:http://blog.csdn.net/forezp。 https://blog.csdn.net/forezp/article/details/83792388 转载请标明出处...

方志朋
2018/11/06
0
0
周立/spring-cloud-study

项目简介 本项目是《使用Spring Cloud与Docker实战微服务》: http://git.oschina.net/itmuch/spring-cloud-book http://www.github.com/eacdy/spring-cloud-book Spring Cloud章节的配套代码......

周立
2016/09/19
0
0
Hystrix 停止开发。。。Spring Cloud 何去何从?

栈长得到消息,Hystrix 停止开发了。。。 大家如果有对 Hystrix 不清楚的,请看下这篇文章:分布式服务防雪崩熔断器,Hystrix理论+实战。 来看下 Hystrix 停止开发官宣: https://github.com...

Java技术栈
2018/11/30
0
0
微服务网关Zuul迁移到Spring Cloud Gateway

背景 在之前的文章中,我们介绍过微服务网关Spring Cloud Netflix Zuul,前段时间有两篇文章专门介绍了Spring Cloud的全新项目Spring Cloud Gateway,以及其中的过滤器工厂。本文将会介绍将微...

aoho
2018/09/24
0
0

没有更多内容

加载失败,请刷新页面

加载更多

富兰克林的人生信条

春节假期期间读了富兰克林自传,这位饱经风霜的老人出身贫寒,只读过两年书,但是通过刻苦自学和不懈奋斗还是取得了令人难以置信的成就,他的一生可以作为我们普通人的励志典范。 富兰克林 ...

春哥大魔王的博客
今天
1
0
不用中间变量交换 a ,b(三种方法)

1、加减法:该方法可以交换整型和浮点型数值的变量,但在处理浮点型的时候有可能出现精度的损失。 a = a + b; b = a - b; a = a - b; 2、异或法:可以完成对整型变量的交换,对于浮点型变量它...

robslove
今天
5
0
一文了解 OutOfMemory 及解决方案

1. Java 堆空间 发生频率 5颗星 造成原因 无法在 Java 堆中分配对象 吞吐量增加 应用程序无意中保存了对象引用,对象无法被 GC 回收 应用程序过度使用 finalizer。finalizer 对象不能被 GC 立...

java菜分享
今天
5
0
高效遍历Java容器

通过本文,你可以更深入的学习 Java 语言中 forEach 语法的知识,以及它和 C 语言形式的 for 循环、 Steam API 的对比。 简介 Java 程序员经常使用容器,比如 ArrayList 和 HashSet。Java 8 ...

微笑向暖wx
今天
4
0
SpringBoot整合Swagger测试api构建

什么是Swagger? Swagger是什么:THE WORLD’S MOST POPULAR API TOOLING 根据官网的介绍: Swagger Inspector:测试API和生成OpenAPI的开发工具。Swagger Inspector的建立是为了解决开发者的...

编程SHA
今天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部