Quarkus中Reactive Redis如何列出所有键值对?线程阻塞问题求助
解决Reactive Redis多键值获取与流合并问题
问题根源
你的代码里有两个核心问题:
- 使用了
.await().indefinitely()这种阻塞调用,而当前运行在Vert.x的EventLoop线程上,这个线程是反应式框架的核心事件循环,绝对不能被阻塞,否则直接触发线程阻塞报错。 - 试图用普通Stream转换key到Promotion,但每个
get(key)返回的是Uni<Promotion>,阻塞获取会破坏非阻塞模型,也没法正确合并多个反应式流。
修正后的代码
public Uni<List<Promotion>> listAll() { return this.reactiveRedisDataSource.key().keys("promo*") .onItem().ifNotNull() .transformToUni(keys -> { LOGGER.info("listAll ::: keys ::: " + keys); // 把每个key对应的Redis查询转为Uni<Promotion>,全程非阻塞 List<Uni<Promotion>> promotionUnis = keys.stream() .map(key -> this.reactiveRedisDataSource .value(String.class, Promotion.class) .get(key)) .toList(); // 合并所有Uni,等待全部完成后返回结果列表 return Uni.combine().all().unis(promotionUnis) .combinedWith(resultList -> (List<Promotion>) resultList); }); }
关键修改说明
- 移除阻塞调用:删掉
.await().indefinitely(),保留每个key对应的get(key)返回的Uni<Promotion>,确保所有操作都遵循非阻塞原则。 - 反应式合并流:用
Uni.combine().all().unis()收集所有查询操作的Uni实例,这个方法会等待所有异步操作完成后,自动把结果合并成一个列表,完美解决多流合并的问题。 - 类型转换:
combinedWith里的强转是因为合并后的默认结果是List<Object>,这里强转成List<Promotion>是安全的,因为所有元素都是Promotion类型。
内容的提问来源于stack exchange,提问作者William Mamani Cutipa
相关产品推荐
相关产品推荐

