线程池 | 配置指南

线程池 | 配置指南

2026年5月7日星期四 · #学习文档 Java / 线程池 / 并发编程 · 4635 字 23 分钟 ·
-浏览量
·
简介

Java ThreadPoolExecutor 核心参数、线程数估算、队列选型与拒绝策略,附带企业级监控与动态调优方案。

线程池 | 配置指南#

本文面向需要在生产环境配置 Java 线程池的开发者。核心目标:将 ThreadPoolExecutor 的七个参数、任务调度流程、CPU/IO 场景差异、线程数估算方法、队列选型原则、监控指标与动态调优方案整理为可执行的工程规范。重点审查项:线程数是否受下游资源约束、拒绝策略是否可观测、容器环境是否正确读取 CPU 核数。

核心摘要#

  • 问题:手动创建线程存在资源失控、创建开销大、缺乏背压与降级机制三类风险。
  • 方案:使用 ThreadPoolExecutor 显式配置核心线程数、最大线程数、队列、拒绝策略与线程工厂,并通过监控指标闭环调优。
  • 关键约束corePoolSize 不应超过下游最小连接池容量;必须使用有界队列;拒绝策略必须可观测。
  • 目标:读完本文后,能够针对 CPU 密集、IO 密集、混合型三种业务场景给出初始配置,并设计压测与监控方案。

一、为什么需要线程池#

手动为每个请求创建线程,存在以下三类问题:

问题具体表现后果
资源失控每个线程默认约 1MB 栈空间(-Xss 可配置),1000 个并发请求约占用 1GB 堆外内存突发流量下触发 OOM
创建开销线程创建涉及 JVM 栈分配、OS 内核态切换,单次约 10~50μs高频创建时 CPU 与延迟显著上升
管理缺失无法限制并发上限、无法感知任务积压、无法优雅降级故障时缺乏控制手段

线程池提供的核心能力:

  1. 线程复用:降低线程创建与销毁开销。
  2. 有界队列:提供背压机制,防止无限堆积。
  3. 拒绝策略:在容量耗尽时执行降级或告警。

二、ThreadPoolExecutor 核心参数#

ThreadPoolExecutor 的构造函数包含七个参数,必须整体理解:

new ThreadPoolExecutor(
corePoolSize, // 1. 核心线程数
maximumPoolSize, // 2. 最大线程数
keepAliveTime, // 3. 非核心线程空闲存活时间
TimeUnit.SECONDS, // 4. 时间单位
new LinkedBlockingQueue<>(1000), // 5. 工作队列
new NamedThreadFactory("order-exec"), // 6. 线程工厂
new ThreadPoolExecutor.CallerRunsPolicy() // 7. 拒绝策略
);

2.1 corePoolSize 与 maximumPoolSize#

参数含义行为
corePoolSize长期保活的核心线程数即使空闲,默认也不回收(除非调用 allowCoreThreadTimeOut(true)
maximumPoolSize线程池允许创建的最大线程数仅在工作队列满后才会扩张到此值

两种典型策略:

  • 固定大小corePoolSize = maximumPoolSize。无弹性,依赖队列缓冲流量波动。
  • 弹性伸缩corePoolSize < maximumPoolSize。队列满后扩容,空闲线程超时回收。

2.2 keepAliveTime 与 TimeUnit#

  • 控制非核心线程的空闲回收时间。
  • 建议值 30~120 秒。过短导致线程频繁创建销毁,引起 CPU 抖动;过长导致资源闲置。

2.3 工作队列#

队列类型决定排队行为与弹性空间,必须与线程数一起决策。详见第六章。

2.4 线程工厂#

生产环境必须自定义线程工厂,原因:

  • jstack 或 arthas 排查时,"pool-1-thread-1" 无法判断业务归属;
  • 命名清晰的线程(如 "order-exec-1")可快速定位问题线程池。
public class CustomThreadFactory implements ThreadFactory {
private final String prefix;
private final AtomicInteger counter = new AtomicInteger(1);
public CustomThreadFactory(String prefix) {
this.prefix = prefix;
}
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r, prefix + "-" + counter.getAndIncrement());
t.setDaemon(false);
t.setUncaughtExceptionHandler((thread, ex) ->
log.error("线程 {} 发生未捕获异常", thread.getName(), ex));
return t;
}
}

2.5 拒绝策略#

当工作队列满且线程数达到 maximumPoolSize 时,新任务触发拒绝策略:

