线程池、连接池、队列深度如何设置上限?

1. 概述

1.1 资源上限设置的重要性

线程池、连接池、队列深度是系统资源管理的核心参数,合理设置这些参数的上限直接影响系统的性能、稳定性和资源利用率。

资源上限设置的意义

  • 防止资源耗尽:避免系统资源被耗尽导致系统崩溃
  • 提高资源利用率:合理配置,提高资源利用率
  • 保证系统稳定性:避免资源竞争导致的系统不稳定
  • 优化系统性能:合理配置,优化系统性能

1.2 资源类型

主要资源类型

  1. 线程池(Thread Pool):管理线程资源
  2. 连接池(Connection Pool):管理数据库、HTTP等连接资源
  3. 队列深度(Queue Depth):管理任务队列的深度

1.3 本文内容结构

本文将从以下几个方面全面解析资源上限设置:

  1. 线程池参数设置:核心线程数、最大线程数、队列容量等
  2. 连接池参数设置:最大连接数、最小连接数、超时时间等
  3. 队列深度设置:队列容量、拒绝策略等
  4. 计算方法:如何计算合理的上限值
  5. 最佳实践:实际项目中的最佳实践
  6. 监控和调优:如何监控和调优资源使用

2. 线程池参数设置

2.1 ThreadPoolExecutor参数

2.1.1 核心参数

ThreadPoolExecutor核心参数

  • corePoolSize:核心线程数
  • maximumPoolSize:最大线程数
  • keepAliveTime:线程空闲存活时间
  • unit:时间单位
  • workQueue:工作队列
  • threadFactory:线程工厂
  • rejectedExecutionHandler:拒绝策略

2.1.2 参数说明

1
2
3
4
5
6
7
8
9
public ThreadPoolExecutor(
int corePoolSize, // 核心线程数
int maximumPoolSize, // 最大线程数
long keepAliveTime, // 线程空闲存活时间
TimeUnit unit, // 时间单位
BlockingQueue<Runnable> workQueue, // 工作队列
ThreadFactory threadFactory, // 线程工厂
RejectedExecutionHandler handler // 拒绝策略
)

2.2 核心线程数(corePoolSize)

2.2.1 设置原则

核心线程数设置原则

  • CPU密集型任务:corePoolSize = CPU核心数 + 1
  • IO密集型任务:corePoolSize = CPU核心数 × 2
  • 混合型任务:根据IO等待时间调整

2.2.2 计算方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
public class ThreadPoolCalculator {

/**
* 计算核心线程数
*/
public static int calculateCorePoolSize(TaskType taskType) {
int cpuCores = Runtime.getRuntime().availableProcessors();

switch (taskType) {
case CPU_INTENSIVE:
// CPU密集型:CPU核心数 + 1
return cpuCores + 1;

case IO_INTENSIVE:
// IO密集型:CPU核心数 × 2
return cpuCores * 2;

case MIXED:
// 混合型:根据IO等待时间调整
// 假设IO等待时间占比为50%
return (int) (cpuCores / (1 - 0.5));

default:
return cpuCores;
}
}

/**
* 根据IO等待时间计算
*/
public static int calculateCorePoolSizeByWaitTime(double waitTimeRatio) {
int cpuCores = Runtime.getRuntime().availableProcessors();
// 公式:线程数 = CPU核心数 / (1 - IO等待时间占比)
return (int) (cpuCores / (1 - waitTimeRatio));
}
}

enum TaskType {
CPU_INTENSIVE, // CPU密集型
IO_INTENSIVE, // IO密集型
MIXED // 混合型
}

2.3 最大线程数(maximumPoolSize)

2.3.1 设置原则

最大线程数设置原则

  • 不能无限大:避免创建过多线程导致系统资源耗尽
  • 考虑系统负载:根据系统负载和业务特点设置
  • 一般建议:maximumPoolSize = corePoolSize × 2 到 4倍

