系统的最佳线程数,怎么确定?

线程使用的两个核心规范

首先看编程规范中, 有两个很重要的,与线程有关的需要强制执行的规范:

规范一:【强制】线程资源必须通过线程池提供,不允许在应用中自行显式创建线程。

说明:Java线程的创建非常昂贵,需要JVM和OS(操作系统)配合完成大量的工作:

1)消耗内存资源:必须为线程堆栈分配和初始化大量内存块,其中包含至少1MB的栈内存。

2)消耗CPU资源:需要进行系统调用,以便在OS(操作系统)中创建和注册内核线程,大量内核线程调度会导致CPU上下文过度切换。

所以,Java高并发应用频繁创建和销毁线程的操作将是非常低效的,而且是不被编程规范所允许的。

如何降低Java线程的创建成本?必须使用到线程池。使用线程池的好处是减少在创建和销毁线程上所消耗的时间以及系统资源的开销,解决资源不足的问题。如果不使用线程池,有可能造成系统创建大量同类线程而导致消耗完内存或者“过度切换”的问题。

规范二:【强制】线程池不允许使用Executors去创建快捷线程池 ,而是通过ThreadPoolExecutor的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。

说明:Executors返回的线程池对象的弊端如下:

  • FixedThreadPool和SingleThreadPool: 允许的请求队列长度为Integer.MAX_VALUE,可能会堆积大量的请求,从而导致OOM。

  • CachedThreadPool和ScheduledThreadPool: 允许的创建线程数量为Integer.MAX_VALUE,可能会创建大量的线程,从而导致OOM。

通过以上规范,说明我们应用中,需要用自定义线程池。然而,由于构造一个线程池竟然有7个参数

图片

7个重要参数中,最为重要的三个是:核心,最大线程数量, BlockingQueue。前两个参数和线程数量有关系, 后一个和内存资源消耗有关。

线程数设置太少或者阻塞队列太小, 会导致大量任务被拒绝,抛出RejectedExecutionException,触发线上的接口降级,用户体验很差。

二线程数设置太多或者阻塞队列太长,会导致资源消费高而有效负荷很小, 特别是阻塞队列设置过长,会导致频繁FullGC,甚至OOM。

如何确定系统的最佳线程数?

如何确定系统的最佳线程数,大体上分三步:

第一步,理论预估;

第二步,压测验证;

第三步,监控调整。

step1: 完成线程数的理论预估 (设计阶段)

首先,按照任务类型对线程池进行分类, 分为三类,具体如下图:

图片

第一类:IO 密集型线程池线程数预估

线程数就是 CPU的核数的2倍。

图片

第二类:CPU密集线程池线程数预估

CPU密集型任务并行执行的数量应当等于CPU的核心数, 线程数就是 CPU的核数

图片

第三类:混合型线程池线程数预估

混合型线程池线程数预估, 参考下面的的公式:

最佳线程数 = ((线程等待时间 + 线程 CPU 时间) / 线程 CPU 时间 ) * CPU 核数

图片

step2: 完成线程数的压测验证 (测试阶段)

过少的线程会造成任务拒绝,业务降级。

过多的线程会造成,额外的内存开销CPU开销,甚至会导致OOM。

所以,合理的线程池线程数,才是王道。

在设计阶段完成了step1的线程数的理论预估之后, 那么我们的理论值就出来了。

如何做验证呢?这里需要 压测。

根据公式:

服务器端最佳线程数量=((线程等待时间+线程cpu时间)/线程cpu时间) * cpu数量

前面线程等待时间,线程cpu时间都是 预估的 ,都是要验证的。

首先通过用户慢慢递增来进行性能压测,观察QPS。持续大的增加用户数, 压测出最大的吞吐量。

然后再 收集 最大的吞吐量场景的 线程等待时间,线程cpu时间, 再计算出最佳线程数。

step3: 完成线程数的线上调整 (生产阶段)

压测的场景,是有限的。而线上的业务, 是复杂的,多样的。