策略行为适用场景风险
AbortPolicy(默认)抛出 RejectedExecutionException核心链路,必须让调用方感知拒绝调用方需捕获异常
CallerRunsPolicy由提交线程自身执行不能丢任务,天然限流可能阻塞调用线程
DiscardPolicy静默丢弃可幂等重试的非关键任务无感知数据丢失,生产慎用
DiscardOldestPolicy丢弃队头最老任务实时性优先,允许淘汰旧请求老请求静默失败

生产建议:优先实现自定义拒绝策略,记录指标、触发告警、执行降级。


三、任务提交与执行流程#

flowchart TD A[提交任务] A --> B{当前线程数 < corePoolSize?} B -->|是| C[创建核心线程并执行] B -->|否| D[将任务放入工作队列] D --> E{工作队列是否已满?} E -->|否| F[任务在队列中等待] E -->|是| G{当前线程数 < maximumPoolSize?} G -->|是| H[创建非核心线程并执行] G -->|否| I[触发拒绝策略]

关键认知:只有工作队列满了,线程池才会创建非核心线程。若使用无界队列,maximumPoolSize 永远不会生效。


四、CPU 密集型与 IO 密集型任务#

线程池大小最核心的决策依据是阻塞比(W/C),即等待时间与计算时间的比值。

4.1 CPU 密集型#

典型场景:加密解密、数据压缩、图像处理、复杂排序、JSON 序列化。

  • 线程大部分时间占用 CPU 执行指令。
  • 阻塞比 W/C 约等于 0。
  • 线程切换是纯损耗,不会提升吞吐。
  • 线程数建议N_cpu + 1

4.2 IO 密集型#

典型场景:数据库查询、HTTP 远程调用、文件读写、消息队列消费。

  • 线程大量时间处于 IO 等待状态。
  • 阻塞比 W/C 可达几倍到几十倍。
  • CPU 空闲期间可调度更多线程,提升资源利用率。
  • 线程数建议:根据 Goetz 公式估算,并受下游连接池约束。

4.3 混合型任务#

典型 Web 请求链路示例:

阶段类型耗时占比(示例)
接受 HTTP 请求网络 IO约 5%
参数校验 / 反序列化CPU约 5%
查询数据库IO 等待约 70%
业务规则计算CPU约 10%
写 Redis 缓存IO约 10%

混合场景应分段分析,或通过压测统计整体阻塞比,避免直接套用单一公式。


五、线程数估算方法#

5.1 Little’s Law#

系统稳态下的基本关系:

平均并发数 L = 到达率 λ × 平均响应时间 W

推导出线程数下界:

N_threads ≥ λ × T_response

示例:峰值 QPS = 500,平均 RT = 200ms = 0.2s,则最低需要 500 × 0.2 = 100 个并发线程维持吞吐。

5.2 Brian Goetz 公式#

出处:《Java 并发编程实战》

N_threads = N_cpu × U_cpu × (1 + W/C)
参数含义获取方式
N_cpuCPU 核心数Runtime.getRuntime().availableProcessors()
U_cpu目标 CPU 利用率建议 0.7~0.85,预留余量给 GC / OS / 其他进程
W/C等待时间 / 计算时间Profiler 或 APM 统计

示例:8 核机器,目标利用率 80%,IO 等待 200ms,计算 20ms。

  • W/C = 200 / 20 = 10
  • N = 8 × 0.8 × (1 + 10) = 70.4,取 72

5.3 公式的局限#

  1. 阻塞比难以准确测量:不同流量时段、不同数据量下差异巨大,单次测量值可能误导。
  2. 忽略下游瓶颈:数据库连接池上限 50 时,设 200 个线程只会造成大量线程等待连接,反而劣化延迟。
  3. 假设任务同质:同一池处理轻量查询与重量报表时,平均 W/C 失去意义。

5.4 估算流程#

1. 用 Goetz 公式或 Little's Law 得出理论初始值
2. 对比下游资源上限(DB 连接池、HTTP 连接池),取较小值
3. 结合机器内存校验:线程数 × 1MB(默认栈)不超过可用堆外内存的 50%
4. 以该值作为压测起点,做阶梯加压验证

5.5 常见场景参考值#