2.3.2 计算方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
public class ThreadPoolCalculator {

/**
* 计算最大线程数
*/
public static int calculateMaximumPoolSize(int corePoolSize, TaskType taskType) {
switch (taskType) {
case CPU_INTENSIVE:
// CPU密集型:最大线程数 = 核心线程数 + 1
return corePoolSize + 1;

case IO_INTENSIVE:
// IO密集型:最大线程数 = 核心线程数 × 2-4
return corePoolSize * 3;

case MIXED:
// 混合型:最大线程数 = 核心线程数 × 2
return corePoolSize * 2;

default:
return corePoolSize * 2;
}
}

/**
* 根据系统负载计算最大线程数
*/
public static int calculateMaximumPoolSizeByLoad(int corePoolSize, double systemLoad) {
// 系统负载高时,适当增加最大线程数
if (systemLoad > 0.8) {
return corePoolSize * 4;
} else if (systemLoad > 0.5) {
return corePoolSize * 3;
} else {
return corePoolSize * 2;
}
}
}

2.4 队列容量(workQueue)

2.4.1 队列类型

常用队列类型

  • ArrayBlockingQueue:有界队列,固定容量
  • LinkedBlockingQueue:可选有界队列,默认无界
  • SynchronousQueue:同步队列,不存储元素
  • PriorityBlockingQueue:优先级队列

2.4.2 队列容量设置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public class ThreadPoolCalculator {

/**
* 计算队列容量
*/
public static int calculateQueueCapacity(int corePoolSize, int maximumPoolSize, int expectedTasks) {
// 方法1:根据预期任务数计算
// 队列容量 = 预期任务数 - 最大线程数
int capacity1 = expectedTasks - maximumPoolSize;

// 方法2:根据核心线程数计算
// 队列容量 = 核心线程数 × 10
int capacity2 = corePoolSize * 10;

// 方法3:固定值(根据业务特点)
// 队列容量 = 1000(适合大多数场景)
int capacity3 = 1000;

// 取最小值,避免队列过大
return Math.min(Math.min(capacity1, capacity2), capacity3);
}

/**
* 根据响应时间要求计算队列容量
*/
public static int calculateQueueCapacityByResponseTime(
int qps,
double avgResponseTime,
int maxWaitTime) {
// 队列容量 = QPS × (最大等待时间 - 平均响应时间)
return (int) (qps * (maxWaitTime - avgResponseTime) / 1000);
}
}

2.5 完整线程池配置示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
@Configuration
public class ThreadPoolConfig {

/**
* CPU密集型任务线程池
*/
@Bean("cpuIntensiveExecutor")
public ThreadPoolExecutor cpuIntensiveExecutor() {
int cpuCores = Runtime.getRuntime().availableProcessors();

return new ThreadPoolExecutor(
cpuCores + 1, // 核心线程数
cpuCores + 1, // 最大线程数
60L, TimeUnit.SECONDS, // 空闲线程存活时间
new LinkedBlockingQueue<>(1000), // 队列容量
new ThreadFactoryBuilder()
.setNameFormat("cpu-pool-%d")
.build(),
new ThreadPoolExecutor.CallerRunsPolicy() // 拒绝策略
);
}

/**
* IO密集型任务线程池
*/
@Bean("ioIntensiveExecutor")
public ThreadPoolExecutor ioIntensiveExecutor() {
int cpuCores = Runtime.getRuntime().availableProcessors();

return new ThreadPoolExecutor(
cpuCores * 2, // 核心线程数
cpuCores * 4, // 最大线程数
60L, TimeUnit.SECONDS, // 空闲线程存活时间
new LinkedBlockingQueue<>(2000), // 队列容量
new ThreadFactoryBuilder()
.setNameFormat("io-pool-%d")
.build(),
new ThreadPoolExecutor.CallerRunsPolicy() // 拒绝策略
);
}

/**
* 混合型任务线程池
*/
@Bean("mixedTaskExecutor")
public ThreadPoolExecutor mixedTaskExecutor() {
int cpuCores = Runtime.getRuntime().availableProcessors();

return new ThreadPoolExecutor(
cpuCores, // 核心线程数
cpuCores * 2, // 最大线程数
60L, TimeUnit.SECONDS, // 空闲线程存活时间
new LinkedBlockingQueue<>(1500), // 队列容量
new ThreadFactoryBuilder()
.setNameFormat("mixed-pool-%d")
.build(),
new ThreadPoolExecutor.CallerRunsPolicy() // 拒绝策略
);
}
}