由于系统运行过程中存在的不确定性,很难一劳永逸地规划一个合理的线程数。所以在实际线上验证的时候,需要通过实时监控预警的方式调整核心参数,这里主要可以监控的2个方面为:任务Reject次数过多、阻塞队列过载,基于这两个监控可以有依据的调整线程数(包括核心线程数、最大线程数)和阻塞队列的大小。

  • 14
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 确定Tomcat线程数需要考虑以下几个因素: 1. 硬件配置:Tomcat线程数应该与服务器的CPU和内存资源匹配。如果服务器配置较高,可以增加线程数,提高并发能力。 2. 应用负载:线程数应该根据应用的负载情况进行调整。如果应用负载较重,可以适当增加线程数以提高并发处理能力。 3. 线程池配置:Tomcat默认使用的线程池是org.apache.tomcat.util.threads.ThreadPoolExecutor,可以通过修改线程池的配置参数来控制线程数。例如,可以通过修改maxThreads参数来调整线程数。 4. 网络延迟:如果应用需要处理网络请求,需要考虑网络延迟的影响。如果网络延迟较高,可以适当增加线程数以提高并发处理能力。 总之,确定Tomcat线程数需要综合考虑硬件配置、应用负载、线程池配置和网络延迟等因素。一般情况下,可以通过监控应用的性能指标来进行调整。 ### 回答2: Tomcat线程数确定涉及到多个因素,包括服务器硬件资源、应用程序的负载以及性能需求等。 首先,服务器硬件资源是决定Tomcat线程数的重要因素之一。通过检查服务器的CPU核心数和内存大小,可以估算出服务器能够同时支持的线程数。一般来说,每个核心的CPU可以支持多个线程,但需要根据具体的硬件配置来确定。 其次,应用程序的负载对Tomcat线程数的需求也有影响。如果应用程序是高并发的,即有大量的请求需要同时处理,那么需要增加Tomcat的线程数。这样可以更好地并行处理请求,提高系统的响应速度。 此外,性能需求也是决定Tomcat线程数的一个重要考虑因素。如果希望系统能够提供更高的并发处理能力和更快的响应速度,那么可以增加Tomcat的线程数。但是过高的线程数可能会导致系统资源的过度消耗,甚至引发线程抢占资源的问题,因此需要合理平衡。 确定Tomcat线程数的一种常用方法是进行压力测试。通过模拟真实场景下的用户请求,并观察系统的负载情况和响应速度,可以逐步调整Tomcat的线程数,找到最佳的设置。压力测试可以使用专业的性能测试工具进行,比如Apache JMeter等。 总而言之,确定Tomcat线程数需要综合考虑服务器硬件资源、应用程序负载和性能需求等因素,并可以通过压力测试来找到最佳的设置。 ### 回答3: 确定Tomcat的线程数需要综合考虑以下几个方面: 1. 服务器硬件资源:首先,要根据服务器的硬件配置来确定Tomcat的线程数。如果服务器配置较高,比如有较多的处理器核心和内存,那么可以适当增加Tomcat的线程数,以充分利用服务器资源,提高系统的并发处理能力。 2. 预计的并发请求数:根据网站或应用预计的并发请求数来确定Tomcat的线程数。如果网站或应用预计会有大量并发请求,那么需要增加Tomcat的线程数,以确保能够及时响应并处理这些请求。 3. 处理请求的耗时:要考虑请求的处理时间,以确定Tomcat的线程数。如果每个请求的处理时间较长,那么需要更多的线程数来处理并发请求,以避免请求的排队等待时间过长。 4. 系统负载:要监控服务器的负载情况,以及Tomcat的CPU和内存使用情况。如果负载较高,或者CPU和内存使用率超过了服务器的承载能力,那么需要减少Tomcat的线程数,以降低系统的负载,避免过度消耗服务器资源。 综合以上因素,通过调整Tomcat的线程数,可以达到在服务器资源充分利用的同时,保证系统的稳定性和性能。可以使用Tomcat的配置文件(如server.xml)来设置线程池的大小,以及最小和最大线程数等参数,根据实际需求进行调整。但需要注意,调整线程数时,要进行适当的测试和监控,以确保系统的稳定性和性能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值