场景corePoolSizemaximumPoolSize说明
CPU 密集N_cpu + 1N_cpu + 1+1 防止偶发 IO 阻塞
IO 密集(DB 为主)min(N_cpu × 10, DB 连接池)core × 1.2严格受下游约束
IO 密集(HTTP 为主)N_cpu × (1 + W/C)core × 1.5W/C 需实测
混合型 Web实测后取 10~20× 核数core × 1.25务必压测验证
定时任务 / 批处理2~N_cpucore × 2避免与业务线程池竞争

六、工作队列选型#

队列类型容量行为特征适配场景配套线程数策略
LinkedBlockingQueue(n)有界FIFO,满时触发拒绝策略通用业务,需要背压core = max = N,队列缓冲突发
SynchronousQueue0无缓冲,提交必须立即有线程接收高吞吐低延迟max 较大,newCachedThreadPool 底层
ArrayBlockingQueue(n)有界,数组实现内存局部性好,容量固定严格控制内存core 小,max 大,队列满才扩容
PriorityBlockingQueue无界按优先级出队任务有优先级差异必须控制提交速率
DelayQueue无界到期才出队延迟任务、定时重试core = max = 固定小值

生产红线:禁止使用 Executors.newFixedThreadPool()Executors.newCachedThreadPool()

  • newFixedThreadPool 使用无界 LinkedBlockingQueue,任务堆积可导致 OOM。
  • newCachedThreadPoolmaximumPoolSizeInteger.MAX_VALUE,突发流量下线程数失控。

七、常见反模式#

7.1 全局共用一个线程池#

核心链路与非核心链路共享线程池时,非核心任务突发会挤占核心任务资源。

// 错误:所有任务共用
@Bean("globalExecutor")
ThreadPoolExecutor global() { ... }
// 正确:按业务隔离
@Bean("paymentExecutor") // 核心链路
ThreadPoolExecutor payment() { ... }
@Bean("logExecutor") // 非核心,允许丢弃
ThreadPoolExecutor log() { ... }

7.2 不考虑下游限制盲目设大#

下游 MySQL 连接池上限 50 时,设 500 个线程会导致 450 个线程空等连接,增加上下文切换与排队延迟。

正确做法corePoolSize ≤ 下游最小连接池上限

7.3 keepAliveTime 设置过短#

流量波动场景下,keepAliveTime 过短(如 1 秒)会导致非核心线程频繁创建销毁,造成 CPU 与内存抖动。

正确做法:建议 30~120 秒。

7.4 任务中嵌套提交任务#

// 危险:父任务等待子任务,子任务无法入队 → 死锁
executor.submit(() -> {
Future<?> child = executor.submit(() -> { /* 子任务 */ });
child.get();
});

正确做法:使用 ForkJoinPool 处理父子依赖任务,或为子任务使用独立线程池。

7.5 容器环境不修正 CPU 核数#

Docker 容器限制 2 核时,旧版 JDK 的 Runtime.getRuntime().availableProcessors() 可能返回宿主机 32 核,导致线程数虚高。

// 问题版本
int cores = Runtime.getRuntime().availableProcessors();
// 安全版本:读取容器 CPU 配额
private int getCpuCores() {
String cpuLimit = System.getenv("CPU_LIMIT");
if (cpuLimit != null) return Integer.parseInt(cpuLimit);
try {
Path quotaPath = Paths.get("/sys/fs/cgroup/cpu/cpu.cfs_quota_us");
Path periodPath = Paths.get("/sys/fs/cgroup/cpu/cpu.cfs_period_us");
long quota = Long.parseLong(Files.readString(quotaPath).trim());
long period = Long.parseLong(Files.readString(periodPath).trim());
if (quota > 0) return (int) Math.ceil((double) quota / period);
} catch (Exception ignored) {}
return Runtime.getRuntime().availableProcessors();
}

7.6 线程未命名#

jstack"pool-1-thread-1" 无法判断业务归属,应使用 "order-exec-1" 等命名。


八、企业级配置案例#

8.1 需求分析清单#

配置线程池前必须明确:

  1. 峰值 QPS、平均 RT、P99 RT 是多少?
  2. 任务是否存在外部依赖?下游连接池上限是多少?
  3. SLA 要求:能否丢任务?允许多大延迟?
  4. 容器 / Pod 分配的 CPU 核数是多少?

8.2 订单查询服务配置示例#

场景:8 核 Pod,DB 查询 60ms,本地计算 5ms,W/C ≈ 12,目标 CPU 利用率 80%,DB 连接池上限 50。

计算过程

