在燃烧高香的季节,商业季节即将到来。
在以前的在线项目中,整个线程池的问题已经用尽。最近,我终于有时间研究它。问题并不复杂。这也是由于Dubbo线池的拒绝策略很快找到了粗糙的原因。
通过这个问题,每个家庭都对拒绝该策略的线程池也有一些好奇。放坑,挖土壤,让我们一起看一下?
偶尔的线程池的问题偶尔出现在线上。该现象如下:
调用下游接口时,侧面的线池耗尽。
起初,我认为这是突然的交通,但是监控显示稳定的交通,问题发现该问题仍在扩展后发现。逐渐意识到问题并不简单。
由于存在异常的日志和堆栈,因此首先要查看这种异常情况。在源代码中,我们可以发现此提示出现在中间。
从java.util.concurrent.threadpoolexecutor.abortpolicy继承,这是一个线程池拒绝策略。当线程池中的缓冲区任务已满,线程数达到最大值时,它将触发拒绝策略并调用拒绝策略以处理iTessence
那么,有哪些不同的拒绝策略?
在,我们可以找到JDK设定的四种拒绝策略:
在此策略下,如果线程池未关闭,则由当前称为线程处理,否则该任务将直接丢弃。
如果未配置拒绝策略,则默认情况下,线程池将使用该策略,将其直接扔给上层业务处理。
直接处理它的最简单方法。
该策略是队列中最古老的任务(实际上是要执行的下一个任务),并尝试执行当前任务。
那么拒绝的策略是什么?
实际上,可以从名称看。
拒绝策略是提出一个例外,同时做一件事 - 当时记录JVM线程堆栈。
让我们先看一下源代码。
该方法实际上非常简单。最后,调用当前的JVM线程堆栈转储,这是一个很大的好处,可以知道当时其他线程在做什么并有助于线程池溢出的原因。
线堆栈易于处理,看看该线程当时在做什么。
网络通信的潜在用途,涉及的线程池包括IO线程池(BOSS,Worker)和业务线程池(处理业务事件)。通过以前的日志,您可以看到它是服务器端的业务线程池,也就是说,精疲力尽,然后计算统计信息以查看线程在做什么。
显然,DB连接上的大量线程被阻塞,然后易于处理。您可以查看同一时间段的查询是否占用很长时间,或者连接池很小,线程池和连接池不正确。(不是讨论的焦点哈哈)。
可以看出,通过重写以帮助在异常场景中解决问题的策略,它带来了很大的帮助。
那么其他主流组件如何?
考虑到它,它包含许多线程池来处理不同的消息处理方案,包括发送,放置,拉,查询等。
在使用线程池时,可以通过继承包装来传递参数,这还包含配置。
实际上,当创建不同的线程池时,没有特殊的拒绝策略,因此使用默认值,即抛出异常。
同时,为了避免任务溢出,为每个线程池设置了一个较大的任务队列。
总而言之,使用拒绝策略,即引发异常。同时,为了避免任务队列溢出,设置了更大的任务队列。
想一想示例,默认情况下使用线程池的拒绝策略,并通过单个模式提供处理。
可以看出,默认拒绝策略也是异常的。对比之间的区别在于,将采用任务队列的大小,并且可以配置环境变量。
该团队一直在团队中使用它,这是一个分析存储组件计算存储分离和MPP体系结构。在查看了FE中的拒绝策略之后,有两个官方实施:
logdiscardpolicy
可以理解的是,任务被丢弃并记录了警告日志。
阻止的损失
此策略将是特殊的,它将阻止当前线程,尽力尝试将任务放入队列中。如果它超过指定的阻塞时间(默认60s),仍然不可能将任务放入队列中,然后记录警告日志并丢弃任务。
这两种策略实际上都在中国使用。同时,默认情况下,线程池的任务队列设置为10。
拒绝策略相对复杂,其自定义实现了两种拒绝策略。
实际上,本质上是,但是将进行一些特殊待遇,包括强制执行的判断,拒绝任务数量的任务数量,并最终引发了例外。
线程池在ES中的含义是什么?
在会议条件的情况下,即使可以使用ES定制任务包装和任务队列,您也可以确定是否根据任务配置强制任务队列。对于一些更重要的任务,当您无法丢弃时,您可以将其设置为真。
在任务队列中强制放置的效果取决于封装的队列类型。如果包装封装,它将阻止等待队列。如果包装是无限的,因为队列是无限的,并且PUT使用异步模式,则将立即放入队列并返回。
当线程池未关闭并且使用ES自定义任务队列时,任务将被迫将任务放入线程池队列中。在它们中,它也已继承,最后使用PUT方法来放置它在任务队列中,在异步模式下。
它看起来像它,最终使用的PUT方法是在异步模式非blocking中的队列中。
两者之间有许多相似之处,一些法官,当他们拒绝时被抛弃。
区别在于,默认情况下采用强制执行模式,并且在线程池关闭时仍可以将队列放入队列中。
我随意在Github滚动,也有一些方法可以看到策略链。实施也非常简单。您可以随意配置不同的策略。
拒绝策略的主要应用主要应用于线程池的资源溢出。除了JDK提供的四种拒绝策略外,不同的组件还将尝试使用不同的拒绝策略来应用。
JDK的拒绝策略
提供了Callerrunspolicy JDK,呼叫者线程处理apolicy jdk线程池默认值以抛弃提供异常的丢弃jdk,丢弃当前任务diss Disspololdestpolicy JDK提供,丢弃下一个任务定制拒绝策略|组件|类型| ------------------------------------- |------- |------ ||RocketMQ |堕胎|默认用来拒绝的线程池,即|Dubbo |abortpolicywithreport |投掷异常和报告溢出,报告溢出,记录JVM线程堆栈||网络|拒绝ExexecutionHandler |逻辑和一致性,抛出例外,将其封装为单个手柄,||多丽丝|logdiscardpolicy |逻辑和一致,丢弃任务,并记录警告日志|多丽丝|阻止Polic。|弹性|Esabortpolicy |通常且一致。队列的性能取决于队列类型,可以立即阻止或返回||弹性|ForcequeUepolicy |默认来强制任务或将其放在任务队列中,异步非屏体||其他|政策链|策略链通过节点处理的决策最终表现
原始:https://juejin.cn/post/71000047444067809316