react 线程_React式服务中的线程本地状态可用性

react 线程

任何架构决策都需要权衡。 如果您决定采用React式,也没有什么不同,例如,一方面使用React式流实现几乎可以立即获得更好的资源利用率,但另一方面会使调试更加困难。 引入React式库也对您的域产生巨大影响,您的域将不再仅在PaymentOrderCustomer方面说话,React式术语将破解Flux<Payment>Flux<Order>Mono<Customer> (或Observable<Payment>Flowable<Order>Single<Customer>或您选择的库提供的任何Reactive Streams发布者)。 这种折衷很快就变得很明显,但是您可能会猜到并不是所有的折衷都会如此明显– 泄漏抽象定律保证了这一点。

React性库使更改线程上下文变得轻而易举。 您可以轻松地订阅一个调度程序,然后在另一个调度程序上执行部分操作员链,最后跳到完全不同的调度程序上。 只要您不涉及线程本地状态,就可以从一个线程跳到另一个线程-尽管您的服务支持服务的关键部分(例如安全性,交易),但通常不会每天处理这种状态, 多租户)。 当技术堆栈中隐藏良好的部分取决于线程局部状态时,更改线程上下文会导致棘手的错误定位。

让我通过一个简单的示例演示该问题:

private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
private static final String SESSION_ID = "session-id";@GetMapping("documents/{id}")
Mono<String> getDocument(@PathVariable("id") String documentId) {MDC.put(SESSION_ID, UUID.randomUUID().toString());LOG.info("Requested document[id={}]", documentId);return Mono.just("Lorem ipsum").map(doc -> {LOG.debug("Sanitizing document[id={}]", documentId);return doc.trim();});
}

使用MDC.put(SESSION_ID, UUID.randomUUID().toString())我们将会话session-id放入基础日志库的映射诊断上下文中 ,以便稍后进行登录。

让我们以自动为我们记录session-id的方式配置记录模式:

logging.pattern.console=[%-28thread] [%-36mdc{session-id}] - %-5level - %msg%n

当我们通过请求( curl localhost:8080/documents/42 )访问公开的服务时,我们将看到session-id出现在日志条目中:

[reactor-http-server-epoll-10] [00c4b05f-a6ee-4a7d-9f92-d9d53dbbb9d0] - INFO  - Requested document[id=42]
[reactor-http-server-epoll-10] [00c4b05f-a6ee-4a7d-9f92-d9d53dbbb9d0] - DEBUG - Sanitizing document[id=42]

如果在将session-id放入MDC之后切换执行上下文(例如,通过预订不同的调度程序),情况将发生变化:

@GetMapping("documents/{id}")
Mono<String> getDocument(@PathVariable("id") String documentId) {MDC.put(SESSION_ID, UUID.randomUUID().toString());LOG.info("Requested document[id={}]", documentId);return Mono.just("Lorem ipsum").map(doc -> {LOG.debug("Sanitizing document[id={}]", documentId);return doc.trim();}).subscribeOn(Schedulers.elastic()); // don't use schedulers with unbounded thread pool in production
}

在执行上下文更改之后,我们将注意到该调度程序调度的操作员记录的日志条目中缺少session-id

[reactor-http-server-epoll-10] [c2ceae03-593e-4fb3-bbfa-bc4970322e44] - INFO  - Requested document[id=42]
[elastic-2                   ] [                                    ] - DEBUG - Sanitizing document[id=42]

您可能会猜到,我们正在使用的日志记录库内部隐藏了一些ThreadLocal

一些Reactive Streams实现提供了允许将上下文数据提供给操作员的机制(例如Project Reactor提供订户上下文 ):

@GetMapping("documents/{id}")
Mono<String> getDocument4(@PathVariable("id") String documentId) {String sessionId = UUID.randomUUID().toString();MDC.put(SESSION_ID, sessionId);LOG.info("Requested document[id={}]", documentId);return Mono.just("Lorem ipsum").zipWith(Mono.subscriberContext()).map(docAndCtxTuple -> {try(MDC.MDCCloseable mdc = MDC.putCloseable(SESSION_ID, docAndCtxTuple.getT2().get(SESSION_ID))) {LOG.debug("Sanitizing document[id={}]", documentId);return docAndCtxTuple.getT1().trim();}}).subscriberContext(Context.of(SESSION_ID, sessionId)).subscribeOn(Schedulers.elastic()); // don't use schedulers with unbounded thread pool in production
}