Goetz 公式:8 × 0.8 × (1 + 12) = 83.2 → 取 84
约束检查:DB 连接池上限 50 → 线程数不应超过 50
内存检查:50 × 1MB = 50MB,在 2GB Pod 内可接受
最终决策:
corePoolSize = 50
maximumPoolSize = 60
queue = LinkedBlockingQueue(300)
keepAliveTime = 60 秒
拒绝策略 = 自定义(记录指标 + 抛异常)

代码实现

@Bean("orderExecutor")
public ThreadPoolExecutor orderExecutor() {
int cores = Runtime.getRuntime().availableProcessors();
int effectiveCores = Math.min(cores, Integer.parseInt(
System.getenv().getOrDefault("CPU_LIMIT", String.valueOf(cores))));
int dbPoolSize = 50;
int coreSize = Math.min(effectiveCores * 10, dbPoolSize);
int maxSize = (int) (coreSize * 1.2);
int queueCap = coreSize * 6;
ThreadPoolExecutor executor = new ThreadPoolExecutor(
coreSize, maxSize,
60L, TimeUnit.SECONDS,
new LinkedBlockingQueue<>(queueCap),
new CustomThreadFactory("order-exec"),
new MetricsRejectedHandler("order")
);
executor.allowCoreThreadTimeOut(false);
return executor;
}

自定义拒绝处理器

public class MetricsRejectedHandler implements RejectedExecutionHandler {
private final String poolName;
public MetricsRejectedHandler(String poolName) {
this.poolName = poolName;
}
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
Metrics.counter("threadpool.rejected", "pool", poolName).increment();
log.error("[{}] 任务被拒绝,队列积压:{} 活跃线程:{} 最大线程:{}",
poolName, e.getQueue().size(), e.getActiveCount(), e.getMaximumPoolSize());
throw new RejectedExecutionException("Pool " + poolName + " is saturated");
}
}

8.3 压测验证方案#

阶梯加压节奏:

10 并发 → 稳定 2 分钟 → 记录基准
50 并发 → 稳定 2 分钟 → 记录吞吐 / RT / 队列深度
100 并发 → 稳定 2 分钟 → 观察是否积压
150 并发 → 稳定 2 分钟 → 观察 P99 劣化点
200 并发 → 稳定 2 分钟 → 寻找拒绝临界点

压测期间重点采集:

pool.getActiveCount(); // 当前活跃线程数
pool.getQueue().size(); // 排队任务数
pool.getCompletedTaskCount(); // 已完成任务总数
pool.getLargestPoolSize(); // 历史最大线程数
pool.getTaskCount(); // 提交的总任务数

九、动态线程池#

9.1 动态调整原理#

ThreadPoolExecutor 支持运行时修改核心参数:

executor.setCorePoolSize(newCoreSize);
executor.setMaximumPoolSize(newMaxSize);

结合 Apollo / Nacos 配置中心可实现秒级热更新。

9.2 实现示例#

@Component
public class DynamicThreadPoolManager {
@Autowired
private ThreadPoolExecutor orderExecutor;
@NacosConfigListener(dataId = "thread-pool-config", groupId = "DEFAULT_GROUP")
public void onConfigChange(String configJson) {
ThreadPoolConfig cfg = JSON.parseObject(configJson, ThreadPoolConfig.class);
int newCore = cfg.getCoreSize();
int newMax = cfg.getMaxSize();
// 扩大时先改 max,缩小时先改 core
if (newCore > orderExecutor.getMaximumPoolSize()) {
orderExecutor.setMaximumPoolSize(newMax);
orderExecutor.setCorePoolSize(newCore);
} else {
orderExecutor.setCorePoolSize(newCore);
orderExecutor.setMaximumPoolSize(newMax);
}
log.info("线程池动态调整完成 pool=order core={} max={}", newCore, newMax);
}
}

9.3 队列容量动态修改#

标准 BlockingQueue 容量在构造时固定。如需动态队列,可选:

  1. 自实现 ResizableLinkedBlockingQueue:重写 capacity setter,加锁保证并发安全。
  2. 开源方案
    • dynamic-tp(京东开源):支持参数热更新、监控、告警一体化。
    • Hippo4j(美团团队维护):企业级动态线程池框架,支持多注册中心。

十、可观测性:监控与告警#

10.1 Prometheus 指标暴露#