3. 连接池参数设置

3.1 数据库连接池(HikariCP)

3.1.1 核心参数

HikariCP核心参数

  • maximumPoolSize:最大连接数
  • minimumIdle:最小空闲连接数
  • connectionTimeout:连接超时时间
  • idleTimeout:空闲连接超时时间
  • maxLifetime:连接最大存活时间

3.1.2 最大连接数计算

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
public class ConnectionPoolCalculator {

/**
* 计算数据库连接池最大连接数
*/
public static int calculateMaxPoolSize(
int dbMaxConnections, // 数据库最大连接数
int applicationInstances, // 应用实例数
double peakLoadRatio) { // 峰值负载比例

// 方法1:根据数据库最大连接数计算
// 每个应用实例的连接数 = 数据库最大连接数 / 应用实例数
int connectionsPerInstance = dbMaxConnections / applicationInstances;

// 方法2:考虑峰值负载
// 最大连接数 = 基础连接数 × 峰值负载比例
int maxPoolSize = (int) (connectionsPerInstance * peakLoadRatio);

// 方法3:经验值
// 一般建议:最大连接数 = 20-50
int recommendedMax = 30;

// 取最小值,避免超过数据库限制
return Math.min(maxPoolSize, Math.min(recommendedMax, connectionsPerInstance));
}

/**
* 根据QPS和响应时间计算最大连接数
*/
public static int calculateMaxPoolSizeByQPS(
int qps, // 每秒查询数
double avgResponseTime, // 平均响应时间(秒)
double peakRatio) { // 峰值比例

// 最大连接数 = QPS × 平均响应时间 × 峰值比例
int maxPoolSize = (int) (qps * avgResponseTime * peakRatio);

// 设置上限:最小10,最大100
return Math.max(10, Math.min(maxPoolSize, 100));
}
}

3.1.3 HikariCP配置示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# application.yml
spring:
datasource:
hikari:
# 最大连接数
maximum-pool-size: 30
# 最小空闲连接数
minimum-idle: 10
# 连接超时时间(毫秒)
connection-timeout: 30000
# 空闲连接超时时间(毫秒)
idle-timeout: 600000
# 连接最大存活时间(毫秒)
max-lifetime: 1800000
# 连接测试查询
connection-test-query: SELECT 1
# 连接池名称
pool-name: HikariCP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
@Configuration
public class DataSourceConfig {

@Bean
public DataSource dataSource() {
HikariConfig config = new HikariConfig();

// 基础配置
config.setJdbcUrl("jdbc:mysql://localhost:3306/test");
config.setUsername("root");
config.setPassword("password");

// 连接池配置
int maxPoolSize = ConnectionPoolCalculator.calculateMaxPoolSize(
200, // 数据库最大连接数
4, // 应用实例数
1.2 // 峰值负载比例
);

config.setMaximumPoolSize(maxPoolSize);
config.setMinimumIdle(maxPoolSize / 3); // 最小空闲连接数 = 最大连接数 / 3
config.setConnectionTimeout(30000); // 30秒
config.setIdleTimeout(600000); // 10分钟
config.setMaxLifetime(1800000); // 30分钟

return new HikariDataSource(config);
}
}

3.2 HTTP连接池(Apache HttpClient)

3.2.1 核心参数

HttpClient连接池参数

  • maxTotal:最大连接数
  • defaultMaxPerRoute:每个路由的最大连接数
  • connectionRequestTimeout:获取连接超时时间
  • connectTimeout:连接超时时间
  • socketTimeout:读取超时时间