当然,使数据可用只是故事的一部分。 一旦我们提供了session-idsubscriberContext(Context.of(SESSION_ID, sessionId)) ),我们不仅必须检索它,还必须将其附加到线程上下文中,并且还记得要自己清理,因为调度程序可以自由地进行清理。重用线程。

提出的实现会带回session-id

[reactor-http-server-epoll-10] [24351524-f105-4746-8e06-b165036d02e6] - INFO  - Requested document[id=42]
[elastic-2                   ] [24351524-f105-4746-8e06-b165036d02e6] - DEBUG - Sanitizing document[id=42]

但是,使它起作用的代码太复杂,太具有侵入性,以致于在大多数代码库中都不用张开双臂来欢迎它,尤其是当它最终散布在整个代码库中时。

我很乐意通过为该问题提供一个简单的解决方案来结束本博客文章,但我还没有偶然发现这样的问题(现在,我们需要使用这样更复杂,更具侵入性的解决方案,同时还要尝试解决这种复杂性从以业务为中心的软件部分到基础设施部分,如果可能的话,还可以直接到库本身)。

翻译自: https://www.javacodegeeks.com/2018/09/thread-local-state-availability-in-reactive-services.html

react 线程

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/332972.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

iTerm2的使用技巧及快捷键

文章目录查看剪贴板内容清屏切换全屏切屏/分屏切换标签栏移动标签栏编辑会话打开最近的目录复制粘贴查找移动光标搜索历史命令查看历史命令删除滚屏界面窗口缩放搜索会话/配置文件/快照展开&#xff08;Expose&#xff09;所有的标签窗口操作查看当前终端中光标的位置开启和关闭…

位运算和进制转换,反码补码

