Tokio 中 hang 死所有 worker 的方法
Tokio 的 task (一个 Future ) 里如果使用了阻塞调用,例如 std::sync::Mutex
,会阻塞当前的 tokio-worker 线程,这个 worker 无法再执行其他 task。所以代码里如果不可避免的有(少量的)阻塞调用,就要为 runtime 启动更多的 worker 线程,保证存在没被阻塞的 worker 来执行待调度的 task,以避免整个 tokio runtime 完全 hang 住(有 task 但没 worker 运行它)。
但现实是,就算 worker 再多,tokio 也可能造成永久性的阻塞。
原因是 tokio 里的待执行 task 不是简单的放到一个 queue 里,除了 runtime 内共享的,可被每个 worker 消费的 run_queue
,每个 worker 还有一个自己的 lifo_slot
,只存储一个最后被放入的 task (目的是减小调度延迟)。lifo_slot
只由它所属的 worker 使用,里面存储的 task 不能被其他 worker 执行。由于这个结构,构造 hang 住的方法是如图所示:
Future f1 被 runtime-1 执行, 持有一个 async 的锁
m
后,返回了Pending
,这时它被调度到 worker-1 本地的lifo_slot
。Future f2 在 runtime-1 执行后返回
Pending
,被放入共享队列run_queue
。Future f3 在 runtime-1 中执行, 它将一个任务
f4
交给其他的 runtime 去完成(例如为了隔离网络IO和本地磁盘IO),使用block_on(f4)
的方式,等待执行结果返回。f4 中也需要锁
m
,等待。
这时,f2 在共享队列 run_queue
中,可以被执行,但是 f1 在 worker-1 本地的 lifo_slot
里,只能由 worker-1 调度,但 worker-1 当前阻塞在 f3。于是等待关系形成了一个环: f4 → m(f1) → f3 → f4
,hang 死任务达成。
张炎泼(XP) @ Databend
前白山云合伙人兼研发总裁
曾就职于新浪、美团云等。物理系背叛者,设计师眼中的美工,bug mafer,vim 死饭,研究分布式协议
关于 Databend
Databend 是一款开源、弹性、低成本,基于对象存储也可以做实时分析的新式数仓。期待您的关注,一起探索云原生数仓解决方案,打造新一代开源 Data Cloud。
Databend 文档:https://databend.rs/
Wechat:Databend

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
API 网关策略的二三事
作者暴渊,API7.ai 技术工程师,Apache APISIX Committer。 近些年随着云原生和微服务架构的日趋发展,API 网关以流量入口的角色在技术架构中扮演着越来越重要的作用。API 网关主要负责接收所有请求的流量并进行处理转发至上游服务,API 网关的策略决定了 API 网关处理这些流量的逻辑与规则,直接决定了实际的业务流量行为。 什么是 API 网关策略? API 网关一般位于所有的上游服务之前,当用户向服务发送请求后请求会先到 API 网关,API 网关接收到请求之后一般会判断几件事情: 请求是否合法,比如是否来自被禁止访问的用户列表中; 这个请求是否通过认证,访问的内容是否是经过授权的; 请求是否触发了某些限制规则,比如限流限速等; 请求应该转发给哪个上游服务。 经过这一系列步骤,这个请求要么不符合预设的规则被拒绝,要么经过了层层处理正确到达指定的上游服务中。我们将这些处理规则称之为 API 网关的策略。这些规则由网关的管理员在网关运行时不断添加至网关中,网关接受这些规则并根据这些规则作出正确的流量处理行为。 以 API 网关 Apache APISIX 为例,...
- 下一篇
feilong 3.4.1 发布了,让 Java 开发更简便的工具库
feilong 3.4.1 发布了,让Java开发更简便的工具库 让你从大量重复的底层代码中脱身,提高开发效率; 让你的代码更简炼,易写、易读、易于维护; 文档地址:http://feilong-core.mydoc.io/ maven 依赖配置: <dependency> <groupId>com.github.ifeilong</groupId> <artifactId>feilong</artifactId> <version>3.4.1</version> </dependency> Gradle 依赖配置: com.github.ifeilong:feilong:3.4.1 本次升级共有3处变更, 具体参见3.4.1 milestone 🎸feilong-context #512修改 com.feilong.context.invoker.DefaultResponseCommandBuilder.build(R) log 信息 [javadoc] #513修改 ...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- Linux系统CentOS6、CentOS7手动修改IP地址
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- SpringBoot2整合Redis,开启缓存,提高访问速度
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- MySQL8.0.19开启GTID主从同步CentOS8
- Mario游戏-低调大师作品
- CentOS7安装Docker,走上虚拟化容器引擎之路