Nis*_*ant 5 project-reactor spring-webflux
我正在使用Project Reactor我正在写的新服务。我使用的是Spring 5带Netty。我正在与许多不同的服务和关系数据库进行交互。所有这些服务都有一个正在阻止并且JDBC也在阻止的客户端。因此,基本上所有这些网络调用都不返回发布者。
我的问题是使用所有阻塞API时的最佳做法是什么。目前,我所做的是将所有阻塞的API代码包装Mono.callable并使用subscribeOn(Scheduler.elastic())。因此,基本上所有阻塞工作都是在弹性线程池上完成的。
问题1.我是否应该创建专用的线程池执行程序,而不是使用Elastic?如果是,那为什么呢?还是应该为每个不同的服务创建一个专用的弹性池?
问题2.在阻塞方法返回结果时,我应该使用publishOn以便主线程再次进行处理吗?如果是,如何获取主线程(netty事件循环线程?)引用?
问题3.如果我要在多个不同的运算符中调用多个阻塞调用(某些在链接时,有些在使用zip()调用时),那么使用subscribe publishand再次subscribe publish不会带来很多上下文切换?
这些问题大多数与最佳实践有关。
\n\n\n这些问题大多数都与最佳实践相关。
\n
Reactive Java 仍处于起步阶段,因此很难找到公认的“最佳实践”(在大多数情况下,整个社区尚未形成共识,因此只有 Reactor 开发团队的一些指导和其他一些。)
\n\n话虽这么说,我认为现在有一些被广泛接受的观点对此会有帮助。首先,您声明:
\n\n\n\n\n所有这些服务都有一个正在阻塞的客户端。
\n
这可能是最简单的一点,就好像您没有与大量其他非阻塞服务进行交互,那么使用reactor就没有什么意义了。例外情况是,如果您有明确的迁移路径将这些服务重写为非阻塞服务。
\n\n\n\n\nJDBC 也是阻塞的
\n
R2DBC不是,并且可能值得研究(尽管该项目还处于早期阶段。)
\n\n\n\n\n我应该创建一个专用的线程池执行器而不是使用弹性吗?
\n
没必要吧 (答案是“是”的唯一原因是,如果您有非常具体的线程要求,需要对该执行程序服务进行特定的“调整”,但如果是这样的话,您就不会问这个问题。)
\n\n但是,请考虑boundedElastic()相反,因为这对调度程序中的活动线程数量设置了上限,这可以减少造成背压问题的线程数量失控。该调度程序专门设计用于连接传统的阻塞 IO 库。
\n\n\n我应该为每个不同的服务创建一个专用的弹性池吗?
\n
除非您有特殊原因,否则不会。boundedElastic()如果您想要为不同的服务提供单独的(或不同的)绑定,这在调度程序中会更相关。(恕我直言,仅仅创建一个这样你就可以“给它一个相关的名称”并不是一个足够好的理由。)
\n\n\n当阻塞方法返回结果时,我应该使用publishOn以便主线程再次开始处理吗?
\n
这完全取决于您的用例 - 反应器故意与并发无关,因此取决于您是否需要在“主线程”中发布结果。(根据我的经验,通常你不在乎。)
\n\n\n\n\n如何获取主线程引用?
\n
publishOn(Schedulers.immediate())可用于在您调用的当前线程上发布。
\n\n\n如果我\xe2\x80\x99m 在多个不同的运算符中调用多个阻塞调用(有些在链接时,有些在使用 zip() 调用时),那么使用订阅发布并再次订阅发布将\xe2\x80\x99t 进行大量上下文切换?
\n
这取决于。但是,是的,当然有可能——这又回到了我的第一点。除非您在非阻塞代码上花费的时间超过了在线程池中调用阻塞服务所花费的时间,否则几乎没有动力进行切换(除非您计划在核心就位时逐步将服务迁移到非阻塞。)
\n\n仅切换到反应器并将其用作阻塞在线程池中的服务的前端,您当然不会获得性能增强。
\n| 归档时间: |
|
| 查看次数: |
330 次 |
| 最近记录: |