3.2.2 配置示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
@Configuration
public class HttpClientConfig {

@Bean
public CloseableHttpClient httpClient() {
// 连接池配置
PoolingHttpClientConnectionManager connectionManager =
new PoolingHttpClientConnectionManager();

// 最大连接数
int maxTotal = calculateMaxConnections();
connectionManager.setMaxTotal(maxTotal);

// 每个路由的最大连接数
int maxPerRoute = maxTotal / 2;
connectionManager.setDefaultMaxPerRoute(maxPerRoute);

// 请求配置
RequestConfig requestConfig = RequestConfig.custom()
.setConnectionRequestTimeout(5000) // 获取连接超时:5秒
.setConnectTimeout(5000) // 连接超时:5秒
.setSocketTimeout(10000) // 读取超时:10秒
.build();

return HttpClients.custom()
.setConnectionManager(connectionManager)
.setDefaultRequestConfig(requestConfig)
.build();
}

/**
* 计算最大连接数
*/
private int calculateMaxConnections() {
// 根据QPS和响应时间计算
int qps = 1000;
double avgResponseTime = 0.1; // 100ms
double peakRatio = 2.0;

return (int) (qps * avgResponseTime * peakRatio);
}
}

3.3 Redis连接池(Jedis)

3.3.1 核心参数

Jedis连接池参数

  • maxTotal:最大连接数
  • maxIdle:最大空闲连接数
  • minIdle:最小空闲连接数
  • maxWaitMillis:获取连接最大等待时间

3.3.2 配置示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
@Configuration
public class RedisConfig {

@Bean
public JedisPool jedisPool() {
JedisPoolConfig config = new JedisPoolConfig();

// 最大连接数
config.setMaxTotal(50);

// 最大空闲连接数
config.setMaxIdle(20);

// 最小空闲连接数
config.setMinIdle(10);

// 获取连接最大等待时间
config.setMaxWaitMillis(3000);

// 连接测试
config.setTestOnBorrow(true);
config.setTestWhileIdle(true);

return new JedisPool(config, "localhost", 6379);
}
}

4. 队列深度设置

4.1 线程池队列深度

4.1.1 队列类型选择

队列类型选择

  • 有界队列(ArrayBlockingQueue):固定容量,防止内存溢出
  • 无界队列(LinkedBlockingQueue):无容量限制,可能导致内存溢出
  • 同步队列(SynchronousQueue):不存储元素,直接传递

4.1.2 队列深度计算

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
public class QueueDepthCalculator {

/**
* 计算线程池队列深度
*/
public static int calculateThreadPoolQueueDepth(
int corePoolSize,
int maximumPoolSize,
int expectedQPS,
double avgTaskTime) {

// 方法1:根据QPS和任务时间计算
// 队列深度 = QPS × 平均任务时间 × 缓冲系数
int depth1 = (int) (expectedQPS * avgTaskTime * 1.5);

// 方法2:根据核心线程数计算
// 队列深度 = 核心线程数 × 10
int depth2 = corePoolSize * 10;

// 方法3:固定值
// 队列深度 = 1000(适合大多数场景)
int depth3 = 1000;

// 取合理值
return Math.max(100, Math.min(depth1, Math.max(depth2, depth3)));
}

/**
* 根据响应时间要求计算队列深度
*/
public static int calculateQueueDepthByResponseTime(
int qps,
double targetResponseTime,
double avgResponseTime) {

// 队列深度 = QPS × (目标响应时间 - 平均响应时间)
int depth = (int) (qps * (targetResponseTime - avgResponseTime));

// 设置上限:最小100,最大10000
return Math.max(100, Math.min(depth, 10000));
}
}

4.2 消息队列深度

4.2.1 Kafka队列深度