public static void registerToPrometheus(ThreadPoolExecutor pool, String name) {
MeterRegistry registry = Metrics.globalRegistry;
Gauge.builder("threadpool.active", pool, ThreadPoolExecutor::getActiveCount)
.tag("pool", name).description("活跃线程数").register(registry);
Gauge.builder("threadpool.pool_size", pool, ThreadPoolExecutor::getPoolSize)
.tag("pool", name).description("当前线程总数").register(registry);
Gauge.builder("threadpool.queue_size", pool, p -> p.getQueue().size())
.tag("pool", name).description("队列积压任务数").register(registry);
Gauge.builder("threadpool.utilization", pool,
p -> (double) p.getActiveCount() / p.getCorePoolSize())
.tag("pool", name).description("核心线程利用率").register(registry);
Gauge.builder("threadpool.largest_pool_size", pool, ThreadPoolExecutor::getLargestPoolSize)
.tag("pool", name).description("历史最大线程数").register(registry);
}

10.2 AlertManager 告警规则#

groups:
- name: threadpool_alerts
rules:
- alert: ThreadPoolHighUtilization
expr: threadpool_utilization > 0.85
for: 2m
labels:
severity: warning
annotations:
summary: "线程池 {{ $labels.pool }} 利用率超过 85%"
- alert: ThreadPoolQueueBacklog
expr: threadpool_queue_size / threadpool_queue_capacity > 0.7
for: 1m
labels:
severity: warning
annotations:
summary: "线程池 {{ $labels.pool }} 队列积压超过 70%"
- alert: ThreadPoolRejection
expr: increase(threadpool_rejected_total[1m]) > 0
for: 0m
labels:
severity: critical
annotations:
summary: "线程池 {{ $labels.pool }} 出现任务拒绝"
- alert: ThreadPoolMaxSizeReached
expr: threadpool_pool_size >= threadpool_max_size
for: 3m
labels:
severity: warning
annotations:
summary: "线程池 {{ $labels.pool }} 线程数触达最大值,持续 3 分钟"

10.3 告警阈值参考#

指标WarningCritical含义
活跃线程 / 核心线程数> 80%> 95%线程饱和,即将排队
队列积压量> 队列容量 50%> 80%消费跟不上,延迟上涨
被拒绝任务数(1 分钟)> 0> 10系统过载
线程数触达 maximumPoolSize持续 1 分钟持续 5 分钟需要扩容或限流

十一、性能调优建议#

11.1 线程数调优#

  • 初始值:使用 Goetz 公式或历史 QPS/RT 数据估算。
  • 约束校验:确保 corePoolSize ≤ min(DB 连接池, HTTP 连接池, 内存可承载线程数)
  • 压测验证:以阶梯加压找到吞吐拐点,将 corePoolSize 设置在拐点并发量的 70%~80%。
  • 动态调整:流量波动明显的服务接入动态线程池。

11.2 队列深度调优#

  • 队列容量不宜过大:过大会隐藏延迟问题,导致 P99 劣化。
  • 经验公式:queueCapacity = corePoolSize × 平均 RT(秒) × 安全系数(2~3)
  • 需要背压的场景使用有界队列,拒绝策略选择 CallerRunsPolicy 或自定义策略。

11.3 GC 与内存调优#

  • 关注线程栈内存占用:默认 1MB/线程,可通过 -Xss 调整。
  • 高频创建/销毁线程会增加 Native Memory 分配压力,尽量复用线程。
  • 容器环境开启 -XX:+UseContainerSupport(JDK 8u191+)。

11.4 上下文切换调优#

  • cs(上下文切换次数)/ 任务数 持续升高时,说明线程数过多。
  • 使用 vmstatpidstat -w 监控上下文切换频率。
  • 在线程饱和前扩容机器或优化任务计算逻辑。

十二、常见问题解答(FAQ)#

Q1:corePoolSizemaximumPoolSize 应该设成一样吗?#

A:不一定。固定大小(core = max)适合负载稳定的场景,实现简单;弹性伸缩(core < max)适合流量波动大、需要应对突发的场景。生产环境更推荐后者,配合有界队列使用。

Q2:为什么线程池达到了 maximumPoolSize 但 CPU 使用率仍然很低?#

A:可能原因:

  1. 线程大部分时间阻塞在 IO 等待,CPU 未被有效利用;
  2. 下游服务(数据库、缓存、HTTP 接口)成为瓶颈;
  3. 锁竞争严重,线程实际并行度不足。

应通过 APM 或 Profiler 定位具体阻塞点,而不是简单增加线程数。

Q3:任务被拒绝时应该选择哪种策略?#

