spring-flux timeout源码分析

spring-flux timeout源码分析

  • 正常和超时数据都会将数据放入ScheduledThreadPoolExecutor的队列中
  • 正常结束的会从ScheduledThreadPoolExecutor队列中remove
  • 超时数据会在ScheduledThreadPoolExecutor队列中积压等待定时器消费

mono flux timeout实现

public final Mono<T> timeout(Duration timeout) {
		return timeout(timeout, Schedulers.parallel());
}

Schedulers.parallel()

public static Scheduler parallel() {
		return cache(CACHED_PARALLEL, PARALLEL, PARALLEL_SUPPLIER);
	}

PARALLEL_SUPPLIER

static final Supplier<Scheduler> PARALLEL_SUPPLIER =
			() -> newParallel(PARALLEL, DEFAULT_POOL_SIZE, true);

newParallel实现

  • ParallelScheduler类
ParallelScheduler(int n, ThreadFactory factory) {
        if (n <= 0) {
            throw new IllegalArgumentException("n > 0 required but it was " + n);
        }
        this.n = n;
        this.factory = factory;
        //初始化定时器(ScheduledThreadPoolExecutor),n默认无cpu核心数
        init(n);
    }

void init(int n) {
        ScheduledExecutorService[] a = new ScheduledExecutorService[n];
        for (int i = 0; i < n; i++) {
            a[i] = Schedulers.decorateExecutorService(Schedulers.PARALLEL, this);
        }
        EXECUTORS.lazySet(this, a);
    }
    //获取定时器ScheduledThreadPoolExecutor
    ScheduledExecutorService pick() {
        ScheduledExecutorService[] a = executors;
        if (a != SHUTDOWN) {
            // ignoring the race condition here, its already random who gets which executor
            int idx = roundRobin;
            if (idx == n) {
                idx = 0;
                roundRobin = 1;
            } else {
                roundRobin = idx + 1;
            }
            return a[idx];
        }
        return TERMINATED;
    }

timeout

public final Flux<T> timeout(Duration timeout,
			@Nullable Publisher<? extends T> fallback,
			Scheduler timer) {
		final Mono<Long> _timer = Mono.delay(timeout, timer).onErrorReturn(0L);
		final Function<T, Publisher<Long>> rest = o -> _timer;

		if(fallback == null) {
			return timeout(_timer, rest, timeout.toMillis() + "ms");
		}
		return timeout(_timer, rest, fallback);
	}
//生成FluxTimeout类
public final <U, V> Flux<T> timeout(Publisher<U> firstTimeout,
			Function<? super T, ? extends Publisher<V>> nextTimeoutFactory, Publisher<? extends T>
			fallback) {
		return onAssembly(new FluxTimeout<>(this, firstTimeout, nextTimeoutFactory,
				fallback));
	}
  • FluxTimeout subscribe方法
public void subscribe(CoreSubscriber<? super T> actual) {
		CoreSubscriber<T> serial = Operators.serialize(actual);

		TimeoutMainSubscriber<T, V> main =
				new TimeoutMainSubscriber<>(serial, itemTimeout, other, timeoutDescription);

		serial.onSubscribe(main);

		TimeoutTimeoutSubscriber ts = new TimeoutTimeoutSubscriber(main, 0L);

		main.setTimeout(ts);
		//会执行ParallelScheduler类的directSchedule方法
		firstTimeout.subscribe(ts);

		source.subscribe(main);
	}
//exec定时器是通过pick方法获取
static Disposable directSchedule(ScheduledExecutorService exec,
			Runnable task,
			long delay,
			TimeUnit unit) {
		SchedulerTask sr = new SchedulerTask(task);
		Future<?> f;
		//0延时
		if (delay <= 0L) {
			f = exec.submit((Callable<?>) sr);
		}
		//delay时间定时执行
		else {
			//将任务放入队列,1个线程定时去消费队列
			f = exec.schedule((Callable<?>) sr, delay, unit);
		}
		sr.setFuture(f);
		return sr;
	}
  • 正常结束
  • 会调用ScheduledThreadPoolExecutor 的cancel方法从队列中移除任务,也可以debug查看调用栈
 public boolean cancel(boolean mayInterruptIfRunning) {
            boolean cancelled = super.cancel(mayInterruptIfRunning);
            if (cancelled && removeOnCancel && heapIndex >= 0)
                remove(this);
            return cancelled;
        }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Cloud Gateway 是一个基于 Spring Framework 5、Spring Boot 2 和 Project Reactor 的 API 网关服务。它提供了一种简单而强大的方法来路由和过滤请求,并将它们转发到底层的微服务。对于理解 Spring Cloud Gateway 的工作原理和深入研究其源代码是非常有用的。 首先,通过源码可以发现 Spring Cloud Gateway 主要由三个核心模块组成:路由模块、过滤器模块和事件模块。路由模块负责根据定义的路由规则将请求转发到特定的目标地址。过滤器模块负责在请求的不同阶段执行一系列的过滤器来处理请求。事件模块则用于处理与路由和过滤器相关的异步事件。 源码中的路由模块使用了 Reactive Streams API 中的 Flux 和 Mono 类来处理异步操作。它利用 RouterFunction 和 HandlerFunction 来定义路由和处理请求的方法,并通过 RoutePredicateFactory 来解析和匹配路由规则。在路由模块中,使用了 Netty 库来实现底层的网络通信和请求转发。 通过源码分析过滤器模块,可以发现 Spring Cloud Gateway 的过滤器分为全局过滤器和自定义过滤器两种类型。全局过滤器在请求的全局范围内应用,并且可以用于添加一些全局的处理逻辑。自定义过滤器则允许开发者根据需要添加自定义的过滤逻辑。过滤器的执行顺序可以通过 Order 注解来控制,以满足不同过滤器的执行顺序需求。 事件模块在源码中使用了 Reactor 提供的 EventProcessor 来处理与路由和过滤器相关的事件。它使用了 Reactor 的 FluxSink 和 MonoSink 来创建异步事件源,并通过事件处理器将事件发送给注册的监听器。通过查看事件模块的源码,可以更加深入地了解 Spring Cloud Gateway 是如何处理与路由和过滤器相关的事件的。 总结而言,通过源码分析 Spring Cloud Gateway,我们可以更好地了解其内部的工作原理和实现细节。这对于开发者来说是非常有用的,因为它可以帮助我们更好地使用和扩展 Spring Cloud Gateway 来满足不同的场景需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值