Kafka队列配置

  • max.poll.records:每次拉取的最大记录数
  • fetch.min.bytes:最小拉取字节数
  • fetch.max.wait.ms:最大等待时间
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Configuration
public class KafkaConsumerConfig {

@Bean
public ConsumerFactory<String, String> consumerFactory() {
Map<String, Object> props = new HashMap<>();

// 每次拉取的最大记录数
props.put(ConsumerConfig.MAX_POLL_RECORDS_CONFIG, 500);

// 最小拉取字节数
props.put(ConsumerConfig.FETCH_MIN_BYTES_CONFIG, 1024);

// 最大等待时间
props.put(ConsumerConfig.FETCH_MAX_WAIT_MS_CONFIG, 500);

return new DefaultKafkaConsumerFactory<>(props);
}
}

4.3 拒绝策略

4.3.1 常用拒绝策略

ThreadPoolExecutor拒绝策略

  • AbortPolicy:直接抛出异常
  • CallerRunsPolicy:调用者运行策略
  • DiscardPolicy:直接丢弃任务
  • DiscardOldestPolicy:丢弃最老的任务

4.3.2 自定义拒绝策略

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class CustomRejectedExecutionHandler implements RejectedExecutionHandler {

@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
// 记录日志
log.warn("Task rejected: poolSize={}, activeCount={}, queueSize={}",
executor.getPoolSize(),
executor.getActiveCount(),
executor.getQueue().size());

// 尝试放入队列(如果队列未满)
if (!executor.getQueue().offer(r)) {
// 队列已满,记录告警
alertService.sendAlert("Thread pool queue full", executor.toString());

// 可以选择:1. 抛出异常 2. 记录到数据库 3. 发送到消息队列
throw new RejectedExecutionException("Task rejected: " + r.toString());
}
}
}

5. 计算方法总结

5.1 线程池计算公式

5.1.1 CPU密集型

1
2
3
核心线程数 = CPU核心数 + 1
最大线程数 = 核心线程数 + 1
队列容量 = 核心线程数 × 10

5.1.2 IO密集型

1
2
3
核心线程数 = CPU核心数 × 2
最大线程数 = 核心线程数 × 2-4
队列容量 = 核心线程数 × 10-20

5.1.3 混合型

1
2
3
核心线程数 = CPU核心数 / (1 - IO等待时间占比)
最大线程数 = 核心线程数 × 2
队列容量 = 核心线程数 × 10-15

5.2 连接池计算公式

5.2.1 数据库连接池

1
2
最大连接数 = min(数据库最大连接数 / 应用实例数, 推荐值)
最小空闲连接数 = 最大连接数 / 3

5.2.2 HTTP连接池

1
2
最大连接数 = QPS × 平均响应时间 × 峰值比例
每个路由最大连接数 = 最大连接数 / 2

5.3 队列深度计算公式

1
队列深度 = max(QPS × 平均任务时间 × 缓冲系数, 核心线程数 × 10)

6. 最佳实践

6.1 线程池最佳实践

6.1.1 实践建议

实践建议

  1. 使用有界队列:避免无界队列导致内存溢出
  2. 合理设置拒绝策略:根据业务特点选择拒绝策略
  3. 监控线程池状态:实时监控线程池的使用情况
  4. 动态调整参数:根据实际负载动态调整参数

6.1.2 监控代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
@Component
public class ThreadPoolMonitor {

@Scheduled(fixedDelay = 60000) // 每分钟监控一次
public void monitorThreadPools() {
// 获取所有线程池
Map<String, ThreadPoolExecutor> threadPools = getThreadPools();

for (Map.Entry<String, ThreadPoolExecutor> entry : threadPools.entrySet()) {
String name = entry.getKey();
ThreadPoolExecutor executor = entry.getValue();

// 监控指标
int poolSize = executor.getPoolSize();
int activeCount = executor.getActiveCount();
int queueSize = executor.getQueue().size();
long completedTaskCount = executor.getCompletedTaskCount();

// 计算使用率
double poolUsage = (double) poolSize / executor.getMaximumPoolSize();
double queueUsage = (double) queueSize / executor.getQueue().remainingCapacity();

// 记录指标
meterRegistry.gauge("thread.pool.size", Tags.of("name", name), poolSize);
meterRegistry.gauge("thread.pool.active", Tags.of("name", name), activeCount);
meterRegistry.gauge("thread.pool.queue", Tags.of("name", name), queueSize);

// 告警
if (poolUsage > 0.8) {
alertService.sendAlert("Thread pool usage high",
String.format("Pool: %s, Usage: %.2f%%", name, poolUsage * 100));
}

if (queueUsage > 0.8) {
alertService.sendAlert("Thread pool queue full",
String.format("Pool: %s, Queue Usage: %.2f%%", name, queueUsage * 100));
}
}
}
}