A:核心链路推荐 AbortPolicy 或自定义策略(记录指标 + 抛异常),让调用方感知并降级;非核心但不可丢任务的场景可选 CallerRunsPolicy;可丢弃的非关键任务可选 DiscardPolicyDiscardOldestPolicy

Q4:使用 CompletableFuture 时如何指定自定义线程池?#

ACompletableFuture 默认使用 ForkJoinPool.commonPool(),可能不适合业务场景。应显式传入:

CompletableFuture.supplyAsync(() -> fetchOrder(orderId), orderExecutor)
.thenApplyAsync(this::enrichOrder, orderExecutor);

Q5:Spring 的 @Async 默认线程池有什么问题?#

A:Spring 默认使用 SimpleAsyncTaskExecutor,每次任务都新建线程,且队列无界。生产环境应通过 ThreadPoolTaskExecutor 自定义:

@Bean("taskExecutor")
public ThreadPoolTaskExecutor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(16);
executor.setMaxPoolSize(32);
executor.setQueueCapacity(200);
executor.setThreadNamePrefix("async-");
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.initialize();
return executor;
}

Q6:如何优雅关闭线程池?#

A:使用 shutdown() + awaitTermination() 组合:

executor.shutdown();
try {
if (!executor.awaitTermination(60, TimeUnit.SECONDS)) {
executor.shutdownNow();
}
} catch (InterruptedException e) {
executor.shutdownNow();
Thread.currentThread().interrupt();
}

Q7:allowCoreThreadTimeOut(true) 是否推荐?#

A:适合流量波动极大的场景,可在低峰期回收核心线程节省资源。但会增加高峰期线程创建开销,核心链路建议保持默认 false


十三、决策速查表#

场景corePoolSizemaximumPoolSize队列拒绝策略
CPU 密集N_cpu + 1N_cpu + 1有界或小容量AbortPolicy
IO 密集(有下游限制)min(公式值, 下游连接池)core × 1.2有界自定义 + 指标
高吞吐低延迟N_cpu × 2较大SynchronousQueueCallerRunsPolicy
批处理 / 定时任务2~N_cpucore × 2有界CallerRunsPolicy
混合型 Web实测后 10~20× 核数core × 1.25有界自定义 + 指标

总结#

  1. 永远不用 Executors 工厂方法,必须显式构造 ThreadPoolExecutor
  2. 必须使用有界队列,无界队列是 OOM 隐患。
  3. corePoolSize 不超过下游最小连接池,这是物理约束。
  4. 拒绝策略必须可观测,静默丢弃在生产环境等于数据黑洞。
  5. 暴露监控指标并设置告警,线程池问题不能靠感觉发现。

合理工程流程:

flowchart LR A[公式估算] --> B[约束校验] --> C[压测验证] --> D[监控落地] --> E[动态调整]

参考资料#

  • 《Java 并发编程实战》Brian Goetz
  • 阿里巴巴《Java 开发手册》
  • dynamic-tp
  • Hippo4j
线程池 | 配置指南
https://tblog.mmzhiku.xyz/posts/projects/projects-java-thread-pool-configuration/
作者
MmzMing
发布于
2026-05-07
许可协议
CC BY-NC-SA 4.0

评论区

看板娘
公告
友链 互换友链

正在招募技术类博客友链,要求原创、稳定更新。点击了解更多。

查看详情
维护 服务器升级

本周日凌晨 2:00-4:00 进行服务器维护,期间站点可能短暂无法访问。

欢迎 关于我的介绍

欢迎来到我的博客,我是深耕java、python和react技术开发。热爱技术、持续学习,欢迎同好交流探讨,也欢迎大佬互换友链。

查看详情
音乐
封面

音乐

暂未播放

0:00
0:00
暂无歌词
标签
# AI 6 # 认证 5 # 安全 4 # 登录 3 # 博客 2 # Skill 2 # Redis 2 # Bitmap 2 # 部署 2 # Java 2 # 并发编程 2 # 性能优化 2 # 二开 1 # firefly 1 # 前端 1 # Prompt 1 # 工作流 1 # RAG 1 # Cloudflare 1 # 缓存设计 1 # 高性能 1 # Bot 1 # Umami 1 # Vercel 1 # 线程池 1 # 虚拟线程 1 # 分布式 1 # JWT 1 # OAuth2 1 # MinIO 1 # 对象存储 1 # 扫码登录 1 # WebSocket 1 # Agent 1 # Oracle 1 # 数据库 1
目录
工具