进制转换 package junit;public class Test {public static void main(String[] args) { // int aInteger.MIN_VALUE;int bInteger.MAX_VALUE;int cInteger.MIN_VALUE;System.out.println(b);System.out.println(c);print(b);// 最高位表示 符号位 最高位0 表示正数 …

python绘制pr曲线图_如何利用Python制作可以动的动态图表。

来源&#xff1a;机器之心原文链接&#xff1a;https://towardsdatascience.com/learn-how-to-create-animated-graphs-in-python-fce780421afe在读技术博客的过程中&#xff0c;我们会发现那些能够把知识、成果讲透的博主很多都会做动态图表。他们的图是怎么做的&#xff1f;难…

switch字符串jdk_JDK 12 Early Access Build 12中的原始字符串文字支持

switch字符串jdk本周Java世界上最大的新闻可能是JDK 11的通用性。 但是&#xff0c;另一个令人兴奋的发展是JDK 12 Early Access Build 12的发布 &#xff08; 2018年9月20日 &#xff09;。 JDK 12的这个早期访问生成12是显著&#xff0c;因为它包括与实施方式中JEP 326 [“原…

MacOS安装pip失败,提示:SyntaxError: invalid syntax

使用命令 easy_install 安装 pip 使用命令 sudo easy_install pip 安装 pip&#xff0c;结果失败了&#xff0c;执行命令的信息如下&#xff1a; ➜ ~ sudo easy_install pip Password: Searching for pip Reading https://pypi.org/simple/pip/ Downloading https://files.…

java压缩视频

引入依赖 <dependency><groupId>ws.schild</groupId><artifactId>jave-core</artifactId><version>3.0.0</version></dependency><dependency><groupId>ws.schild</groupId><artifactId>jave-all-dep…

经济学自身利益最大化_劳动经济学:研究劳动力市场运作的专业

多年以来同学们对劳动经济学认知上存在误区&#xff0c;很多同学一上来看到劳动两字会误以为这是让自己去当工人干活。事实并非如此&#xff0c;例如人力资源管理&#xff0c;大家都知道是一门很热门、实用的管理学&#xff0c;毕业后可以从事hr的工作&#xff0c;其实劳动经济…

corda_使用Spring WebFlux从Corda节点流式传输数据

corda自上次发布以来已经有一段时间了&#xff0c;但我终于回来了&#xff01; 由于我仍在我的项目中&#xff0c;因此我将再次撰写有关使用Corda的文章。 这次&#xff0c;我们将不再关注Corda&#xff0c;而是将Spring与Corda结合使用。 更具体地说&#xff0c;Spring WebFlu…

iTerm2 隐藏用户名和主机名

有时候我们的用户名和主机名太长&#xff0c;比如我的&#xff1a; 这么长的提示符前缀&#xff0c;在终端显示的时候会很不好看&#xff0c;我们可以手动去除。 编辑 ~/.zshrc 文件&#xff0c;增加 DEFAULT_USER"lwx" 配置&#xff0c;如下所示&#xff1a; 注…

投影串口测试程序_串口测试方法和步骤

信号测试与分析版号&#xff1a;xxx编写&#xff1a;xxx1、232串口信号&#xff1a;要点&#xff1a;RS232采用三线制传输分别为TXD\RXD\GND其中TXD为发送信号&#xff0c;RXD为接收信号。全双工&#xff0c;在RS232中任何一条信号线的电压均为负逻辑关系。即&#xff1a;—15v…

springBoot中自定义的yml文件引用的方式

一、yml配置文件 在yam文件中配置自定义的标签 1.在yml配置文件中加入 through:url: http://10.4.2.140:49003/IBSThrough2.测试类进行测试 import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; /…

MacOS安装zsh插件zsh-autosuggestion(自动命令补全和建议)

文章目录安装命令一安装命令二安装命令三使用插件 zsh-autosuggestion 用于命令建议和补全。 GitHub主页&#xff1a;https://github.com/zsh-users/zsh-autosuggestions 安装命令一 cd ~/.oh-my-zsh/custom/plugins/ git clone https://github.com/zsh-users/zsh-autosugg…

javafx 调用java_Java,JavaFX的流畅设计风格拨动开关

javafx 调用java嗨&#xff0c;这次我将在新版本的JMetro中讨论新的Toggle Switch样式。 拨动开关是一种近年来非常流行的控件。 我前一段时间在ControlsFX库中添加了JavaFX实现。 刚刚发布的JMetro版本4.1中提供了此新样式。 什么是拨动开关 在以前的文章中&#xff0c;我讨…

polkit 重新安装_不折腾,为U-NAS安装一个清爽的桌面,把小U打造成双面高手

本帖最后由 emaic 于 2012-2-2 03:41 编辑除了文件的存储和下载外&#xff0c;U-NAS还可以干嘛&#xff1f;其实&#xff0c;只要你-U-NAS的硬件性能足够强悍&#xff0c;U-NAS可以完成很多你意想不到的工作哦&#xff0c;也会有很多意想不到的玩法&#xff0c;希望看了emaic打…

用于zsh的插件incr(目录提示和补全)

文章目录使用命令 wget 下载插件直接下载插件脚本文件配置提示存在不安全目录incr 是一个目录提示和补全插件。 使用命令 wget 下载插件 mkdir ~/.oh-my-zsh/custom/plugins/incr cd ~/.oh-my-zsh/custom/plugins/incr wget -O incr.plugin.zsh http://mimosa-pudica.net/src…

普罗米修斯使用es数据库_用普罗米修斯和格拉法纳仪法来豪猪

普罗米修斯使用es数据库Adam Bien的Porcupine库使配置充当应用程序隔板的专用执行程序服务变得容易。 我创建了一个扩展&#xff0c;通过MicroProfile Metrics公开了豪猪统计信息。 我们还可以通过Prometheus和Grafana仪表板使仪器可见。 进行此扩展的原因是我们希望对Porcupi…

2字节十六进制浮点数 qt_Qt二进制文件操作(读和写)详解

除了文本文件之外&#xff0c;其他需要按照一定的格式定义读写的文件都称为二进制文件。每种格式的二进制文件都有自己的格式定义&#xff0c;写入数据时按照一定的顺序写入&#xff0c;读出时也按照相应的顺序读出。例如地球物理中常用的 SEG-Y 格式文件&#xff0c;必须按照其…

cobol host变量_将Host Cobol批次和Monolith Webapps移动到云和微服务

cobol host变量在Amazon Event “从大型机到微服务– Vanguard迁移到云”中非常有趣的演示。 以下部分可用作迁移模式 &#xff1a;如何从大型机迁移到微服务的不同方式&#xff1a; 重新托管 再造 重构 使用Linux和Java重新平台 回购 退役 全部结合 该演示文稿还展示了V…

maven的常用命令

install 安装 功能&#xff1a; 编译和打包&#xff0c;把打好的可执行的jar包&#xff08;或者war包或者其他包&#xff09;部署到本地maven仓库 编译 javac 打包 -jar&#xff0c;将java代码打包为jar文件 安装到本地仓库-将打包的jar文件&#xff0c;保存到本地仓库目录中…

MacOS在zsh环境下安装和使用终端插件autojump

文章目录介绍安装 autojump使用 git clone使用 HomeBrew 安装配置使用 autojump卸载 autojump介绍 autojump is a faster way to navigate your filesystem. It works by maintaining a database of the directories you use the most from the command line. Directories must…