6.2 连接池最佳实践

6.2.1 实践建议

实践建议

  1. 设置合理的最大连接数:不能超过数据库限制
  2. 设置最小空闲连接数:保证基本连接可用
  3. 设置连接超时时间:避免长时间等待
  4. 监控连接池状态:实时监控连接池使用情况

6.3 队列深度最佳实践

6.3.1 实践建议

实践建议

  1. 使用有界队列:避免无界队列导致内存溢出
  2. 设置合理的队列深度:根据业务特点设置
  3. 监控队列使用情况:实时监控队列深度
  4. 设置拒绝策略:队列满时的处理策略

7. 实战案例

7.1 案例:电商系统线程池配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
@Configuration
public class ECommerceThreadPoolConfig {

/**
* 订单处理线程池
*/
@Bean("orderExecutor")
public ThreadPoolExecutor orderExecutor() {
int cpuCores = Runtime.getRuntime().availableProcessors();

// IO密集型:订单处理涉及数据库、缓存、消息队列等IO操作
return new ThreadPoolExecutor(
cpuCores * 2, // 核心线程数:16
cpuCores * 4, // 最大线程数:32
60L, TimeUnit.SECONDS, // 空闲线程存活时间
new ArrayBlockingQueue<>(2000), // 队列容量:2000
new ThreadFactoryBuilder()
.setNameFormat("order-pool-%d")
.build(),
new CustomRejectedExecutionHandler() // 自定义拒绝策略
);
}

/**
* 支付处理线程池
*/
@Bean("paymentExecutor")
public ThreadPoolExecutor paymentExecutor() {
int cpuCores = Runtime.getRuntime().availableProcessors();

// IO密集型:支付涉及第三方接口调用
return new ThreadPoolExecutor(
cpuCores * 2, // 核心线程数:16
cpuCores * 3, // 最大线程数:24
60L, TimeUnit.SECONDS,
new ArrayBlockingQueue<>(1000), // 队列容量:1000
new ThreadFactoryBuilder()
.setNameFormat("payment-pool-%d")
.build(),
new CustomRejectedExecutionHandler()
);
}
}

7.2 案例:数据库连接池配置

1
2
3
4
5
6
7
8
9
10
# application.yml
spring:
datasource:
hikari:
# 根据数据库最大连接数200,应用实例数4计算
maximum-pool-size: 30 # 200 / 4 * 1.2 ≈ 30
minimum-idle: 10 # 30 / 3 = 10
connection-timeout: 30000
idle-timeout: 600000
max-lifetime: 1800000

8. 总结

8.1 核心要点

  1. 线程池参数:核心线程数、最大线程数、队列容量
  2. 连接池参数:最大连接数、最小空闲连接数、超时时间
  3. 队列深度:根据QPS、响应时间、业务特点计算
  4. 计算方法:根据任务类型、系统负载、业务特点计算
  5. 最佳实践:使用有界队列、合理设置拒绝策略、监控资源使用

8.2 关键理解

  1. CPU密集型:线程数 = CPU核心数 + 1
  2. IO密集型:线程数 = CPU核心数 × 2-4
  3. 连接池:不能超过数据库限制,考虑应用实例数
  4. 队列深度:使用有界队列,避免内存溢出

8.3 最佳实践

  1. 使用有界队列:避免无界队列导致内存溢出
  2. 合理设置拒绝策略:根据业务特点选择
  3. 监控资源使用:实时监控,及时调整
  4. 动态调整参数:根据实际负载动态调整

相关文章