隐私政策

更新日期: 2026 年 7 月 15 日
生效日期: 2026 年 7 月 15 日

适用范围#

本政策适用于 MmzMing 的博客(以下简称“本站”)。本站是个人博客,用于发布和分享内容;不提供账户注册、支付、定位或广告投放服务。访问本站、发表文章评论或在留言板留言前,请阅读本政策。

信息收集与使用#

本站只在提供内容、评论和留言功能,以及维护站点安全所需的范围内处理信息。

  • 访问与统计信息:访问页面时,统计服务可能处理访问时间、页面地址、来源页、浏览器和设备相关信息,用于了解内容访问情况、排查故障和改进站点。
  • 评论信息:使用文章评论功能时,Waline 可能处理您主动提交的昵称、邮箱、站点链接和评论内容;还可能处理 IP 地址等必要信息,用于防止垃圾评论、滥用和维护服务安全。评论内容、昵称和站点链接(如填写)可能公开展示在文章下方;邮箱不会公开展示。
  • 留言信息:留言板使用 Waline /guestbook/ 频道。Waline 可能处理您主动提交的昵称、可选邮箱、站点链接、留言内容和图片,以及浏览器、操作系统、IP 地址等必要的反滥用信息。默认情况下,留言图片以内嵌数据随留言提交;如站点维护者配置了远程图片上传接口,图片会先发送至该接口并在留言中保存返回的图片地址。留言内容、昵称、图片和站点链接(如填写)可能公开展示;邮箱和 IP 地址不会在留言板公开展示。
  • AI 对话信息:使用 AI 搜索时,本站会处理您提交的问题以及最近 6 条对话历史,用于检索博客内容并生成回答。问题和对话历史会发送至 ModelScope,或在第三方接口不可用时由 Cloudflare Workers AI 处理。请勿在 AI 对话中提交密码、Token、身份证件、联系方式或其他敏感信息。

请不要在评论或留言中提交身份证件、银行卡、住址、密码或其他不必要的敏感个人信息。

第三方服务#

为实现本站功能,以下第三方会在各自服务范围内处理相关数据:

  • Umami:用于匿名化的网站访问统计和出站链接点击统计,帮助我了解本站的使用情况。
  • Waline:用于文章评论、留言板及访问量统计。服务会按照其自身规则处理您在评论或留言时提交的信息及必要的反滥用信息。
  • Cloudflare:为本站提供静态资源分发、AI Worker、Vectorize 和相关基础设施。留言板不使用项目 Worker 或 KV 存储。
  • ModelScope:为 AI 搜索提供文本向量和对话模型服务,会处理您提交的问题及发送给模型的最近对话历史。
  • Cloudflare Workers AI:在未配置第三方 AI 接口时提供文本向量和对话模型服务,并处理相同的 AI 请求数据。
  • unpkg:用于加载 Waline 的前端脚本、样式和表情资源;请求这些资源时,您的浏览器会与该服务建立连接。

第三方服务可能有独立的隐私政策和数据保存规则。请在使用相关功能前查阅其规则;本站无法控制其独立的数据处理活动。

本站主要使用浏览器本地存储(Local Storage 或 Session Storage)保存使用偏好,例如主题颜色、明暗模式、文章列表视图和音乐播放设置。留言板会在本地保存匿名资料、未发送草稿和登录状态,以便恢复输入与会话;管理员登录状态仅保存在当前会话。AI 搜索的会话标题和完整对话也会保存在当前浏览器的 Local Storage 中,最长保存 7 天;您可以在 AI 面板中使用“清空全部会话”立即删除这些数据。

本站不主动设置用于广告定向的第一方 Cookie。评论、统计或资源服务可能按照其自身规则使用 Cookie 或类似技术。您可以通过浏览器设置查看、删除或限制 Cookie 和本地存储;清除后,部分偏好或互动状态可能会恢复为默认值,评论功能也可能受到影响。

信息公开、保存与安全#

评论和留言属于公开互动内容,提交后可能被搜索引擎收录、被他人引用或在缓存中短暂保留。请谨慎决定发布内容。除非您提出删除请求、内容违反规则或法律法规另有要求,公开内容会持续保留以维持讨论上下文。

本站会采取合理措施保护数据安全,包括使用 HTTPS、输入校验、内容转义和访问频率限制。但互联网传输和第三方服务均无法保证绝对安全,请理解并自行承担公开发布信息的相应风险。

