liu
12 小时以前 514f372270b181f82e4deff98f8d0f38ace63183
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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
package cn.iocoder.yudao.module.mes.framework.qrexport;
 
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
 
/**
 * MES 二维码导出配置项
 * <p>
 * 批量导出二维码是 CPU 密集型操作(逐张生成二维码 + 合成 PNG),且单批次可达成千上万张,
 * 因此导出被拆成两条路径:
 * <ul>
 *     <li>小批量(不超过 {@link #syncThreshold})走同步流式下载,秒级返回,不受任何闸门限制;</li>
 *     <li>大批量转后台任务,受并发闸门与 CPU 闸门管控,避免把同机部署的业务页面拖垮。</li>
 * </ul>
 */
@Data
@Component
@ConfigurationProperties(prefix = "mes.qr-export")
public class MesProQrExportProperties {
 
    /**
     * 同步/后台的分界线(张)
     * <p>
     * 不超过该数量直接同步流式下载,超过则转后台导出任务。同步路径不排队、不校验 CPU,
     * 保证「导几百张」永远是秒出,不会被正在跑的大批量任务挡住。
     */
    private int syncThreshold = 2000;
 
    /**
     * 提交后台导出任务时的系统 CPU 使用率拒绝阈值(0~1)
     * <p>
     * 达到该值即拒绝新建任务(提示服务器繁忙),避免在服务器已经很忙时再叠加导出负载。
     */
    private double cpuRejectThreshold = 0.80D;
 
    /**
     * 生成过程中的系统 CPU 节流阈值(0~1)
     * <p>
     * 任务一旦开始就必须跑完,仅靠提交时拒绝无法覆盖「提交时 CPU 低、跑起来把业务拖卡」的情况,
     * 因此生成过程中持续采样,超过该水位即让出 CPU(降速但不中断)。
     */
    private double cpuThrottleThreshold = 0.85D;
 
    /**
     * CPU 高于节流阈值时,每次让出 CPU 的毫秒数
     */
    private long cpuThrottleSleepMillis = 300L;
 
    /**
     * 生成过程中检查取消、采样 CPU 的间隔(每多少张一次)
     */
    private int progressCheckInterval = 200;
 
    /**
     * 同时允许运行的后台导出任务数
     * <p>
     * 仅约束大批量任务,小批量同步导出不受此限制。
     */
    private int maxConcurrentTasks = 1;
 
    /**
     * 单个后台任务的最长运行时间(分钟),超时自动取消并清理,避免异常任务长期占用
     */
    private int maxRuntimeMinutes = 30;
 
    /**
     * 临时 ZIP 存放目录,为空时使用 {@code ${java.io.tmpdir}/mes-qr-export}
     */
    private String tempDir = "";
 
    /**
     * 临时 ZIP 的保留时间(分钟)
     * <p>
     * 正常下载完成后立即删除;仅在「下载中断」或「生成完成后始终未下载」时保留一小段时间,
     * 到期由清理任务删除。否则每次中断都要重新生成上万张标签,或者上 GB 的临时文件一直占着磁盘。
     */
    private int tempFileRetentionMinutes = 10;
 
    /**
     * 解析临时目录,未配置时回退到系统临时目录
     */
    public String resolveTempDir() {
        if (tempDir == null || tempDir.isBlank()) {
            return System.getProperty("java.io.tmpdir") + java.io.File.separator + "mes-qr-export";
        }
        return tempDir;
    }
 
}