你的权利#

你可以通过 784774835@qq.com 联系我,申请查询、更正或删除由本站直接保存的评论、留言或相关公开内容。为保护他人权益,请在请求中提供足以定位内容的信息,并说明你与该内容的关系;必要时可能需要进行合理核验。

对于由 Waline、Umami、Cloudflare 或 unpkg 独立处理的数据,你也可以直接向对应服务提供方行使相关权利。删除公开评论或留言后,第三方缓存、搜索引擎索引或他人转载的副本可能无法立即同步删除。

未成年人条款#

未满 14 周岁的未成年人应在监护人同意和指导下使用本站的评论、留言等互动功能。监护人如发现未成年人未经同意提交了个人信息,可通过上述联系方式与我联系,我会在合理范围内协助处理。

政策更新与联系#

我可能因本站功能或适用规则变化更新本政策,更新后的版本将在本站公布并标明日期。继续使用相关功能即表示你已阅读并理解更新后的政策。

如对本政策或数据处理有疑问,请联系 784774835@qq.com

用户协议

更新日期: 2026 年 5 月 19 日
生效日期: 2026 年 5 月 19 日

适用范围#

本协议适用于你访问 MmzMing 的博客,以及使用文章评论、留言板等互动功能的行为。继续浏览本站或提交评论、留言,即表示你已阅读、理解并同意遵守本协议及本站的隐私政策。

评论及留言规则#

请在交流中保持友善、理性和尊重。你不得利用本站发布、传播或实施以下行为:

  • 发布任何违反中华人民共和国法律法规的内容。
  • 发布任何侵犯他人合法权益的内容,包括但不限于隐私、名誉、肖像、著作权、商标权和其他知识产权。
  • 恶意攻击、辱骂、骚扰、威胁、歧视其他用户或任何第三方。
  • 发布垃圾广告、恶意推广、刷屏、灌水,或与讨论主题明显无关的重复内容。
  • 利用本站进行网络诈骗、钓鱼、传播恶意软件,或发布可能危害网络和信息安全的内容。
  • 绕越或试图绕越本站的审核、限流、封禁等管理措施。
  • 冒充他人、伪造身份,或收集、公开他人的个人信息。

内容与访问管理#

你应对自己发布的评论和留言负责,并保证拥有发布该等内容所需的合法权利。论坛管理员有权在不另行通知的情况下删除违规内容、限制或封禁违规账号,或限制其继续使用本站互动功能。

如发现涉嫌违法犯罪、严重侵权或危及本站安全的内容,本站可保留相关记录,并在法律法规要求或必要时向有关部门提供协助。对管理措施有疑问时,可通过文末联系方式说明情况;本站会结合实际情况处理,但不承诺恢复已删除内容或访问权限。

知识产权与内容授权#

本站原创文章、页面设计和其他受保护内容的权利归作者或权利人所有。未经授权,请勿复制、转载、镜像或用于商业用途;法律法规允许的合理使用除外。

你发布评论或留言时,授予本站为展示、存储、备份、审核、删除和维护互动功能所必需的非独占、免费的使用许可。该许可不改变你对原创内容依法享有的权利。

免责声明#

本站内容仅用于个人记录、学习交流和一般信息参考,不构成任何专业意见、承诺或担保。你应结合自身情况独立判断,并对据此采取的行动负责。

评论、留言和外部链接中的内容由其发布者或运营者负责,不代表本站立场。本站会在合理范围内处理明显违规内容,但不保证所有内容均及时发现,也不对第三方网站的可用性、内容、安全性或隐私实践承担责任。

因网络故障、不可抗力、第三方服务异常、维护升级或超出合理控制范围的原因导致本站暂时无法访问、内容延迟或数据丢失的,本站会尽力恢复,但不承担由此产生的间接损失。

未成年人条款#

未满 14 周岁的未成年人应在监护人同意和指导下使用评论、留言等互动功能。监护人应协助未成年人理解本协议,并对其使用行为进行必要的引导。

其他条款#

我可以根据本站功能、管理需要或法律法规变化更新本协议,更新后的版本将在本站公布并标明日期。继续使用本站即视为接受更新后的协议。

本协议的订立、执行和解释适用中华人民共和国法律。因本协议或使用本站产生争议时,双方应先友好协商;协商不成的,依法向有管辖权的人民法院解决。

如对本协议或内容管理有疑问,请联系 784774835@qq.com